<commit_before>//===-- DWARFASTParserSwift.cpp ---------------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "DWARFASTParserSwift.h"

#include "DWARFASTParserClang.h"
#include "DWARFCompileUnit.h"
#include "DWARFDIE.h"
#include "DWARFDebugInfo.h"
#include "DWARFDefines.h"
#include "SymbolFileDWARF.h"

#include "swift/AST/ASTContext.h"
#include "swift/AST/Decl.h"
#include "swift/Demangling/Demangle.h"

#include "clang/AST/DeclObjC.h"

#include "lldb/Core/Module.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SwiftASTContext.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Target/SwiftLanguageRuntime.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"

using namespace lldb;
using namespace lldb_private;

DWARFASTParserSwift::DWARFASTParserSwift(SwiftASTContext &ast) : m_ast(ast) {}

DWARFASTParserSwift::~DWARFASTParserSwift() {}

static llvm::StringRef GetTypedefName(const DWARFDIE &die) {
  if (die.Tag() != DW_TAG_typedef)
    return {};
  DWARFDIE type_die = die.GetAttributeValueAsReferenceDIE(DW_AT_type);
  if (!type_die.IsValid())
    return {};
  return llvm::StringRef::withNullAsEmpty(type_die.GetName());
}

lldb::TypeSP DWARFASTParserSwift::ParseTypeFromDWARF(const SymbolContext &sc,
                                                     const DWARFDIE &die,
                                                     Log *log,
                                                     bool *type_is_new_ptr) {
  lldb::TypeSP type_sp;
  CompilerType compiler_type;
  Status error;

  Declaration decl;
  ConstString mangled_name;
  ConstString name;
  bool is_clang_type = false;
  llvm::Optional<uint64_t> dwarf_byte_size;

  DWARFAttributes attributes;
  const size_t num_attributes = die.GetAttributes(attributes);
  DWARFFormValue type_attr;

  if (num_attributes > 0) {
    uint32_t i;
    for (i = 0; i < num_attributes; ++i) {
      const dw_attr_t attr = attributes.AttributeAtIndex(i);
      DWARFFormValue form_value;
      if (attributes.ExtractFormValueAtIndex(i, form_value)) {
        switch (attr) {
        case DW_AT_decl_file:
          decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
              form_value.Unsigned()));
          break;
        case DW_AT_decl_line:
          decl.SetLine(form_value.Unsigned());
          break;
        case DW_AT_decl_column:
          decl.SetColumn(form_value.Unsigned());
          break;
        case DW_AT_name:
          name.SetCString(form_value.AsCString());
          break;
        case DW_AT_linkage_name:
        case DW_AT_MIPS_linkage_name:
          mangled_name.SetCString(form_value.AsCString());
          break;
        case DW_AT_byte_size:
          dwarf_byte_size = form_value.Unsigned();
          break;
        default:
          break;
        }
      }
    }
  }

  if (!mangled_name && name) {
    if (name.GetStringRef().equals("$swift.fixedbuffer")) {
      DWARFDIE type_die =
          die.GetFirstChild().GetAttributeValueAsReferenceDIE(DW_AT_type);
      if (auto wrapped_type =
          ParseTypeFromDWARF(sc, type_die, log, type_is_new_ptr)) {
        // Create a unique pointer for the type + fixed buffer flag.
        type_sp.reset(new Type(*wrapped_type));
        type_sp->SetSwiftFixedValueBuffer(true);
        return type_sp;
      }
    }
    if (SwiftLanguageRuntime::IsSwiftMangledName(name.GetCString()))
      mangled_name = name;
    else {
      const char *type_name_cstr = name.GetCString();
      // TODO: remove this once all mangled names are always included for all
      // types in DWARF
      swift::ModuleDecl *swift_module = m_ast.GetModule(decl.GetFile(), error);
      if (swift_module)
        compiler_type = m_ast.FindType(type_name_cstr, swift_module);
    }
  }

  if (mangled_name) {
    type_sp = m_ast.GetCachedType(mangled_name);
    if (type_sp)
      return type_sp;

    // Because of DWARFImporter, we may search for this type again while
    // resolving the mangled name.
    die.GetDWARF()->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;

    // Try to import the type from one of the loaded Swift modules.
    compiler_type = m_ast.GetTypeFromMangledTypename(mangled_name, error);
  }

  if (!compiler_type &&
      swift::Demangle::isObjCSymbol(mangled_name.GetStringRef())) {
    // When we failed to look up the type because no .swiftmodule is
    // present or it couldn't be read, fall back to presenting objects
    // that look like they might be come from Objective-C (or C) as
    // Clang types. LLDB's Objective-C part is very robust against
    // malformed object pointers, so this isn't very risky.
    if (auto *clang_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
            sc.module_sp->GetTypeSystemForLanguage(eLanguageTypeObjC))) {
      DWARFASTParserClang *clang_ast_parser =
          static_cast<DWARFASTParserClang *>(clang_ctx->GetDWARFParser());
      TypeMap clang_types;
      GetClangType(die, mangled_name.GetStringRef(), clang_types);

      // Import the Clang type into the Clang context.
      if (!compiler_type && clang_types.GetSize())
        if (TypeSP clang_type_sp = clang_types.GetTypeAtIndex(0))
          if (clang_type_sp) {
            is_clang_type = true;
            compiler_type = clang_ast_parser->GetClangASTImporter().CopyType(
                *clang_ctx, clang_type_sp->GetForwardCompilerType());
            // Swift doesn't know pointers. Convert top-level
            // Objective-C object types to object pointers for Clang.
            auto clang_type = clang::QualType::getFromOpaquePtr(
                compiler_type.GetOpaqueQualType());
            if (clang_type->isObjCObjectOrInterfaceType())
              compiler_type = compiler_type.GetPointerType();
          }

      // Fall back to (id), which is not necessarily correct.
      if (!compiler_type) {
        is_clang_type = true;
        compiler_type = clang_ctx->GetBasicType(eBasicTypeObjCClass);
      }
    }
  }

  ConstString preferred_name;
  if (!compiler_type && name) {
    // Handle Archetypes, which are typedefs to RawPointerType.
    if (GetTypedefName(die).startswith("$sBp")) {
      swift::ASTContext *swift_ast_ctx = m_ast.GetASTContext();
      if (!swift_ast_ctx) {
        if (log)
          log->Printf("Empty Swift AST context while looking up %s.",
                      name.AsCString());
        return {};
      }
      preferred_name = name;
      compiler_type = {swift_ast_ctx->TheRawPointerType};
    }
  }

  switch (die.Tag()) {
  case DW_TAG_inlined_subroutine:
  case DW_TAG_subprogram:
  case DW_TAG_subroutine_type:
    if (!compiler_type || !compiler_type.IsFunctionType()) {
      // Make sure we at least have some function type. The mangling for
      // the "top_level_code" is returning the empty tuple type "()",
      // which is not a function type.
      compiler_type = m_ast.GetVoidFunctionType();
    }
    break;
  default:
    break;
  }

  if (compiler_type) {
    type_sp = TypeSP(new Type(
        die.GetID(), die.GetDWARF(),
        preferred_name ? preferred_name : compiler_type.GetTypeName(),
        is_clang_type ? dwarf_byte_size
                      : compiler_type.GetByteSize(nullptr),
        NULL, LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, compiler_type,
        is_clang_type ? Type::eResolveStateForward : Type::eResolveStateFull));
    // FIXME: This ought to work lazily, too.
    if (is_clang_type)
      type_sp->GetFullCompilerType();
  }

  // Cache this type.
  if (type_sp && mangled_name &&
      SwiftLanguageRuntime::IsSwiftMangledName(mangled_name.GetCString()))
    m_ast.SetCachedType(mangled_name, type_sp);
  die.GetDWARF()->GetDIEToType()[die.GetDIE()] = type_sp.get();

  return type_sp;
}

void DWARFASTParserSwift::GetClangType(const DWARFDIE &die,
                                       llvm::StringRef mangled_name,
                                       TypeMap &clang_types) const {
  std::vector<CompilerContext> decl_context;
  die.GetDeclContext(decl_context);
  if (!decl_context.size())
    return;

  // Typedefs don't have a DW_AT_linkage_name, so their DW_AT_name is the
  // mangled. Get the unmangled name.
  auto fixup_typedef = [&mangled_name, &decl_context]() {
    using namespace swift::Demangle;
    Context Ctx;
    NodePointer node = Ctx.demangleSymbolAsNode(mangled_name);
    if (!node || node->getNumChildren() != 1 ||
        node->getKind() != Node::Kind::Global)
      return;
    node = node->getFirstChild();
    if (node->getNumChildren() != 1 ||
        node->getKind() != Node::Kind::TypeMangling)
      return;
    node = node->getFirstChild();
    if (node->getNumChildren() != 1 || node->getKind() != Node::Kind::Type)
      return;
    node = node->getFirstChild();
    if (node->getKind() != Node::Kind::TypeAlias)
      return;
    for (NodePointer child : *node)
      if (child->getKind() == Node::Kind::Identifier && child->hasText()) {
        decl_context.back().type = CompilerContextKind::Typedef;
        decl_context.back().name = ConstString(child->getText());
        return;
      }
  };
  fixup_typedef();

  auto *sym_file = die.GetCU()->GetSymbolFileDWARF();
  sym_file->UpdateExternalModuleListIfNeeded();

  CompilerContextKind kinds[] = {decl_context.back().type,
                                 CompilerContextKind::Union,
                                 CompilerContextKind::Enumeration};

  // The Swift projection of all Clang type is a struct; search every kind.
  for (CompilerContextKind kind : kinds) {
    decl_context.back().type = kind;
    // Search any modules referenced by DWARF.
    for (const auto &name_module : sym_file->getExternalTypeModules()) {
      if (!name_module.second)
        continue;
      SymbolVendor *sym_vendor = name_module.second->GetSymbolVendor();
      if (sym_vendor->FindTypes(decl_context, true, clang_types))
        return;
    }
    // Next search the .dSYM the DIE came from, if applicable.
    if (SymbolFileDWARF *sym_file = die.GetCU()->GetSymbolFileDWARF())
      if (sym_file->FindTypes(decl_context, true, clang_types))
        return;
  }
}

Function *DWARFASTParserSwift::ParseFunctionFromDWARF(
    lldb_private::CompileUnit &comp_unit, const DWARFDIE &die) {
  DWARFRangeList func_ranges;
  const char *name = NULL;
  const char *mangled = NULL;
  int decl_file = 0;
  int decl_line = 0;
  int decl_column = 0;
  int call_file = 0;
  int call_line = 0;
  int call_column = 0;
  DWARFExpression frame_base(die.GetCU());

  if (die.Tag() != DW_TAG_subprogram)
    return NULL;

  if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
                               decl_column, call_file, call_line, call_column,
                               &frame_base)) {
    // Union of all ranges in the function DIE (if the function is
    // discontiguous)
    SymbolFileDWARF *dwarf = die.GetDWARF();
    AddressRange func_range;
    lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
    lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
    if (lowest_func_addr != LLDB_INVALID_ADDRESS &&
        lowest_func_addr <= highest_func_addr) {
      ModuleSP module_sp(dwarf->GetObjectFile()->GetModule());
      func_range.GetBaseAddress().ResolveAddressUsingFileSections(
          lowest_func_addr, module_sp->GetSectionList());
      if (func_range.GetBaseAddress().IsValid())
        func_range.SetByteSize(highest_func_addr - lowest_func_addr);
    }

    if (func_range.GetBaseAddress().IsValid()) {
      Mangled func_name;
      if (mangled)
        func_name.SetValue(ConstString(mangled), true);
      else
        func_name.SetValue(ConstString(name), false);

      // See if this function can throw.  We can't get that from the
      // mangled name (even though the information is often there)
      // because Swift reserves the right to omit it from the name
      // if it doesn't need it.  So instead we look for the
      // DW_TAG_thrown_type:

      bool can_throw = false;

      DWARFDebugInfoEntry *child(die.GetFirstChild().GetDIE());
      while (child) {
        if (child->Tag() == DW_TAG_thrown_type) {
          can_throw = true;
          break;
        }
        child = child->GetSibling();
      }

      FunctionSP func_sp;
      std::unique_ptr<Declaration> decl_ap;
      if (decl_file != 0 || decl_line != 0 || decl_column != 0)
        decl_ap.reset(new Declaration(
            comp_unit.GetSupportFiles().GetFileSpecAtIndex(decl_file),
            decl_line, decl_column));

      if (dwarf->FixupAddress(func_range.GetBaseAddress())) {
        const user_id_t func_user_id = die.GetID();
        func_sp.reset(new Function(&comp_unit, func_user_id, func_user_id,
                                   func_name, nullptr, func_range,
                                   can_throw)); // first address range

        if (func_sp.get() != NULL) {
          if (frame_base.IsValid())
            func_sp->GetFrameBaseExpression() = frame_base;
          comp_unit.AddFunction(func_sp);
          return func_sp.get();
        }
      }
    }
  }
  return NULL;
}

lldb_private::CompilerDeclContext
DWARFASTParserSwift::GetDeclContextForUIDFromDWARF(const DWARFDIE &die) {
  return CompilerDeclContext();
}

lldb_private::CompilerDeclContext
DWARFASTParserSwift::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) {
  return CompilerDeclContext();
}
<commit_msg>[DWARF/Swift] All the mangled names are now in DWARF.<commit_after>//===-- DWARFASTParserSwift.cpp ---------------------------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "DWARFASTParserSwift.h"

#include "DWARFASTParserClang.h"
#include "DWARFCompileUnit.h"
#include "DWARFDIE.h"
#include "DWARFDebugInfo.h"
#include "DWARFDefines.h"
#include "SymbolFileDWARF.h"

#include "swift/AST/ASTContext.h"
#include "swift/AST/Decl.h"
#include "swift/Demangling/Demangle.h"

#include "clang/AST/DeclObjC.h"

#include "lldb/Core/Module.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SwiftASTContext.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/Type.h"
#include "lldb/Symbol/TypeMap.h"
#include "lldb/Target/SwiftLanguageRuntime.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/Status.h"

using namespace lldb;
using namespace lldb_private;

DWARFASTParserSwift::DWARFASTParserSwift(SwiftASTContext &ast) : m_ast(ast) {}

DWARFASTParserSwift::~DWARFASTParserSwift() {}

static llvm::StringRef GetTypedefName(const DWARFDIE &die) {
  if (die.Tag() != DW_TAG_typedef)
    return {};
  DWARFDIE type_die = die.GetAttributeValueAsReferenceDIE(DW_AT_type);
  if (!type_die.IsValid())
    return {};
  return llvm::StringRef::withNullAsEmpty(type_die.GetName());
}

lldb::TypeSP DWARFASTParserSwift::ParseTypeFromDWARF(const SymbolContext &sc,
                                                     const DWARFDIE &die,
                                                     Log *log,
                                                     bool *type_is_new_ptr) {
  lldb::TypeSP type_sp;
  CompilerType compiler_type;
  Status error;

  Declaration decl;
  ConstString mangled_name;
  ConstString name;
  bool is_clang_type = false;
  llvm::Optional<uint64_t> dwarf_byte_size;

  DWARFAttributes attributes;
  const size_t num_attributes = die.GetAttributes(attributes);
  DWARFFormValue type_attr;

  if (num_attributes > 0) {
    uint32_t i;
    for (i = 0; i < num_attributes; ++i) {
      const dw_attr_t attr = attributes.AttributeAtIndex(i);
      DWARFFormValue form_value;
      if (attributes.ExtractFormValueAtIndex(i, form_value)) {
        switch (attr) {
        case DW_AT_decl_file:
          decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
              form_value.Unsigned()));
          break;
        case DW_AT_decl_line:
          decl.SetLine(form_value.Unsigned());
          break;
        case DW_AT_decl_column:
          decl.SetColumn(form_value.Unsigned());
          break;
        case DW_AT_name:
          name.SetCString(form_value.AsCString());
          break;
        case DW_AT_linkage_name:
        case DW_AT_MIPS_linkage_name:
          mangled_name.SetCString(form_value.AsCString());
          break;
        case DW_AT_byte_size:
          dwarf_byte_size = form_value.Unsigned();
          break;
        default:
          break;
        }
      }
    }
  }

  if (!mangled_name && name) {
    if (name.GetStringRef().equals("$swift.fixedbuffer")) {
      DWARFDIE type_die =
          die.GetFirstChild().GetAttributeValueAsReferenceDIE(DW_AT_type);
      if (auto wrapped_type =
          ParseTypeFromDWARF(sc, type_die, log, type_is_new_ptr)) {
        // Create a unique pointer for the type + fixed buffer flag.
        type_sp.reset(new Type(*wrapped_type));
        type_sp->SetSwiftFixedValueBuffer(true);
        return type_sp;
      }
    }
    if (SwiftLanguageRuntime::IsSwiftMangledName(name.GetCString()))
      mangled_name = name;
  }

  if (mangled_name) {
    type_sp = m_ast.GetCachedType(mangled_name);
    if (type_sp)
      return type_sp;

    // Because of DWARFImporter, we may search for this type again while
    // resolving the mangled name.
    die.GetDWARF()->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;

    // Try to import the type from one of the loaded Swift modules.
    compiler_type = m_ast.GetTypeFromMangledTypename(mangled_name, error);
  }

  if (!compiler_type &&
      swift::Demangle::isObjCSymbol(mangled_name.GetStringRef())) {
    // When we failed to look up the type because no .swiftmodule is
    // present or it couldn't be read, fall back to presenting objects
    // that look like they might be come from Objective-C (or C) as
    // Clang types. LLDB's Objective-C part is very robust against
    // malformed object pointers, so this isn't very risky.
    if (auto *clang_ctx = llvm::dyn_cast_or_null<ClangASTContext>(
            sc.module_sp->GetTypeSystemForLanguage(eLanguageTypeObjC))) {
      DWARFASTParserClang *clang_ast_parser =
          static_cast<DWARFASTParserClang *>(clang_ctx->GetDWARFParser());
      TypeMap clang_types;
      GetClangType(die, mangled_name.GetStringRef(), clang_types);

      // Import the Clang type into the Clang context.
      if (!compiler_type && clang_types.GetSize())
        if (TypeSP clang_type_sp = clang_types.GetTypeAtIndex(0))
          if (clang_type_sp) {
            is_clang_type = true;
            compiler_type = clang_ast_parser->GetClangASTImporter().CopyType(
                *clang_ctx, clang_type_sp->GetForwardCompilerType());
            // Swift doesn't know pointers. Convert top-level
            // Objective-C object types to object pointers for Clang.
            auto clang_type = clang::QualType::getFromOpaquePtr(
                compiler_type.GetOpaqueQualType());
            if (clang_type->isObjCObjectOrInterfaceType())
              compiler_type = compiler_type.GetPointerType();
          }

      // Fall back to (id), which is not necessarily correct.
      if (!compiler_type) {
        is_clang_type = true;
        compiler_type = clang_ctx->GetBasicType(eBasicTypeObjCClass);
      }
    }
  }

  ConstString preferred_name;
  if (!compiler_type && name) {
    // Handle Archetypes, which are typedefs to RawPointerType.
    if (GetTypedefName(die).startswith("$sBp")) {
      swift::ASTContext *swift_ast_ctx = m_ast.GetASTContext();
      if (!swift_ast_ctx) {
        if (log)
          log->Printf("Empty Swift AST context while looking up %s.",
                      name.AsCString());
        return {};
      }
      preferred_name = name;
      compiler_type = {swift_ast_ctx->TheRawPointerType};
    }
  }

  switch (die.Tag()) {
  case DW_TAG_inlined_subroutine:
  case DW_TAG_subprogram:
  case DW_TAG_subroutine_type:
    if (!compiler_type || !compiler_type.IsFunctionType()) {
      // Make sure we at least have some function type. The mangling for
      // the "top_level_code" is returning the empty tuple type "()",
      // which is not a function type.
      compiler_type = m_ast.GetVoidFunctionType();
    }
    break;
  default:
    break;
  }

  if (compiler_type) {
    type_sp = TypeSP(new Type(
        die.GetID(), die.GetDWARF(),
        preferred_name ? preferred_name : compiler_type.GetTypeName(),
        is_clang_type ? dwarf_byte_size
                      : compiler_type.GetByteSize(nullptr),
        NULL, LLDB_INVALID_UID, Type::eEncodingIsUID, &decl, compiler_type,
        is_clang_type ? Type::eResolveStateForward : Type::eResolveStateFull));
    // FIXME: This ought to work lazily, too.
    if (is_clang_type)
      type_sp->GetFullCompilerType();
  }

  // Cache this type.
  if (type_sp && mangled_name &&
      SwiftLanguageRuntime::IsSwiftMangledName(mangled_name.GetCString()))
    m_ast.SetCachedType(mangled_name, type_sp);
  die.GetDWARF()->GetDIEToType()[die.GetDIE()] = type_sp.get();

  return type_sp;
}

void DWARFASTParserSwift::GetClangType(const DWARFDIE &die,
                                       llvm::StringRef mangled_name,
                                       TypeMap &clang_types) const {
  std::vector<CompilerContext> decl_context;
  die.GetDeclContext(decl_context);
  if (!decl_context.size())
    return;

  // Typedefs don't have a DW_AT_linkage_name, so their DW_AT_name is the
  // mangled. Get the unmangled name.
  auto fixup_typedef = [&mangled_name, &decl_context]() {
    using namespace swift::Demangle;
    Context Ctx;
    NodePointer node = Ctx.demangleSymbolAsNode(mangled_name);
    if (!node || node->getNumChildren() != 1 ||
        node->getKind() != Node::Kind::Global)
      return;
    node = node->getFirstChild();
    if (node->getNumChildren() != 1 ||
        node->getKind() != Node::Kind::TypeMangling)
      return;
    node = node->getFirstChild();
    if (node->getNumChildren() != 1 || node->getKind() != Node::Kind::Type)
      return;
    node = node->getFirstChild();
    if (node->getKind() != Node::Kind::TypeAlias)
      return;
    for (NodePointer child : *node)
      if (child->getKind() == Node::Kind::Identifier && child->hasText()) {
        decl_context.back().type = CompilerContextKind::Typedef;
        decl_context.back().name = ConstString(child->getText());
        return;
      }
  };
  fixup_typedef();

  auto *sym_file = die.GetCU()->GetSymbolFileDWARF();
  sym_file->UpdateExternalModuleListIfNeeded();

  CompilerContextKind kinds[] = {decl_context.back().type,
                                 CompilerContextKind::Union,
                                 CompilerContextKind::Enumeration};

  // The Swift projection of all Clang type is a struct; search every kind.
  for (CompilerContextKind kind : kinds) {
    decl_context.back().type = kind;
    // Search any modules referenced by DWARF.
    for (const auto &name_module : sym_file->getExternalTypeModules()) {
      if (!name_module.second)
        continue;
      SymbolVendor *sym_vendor = name_module.second->GetSymbolVendor();
      if (sym_vendor->FindTypes(decl_context, true, clang_types))
        return;
    }
    // Next search the .dSYM the DIE came from, if applicable.
    if (SymbolFileDWARF *sym_file = die.GetCU()->GetSymbolFileDWARF())
      if (sym_file->FindTypes(decl_context, true, clang_types))
        return;
  }
}

Function *DWARFASTParserSwift::ParseFunctionFromDWARF(
    lldb_private::CompileUnit &comp_unit, const DWARFDIE &die) {
  DWARFRangeList func_ranges;
  const char *name = NULL;
  const char *mangled = NULL;
  int decl_file = 0;
  int decl_line = 0;
  int decl_column = 0;
  int call_file = 0;
  int call_line = 0;
  int call_column = 0;
  DWARFExpression frame_base(die.GetCU());

  if (die.Tag() != DW_TAG_subprogram)
    return NULL;

  if (die.GetDIENamesAndRanges(name, mangled, func_ranges, decl_file, decl_line,
                               decl_column, call_file, call_line, call_column,
                               &frame_base)) {
    // Union of all ranges in the function DIE (if the function is
    // discontiguous)
    SymbolFileDWARF *dwarf = die.GetDWARF();
    AddressRange func_range;
    lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase(0);
    lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd(0);
    if (lowest_func_addr != LLDB_INVALID_ADDRESS &&
        lowest_func_addr <= highest_func_addr) {
      ModuleSP module_sp(dwarf->GetObjectFile()->GetModule());
      func_range.GetBaseAddress().ResolveAddressUsingFileSections(
          lowest_func_addr, module_sp->GetSectionList());
      if (func_range.GetBaseAddress().IsValid())
        func_range.SetByteSize(highest_func_addr - lowest_func_addr);
    }

    if (func_range.GetBaseAddress().IsValid()) {
      Mangled func_name;
      if (mangled)
        func_name.SetValue(ConstString(mangled), true);
      else
        func_name.SetValue(ConstString(name), false);

      // See if this function can throw.  We can't get that from the
      // mangled name (even though the information is often there)
      // because Swift reserves the right to omit it from the name
      // if it doesn't need it.  So instead we look for the
      // DW_TAG_thrown_type:

      bool can_throw = false;

      DWARFDebugInfoEntry *child(die.GetFirstChild().GetDIE());
      while (child) {
        if (child->Tag() == DW_TAG_thrown_type) {
          can_throw = true;
          break;
        }
        child = child->GetSibling();
      }

      FunctionSP func_sp;
      std::unique_ptr<Declaration> decl_ap;
      if (decl_file != 0 || decl_line != 0 || decl_column != 0)
        decl_ap.reset(new Declaration(
            comp_unit.GetSupportFiles().GetFileSpecAtIndex(decl_file),
            decl_line, decl_column));

      if (dwarf->FixupAddress(func_range.GetBaseAddress())) {
        const user_id_t func_user_id = die.GetID();
        func_sp.reset(new Function(&comp_unit, func_user_id, func_user_id,
                                   func_name, nullptr, func_range,
                                   can_throw)); // first address range

        if (func_sp.get() != NULL) {
          if (frame_base.IsValid())
            func_sp->GetFrameBaseExpression() = frame_base;
          comp_unit.AddFunction(func_sp);
          return func_sp.get();
        }
      }
    }
  }
  return NULL;
}

lldb_private::CompilerDeclContext
DWARFASTParserSwift::GetDeclContextForUIDFromDWARF(const DWARFDIE &die) {
  return CompilerDeclContext();
}

lldb_private::CompilerDeclContext
DWARFASTParserSwift::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) {
  return CompilerDeclContext();
}
<|endoftext|>


<commit_before>
#include "physics/equipotential.hpp"

#include "base/not_null.hpp"
#include "geometry/frame.hpp"
#include "geometry/grassmann.hpp"
#include "geometry/named_quantities.hpp"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "integrators/methods.hpp"
#include "integrators/embedded_explicit_runge_kutta_integrator.hpp"
#include "integrators/symmetric_linear_multistep_integrator.hpp"
#include "mathematica/mathematica.hpp"
#include "physics/body_centred_body_direction_dynamic_frame.hpp"
#include "physics/body_centred_non_rotating_dynamic_frame.hpp"
#include "physics/ephemeris.hpp"
#include "physics/solar_system.hpp"
#include "quantities/si.hpp"
#include "testing_utilities/solar_system_factory.hpp"

namespace principia {
namespace physics {

using base::make_not_null_unique;
using base::not_null;
using geometry::Arbitrary;
using geometry::Bivector;
using geometry::Frame;
using geometry::Inertial;
using geometry::Instant;
using geometry::Position;
using integrators::EmbeddedExplicitRungeKuttaIntegrator;
using integrators::SymmetricLinearMultistepIntegrator;
using integrators::methods::DormandPrince1986RK547FC;
using integrators::methods::QuinlanTremaine1990Order12;
using quantities::si::Day;
using quantities::si::Metre;
using quantities::si::Milli;
using quantities::si::Minute;
using testing_utilities::SolarSystemFactory;

class EquipotentialTest : public ::testing::Test {
 protected:
  using Barycentric = Frame<enum class BarycentricTag, Inertial>;
  using World = Frame<enum class WorldTag, Arbitrary>;
  EquipotentialTest()
      : ephemeris_parameters_(
            SymmetricLinearMultistepIntegrator<QuinlanTremaine1990Order12,
                                               Position<Barycentric>>(),
            /*step=*/10 * Minute),
        solar_system_(make_not_null_unique<SolarSystem<Barycentric>>(
            SOLUTION_DIR / "astronomy" / "sol_gravity_model.proto.txt",
            SOLUTION_DIR / "astronomy" /
                "sol_initial_state_jd_2451545_000000000.proto.txt",
            /*ignore_frame=*/true)),
        ephemeris_(solar_system_->MakeEphemeris(
            /*accuracy_parameters=*/{/*fitting_tolerance=*/1 * Milli(Metre),
                                     /*geopotential_tolerance=*/0x1p-24},
            ephemeris_parameters_)),
        equipotential_parameters_(
            EmbeddedExplicitRungeKuttaIntegrator<DormandPrince1986RK547FC,
                                                 Position<World>,
                                                 double>(),
            /*max_steps=*/1000,
            /*length_integration_tolerance=*/1 * Metre) {}

  Position<World> ComputePositionInWorld(
      DynamicFrame<Barycentric, World> const& dynamic_frame,
      SolarSystemFactory::Index const body) {
    auto const to_this_frame = dynamic_frame.ToThisFrameAtTime(t0_);
    return to_this_frame.rigid_transformation()(
        solar_system_->trajectory(*ephemeris_, SolarSystemFactory::name(body))
            .EvaluatePosition(t0_));
  }

  Instant const t0_;
  Ephemeris<Barycentric>::FixedStepParameters const ephemeris_parameters_;
  not_null<std::unique_ptr<SolarSystem<Barycentric>>> const solar_system_;
  not_null<std::unique_ptr<Ephemeris<Barycentric>>> const ephemeris_;
  Equipotential<Barycentric, World>::AdaptiveParameters const
      equipotential_parameters_;
};

TEST_F(EquipotentialTest, BodyCentredNonRotating) {
  mathematica::Logger logger(TEMP_DIR / "equipotential.wl");
  auto const dynamic_frame(
      BodyCentredNonRotatingDynamicFrame<Barycentric, World>(
          ephemeris_.get(),
          solar_system_->massive_body(
              *ephemeris_, SolarSystemFactory::name(SolarSystemFactory::Sun))));
  Equipotential<Barycentric, World> const equipotential(
      equipotential_parameters_, &dynamic_frame);

  Bivector<double, World> const plane({2, 3, -5});
  {
    LOG(ERROR)<<"MERCURY";
    Instant const t1 = t0_ + Day;
    CHECK_OK(ephemeris_->Prolong(t1));
    auto const& [positions, βs] = equipotential.ComputeLine(
        plane,
        ComputePositionInWorld(dynamic_frame, SolarSystemFactory::Mercury),
        t1);
    logger.Set(
        "equipotentialMercury", positions, mathematica::ExpressIn(Metre));
    logger.Set("betaMercury", βs);
  }
  {
    LOG(ERROR)<<"EARTH";
    Instant const t1 = t0_ + Day;
    CHECK_OK(ephemeris_->Prolong(t1));
    auto const& [positions, βs] = equipotential.ComputeLine(
        plane,
        ComputePositionInWorld(dynamic_frame, SolarSystemFactory::Earth),
        t1);
    logger.Set("equipotentialEarth", positions, mathematica::ExpressIn(Metre));
    logger.Set("betaEarth", βs);
  }
  {
    LOG(ERROR)<<"JUPITER CLOSE";
    Instant const t1 = t0_ + Day;
    CHECK_OK(ephemeris_->Prolong(t1));
    auto const& [positions, βs] = equipotential.ComputeLine(
        plane,
        ComputePositionInWorld(dynamic_frame, SolarSystemFactory::Jupiter),
        t1);
    logger.Set(
        "equipotentialJupiterClose", positions, mathematica::ExpressIn(Metre));
    logger.Set("betaJupiterClose", βs);
  }
  {
    LOG(ERROR)<<"JUPITER FAR";
    Instant const t1 = t0_ + 100 * Day;
    CHECK_OK(ephemeris_->Prolong(t1));
    auto const& [positions, βs] = equipotential.ComputeLine(
        plane,
        ComputePositionInWorld(dynamic_frame, SolarSystemFactory::Jupiter),
        t1);
    logger.Set(
        "equipotentialJupiterFar", positions, mathematica::ExpressIn(Metre));
    logger.Set("betaJupiterFar", βs);
  }
}

TEST_F(EquipotentialTest, BodyCentredBodyDirection) {
  mathematica::Logger logger(TEMP_DIR / "equipotential.wl");
  auto const dynamic_frame(
      BodyCentredBodyDirectionDynamicFrame<Barycentric, World>(
          ephemeris_.get(),
          solar_system_->massive_body(
              *ephemeris_,
              SolarSystemFactory::name(SolarSystemFactory::Sun)),
          solar_system_->massive_body(
              *ephemeris_,
              SolarSystemFactory::name(SolarSystemFactory::Earth))));
  Equipotential<Barycentric, World> const equipotential(
      equipotential_parameters_, &dynamic_frame);

  Bivector<double, World> const plane({0, 0, 1});
  {
    LOG(ERROR)<<"EARTH L4";
    Instant const t1 = t0_ + 60 * Day;
    CHECK_OK(ephemeris_->Prolong(t1));
    auto const& [positions, βs] = equipotential.ComputeLine(
        plane,
        ComputePositionInWorld(dynamic_frame, SolarSystemFactory::Earth),
        t1);
    logger.Set(
        "equipotentialEarthL4", positions, mathematica::ExpressIn(Metre));
    logger.Set("betaEarthL4", βs);
  }
}
}  // namespace physics
}  // namespace principia
<commit_msg>A nice test for the Earth-Moon L4.<commit_after>
#include "physics/equipotential.hpp"

#include "base/not_null.hpp"
#include "geometry/barycentre_calculator.hpp"
#include "geometry/frame.hpp"
#include "geometry/grassmann.hpp"
#include "geometry/named_quantities.hpp"
#include "geometry/rotation.hpp"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "integrators/methods.hpp"
#include "integrators/embedded_explicit_runge_kutta_integrator.hpp"
#include "integrators/symmetric_linear_multistep_integrator.hpp"
#include "mathematica/mathematica.hpp"
#include "physics/body_centred_body_direction_dynamic_frame.hpp"
#include "physics/body_centred_non_rotating_dynamic_frame.hpp"
#include "physics/ephemeris.hpp"
#include "physics/solar_system.hpp"
#include "quantities/si.hpp"
#include "testing_utilities/solar_system_factory.hpp"

namespace principia {
namespace physics {

using base::make_not_null_unique;
using base::not_null;
using geometry::Arbitrary;
using geometry::Barycentre;
using geometry::Bivector;
using geometry::Frame;
using geometry::Inertial;
using geometry::Instant;
using geometry::Position;
using geometry::Rotation;
using integrators::EmbeddedExplicitRungeKuttaIntegrator;
using integrators::SymmetricLinearMultistepIntegrator;
using integrators::methods::DormandPrince1986RK547FC;
using integrators::methods::QuinlanTremaine1990Order12;
using quantities::si::Day;
using quantities::si::Degree;
using quantities::si::Metre;
using quantities::si::Milli;
using quantities::si::Minute;
using testing_utilities::SolarSystemFactory;

class EquipotentialTest : public ::testing::Test {
 protected:
  using Barycentric = Frame<enum class BarycentricTag, Inertial>;
  using World = Frame<enum class WorldTag, Arbitrary>;
  EquipotentialTest()
      : ephemeris_parameters_(
            SymmetricLinearMultistepIntegrator<QuinlanTremaine1990Order12,
                                               Position<Barycentric>>(),
            /*step=*/10 * Minute),
        solar_system_(make_not_null_unique<SolarSystem<Barycentric>>(
            SOLUTION_DIR / "astronomy" / "sol_gravity_model.proto.txt",
            SOLUTION_DIR / "astronomy" /
                "sol_initial_state_jd_2451545_000000000.proto.txt",
            /*ignore_frame=*/true)),
        ephemeris_(solar_system_->MakeEphemeris(
            /*accuracy_parameters=*/{/*fitting_tolerance=*/1 * Milli(Metre),
                                     /*geopotential_tolerance=*/0x1p-24},
            ephemeris_parameters_)),
        equipotential_parameters_(
            EmbeddedExplicitRungeKuttaIntegrator<DormandPrince1986RK547FC,
                                                 Position<World>,
                                                 double>(),
            /*max_steps=*/1000,
            /*length_integration_tolerance=*/1 * Metre) {}

  Position<World> ComputePositionInWorld(
      Instant const& t,
      DynamicFrame<Barycentric, World> const& dynamic_frame,
      SolarSystemFactory::Index const body) {
    auto const to_this_frame = dynamic_frame.ToThisFrameAtTime(t);
    return to_this_frame.rigid_transformation()(
        solar_system_->trajectory(*ephemeris_, SolarSystemFactory::name(body))
            .EvaluatePosition(t));
  }

  Instant const t0_;
  Ephemeris<Barycentric>::FixedStepParameters const ephemeris_parameters_;
  not_null<std::unique_ptr<SolarSystem<Barycentric>>> const solar_system_;
  not_null<std::unique_ptr<Ephemeris<Barycentric>>> const ephemeris_;
  Equipotential<Barycentric, World>::AdaptiveParameters const
      equipotential_parameters_;
};

TEST_F(EquipotentialTest, BodyCentredNonRotating) {
  mathematica::Logger logger(TEMP_DIR / "equipotential.wl");
  auto const dynamic_frame(
      BodyCentredNonRotatingDynamicFrame<Barycentric, World>(
          ephemeris_.get(),
          solar_system_->massive_body(
              *ephemeris_, SolarSystemFactory::name(SolarSystemFactory::Sun))));
  Equipotential<Barycentric, World> const equipotential(
      equipotential_parameters_, &dynamic_frame);

  Bivector<double, World> const plane({2, 3, -5});
  {
    LOG(ERROR)<<"MERCURY";
    Instant const t1 = t0_ + Day;
    CHECK_OK(ephemeris_->Prolong(t1));
    auto const& [positions, βs] = equipotential.ComputeLine(
        plane,
        ComputePositionInWorld(t0_, dynamic_frame, SolarSystemFactory::Mercury),
        t1);
    logger.Set(
        "equipotentialMercury", positions, mathematica::ExpressIn(Metre));
    logger.Set("betaMercury", βs);
  }
  {
    LOG(ERROR)<<"EARTH";
    Instant const t1 = t0_ + Day;
    CHECK_OK(ephemeris_->Prolong(t1));
    auto const& [positions, βs] = equipotential.ComputeLine(
        plane,
        ComputePositionInWorld(t0_, dynamic_frame, SolarSystemFactory::Earth),
        t1);
    logger.Set("equipotentialEarth", positions, mathematica::ExpressIn(Metre));
    logger.Set("betaEarth", βs);
  }
  {
    LOG(ERROR)<<"JUPITER CLOSE";
    Instant const t1 = t0_ + Day;
    CHECK_OK(ephemeris_->Prolong(t1));
    auto const& [positions, βs] = equipotential.ComputeLine(
        plane,
        ComputePositionInWorld(t0_, dynamic_frame, SolarSystemFactory::Jupiter),
        t1);
    logger.Set(
        "equipotentialJupiterClose", positions, mathematica::ExpressIn(Metre));
    logger.Set("betaJupiterClose", βs);
  }
  {
    LOG(ERROR)<<"JUPITER FAR";
    Instant const t1 = t0_ + 100 * Day;
    CHECK_OK(ephemeris_->Prolong(t1));
    auto const& [positions, βs] = equipotential.ComputeLine(
        plane,
        ComputePositionInWorld(t0_, dynamic_frame, SolarSystemFactory::Jupiter),
        t1);
    logger.Set(
        "equipotentialJupiterFar", positions, mathematica::ExpressIn(Metre));
    logger.Set("betaJupiterFar", βs);
  }
}

TEST_F(EquipotentialTest, BodyCentredBodyDirection) {
  mathematica::Logger logger(TEMP_DIR / "equipotential.wl");
  auto const dynamic_frame(
      BodyCentredBodyDirectionDynamicFrame<Barycentric, World>(
          ephemeris_.get(),
          solar_system_->massive_body(
              *ephemeris_,
              SolarSystemFactory::name(SolarSystemFactory::Earth)),
          solar_system_->massive_body(
              *ephemeris_,
              SolarSystemFactory::name(SolarSystemFactory::Moon))));
  Equipotential<Barycentric, World> const equipotential(
      equipotential_parameters_, &dynamic_frame);

  Bivector<double, World> const plane({0, 0, 1});
  std::vector<std::vector<std::vector<Position<World>>>> all_positions;
  std::vector<std::vector<std::vector<double>>> all_βs;
  for (int j = 0; j < 30; ++j) {
    Instant const t = t0_ + j * Day;
    LOG(ERROR) << "EARTH L4";
    CHECK_OK(ephemeris_->Prolong(t));
    all_positions.emplace_back();
    all_βs.emplace_back();
    auto const earth_position =
        ComputePositionInWorld(t, dynamic_frame, SolarSystemFactory::Earth);
    auto const moon_position =
        ComputePositionInWorld(t, dynamic_frame, SolarSystemFactory::Moon);
    auto const moon_earth = earth_position - moon_position;

    Rotation<World, World> const rot_l4(-60 * Degree, plane);
    auto const moon_l4 = rot_l4(moon_earth);
    auto const l4 = moon_l4 + moon_position;
    Rotation<World, World> const rot_l5(60 * Degree, plane);
    auto const moon_l5 = rot_l5(moon_earth);
    auto const l5 = moon_l5 + moon_position;
    for (int i = 0; i <= 10; ++i) {
      Position<World> const p =
          Barycentre(std::pair{l4, l5},
                     std::pair{i / 10.0, (10.0 - i) / 10.0});
      auto const& [positions, βs] = equipotential.ComputeLine(plane, p, t);
      all_positions.back().push_back(positions);
      all_βs.back().push_back(βs);
    }
  }
  logger.Set(
      "equipotentialsEarthMoon", all_positions, mathematica::ExpressIn(Metre));
  logger.Set("betasEarthMoon", all_βs);
}
}  // namespace physics
}  // namespace principia
<|endoftext|>


<commit_before>// @(#)root/physics:$Name:  $:$Id: TGenPhaseSpace.cxx,v 1.3 2000/09/29 07:13:27 brun Exp $
// Author: Rene Brun , Valerio Filippini  06/09/2000

//_____________________________________________________________________________________
//
//  Utility class to generate n-body event,
//  with constant cross-section (default)
//  or with Fermi energy dependence (opt="Fermi").
//  The event is generated in the center-of-mass frame,
//  but the decay products are finally boosted
//  using the betas of the original particle.

#include "TGenPhaseSpace.h"
#include "TRandom.h"
#include "TMath.h"
#include <stdlib.h>

const Int_t kMAXP = 18;

ClassImp(TGenPhaseSpace)

//_____________________________________________________________________________________
Double_t TGenPhaseSpace::pdk(Double_t a, Double_t b, Double_t c)
{
  Double_t x = (a-b-c)*(a+b+c)*(a-b+c)*(a+b-c);
  x = TMath::Sqrt(x)/(2*a);
  return x;
}

//_____________________________________________________________________________________
Int_t DoubleMax(const void *a, const void *b)
{

  Double_t A = * ((Double_t *) a);
  Double_t B = * ((Double_t *) b);
  if (A > B) return  1;
  if (A < B) return -1;
  return 0;

}

//__________________________________________________________________________________________________
TGenPhaseSpace::TGenPhaseSpace(const TGenPhaseSpace &gen)
{
   fNt      = gen.fNt;
   fWtMax   = gen.fWtMax;
   fTeCmTm  = gen.fTeCmTm;
   fBeta[0] = gen.fBeta[0];
   fBeta[1] = gen.fBeta[1];
   fBeta[2] = gen.fBeta[2];
   for (Int_t i=0;i<fNt;i++) {
      fMass[i]   = gen.fMass[i];
      fDecPro[i] = gen.fDecPro[i];
   }
}

//__________________________________________________________________________________________________
Double_t TGenPhaseSpace::Generate()
{
  //  Generate a random final state.
  //  The function returns the weigth of the current event.
  //  The TLorentzVector of each decay product can be get using GetDecay(n).
  //  The maximum weigth can be get using GetWtMax().
  //
  Double_t rno[kMAXP];
  rno[0] = 0;
  Int_t n;
  if (fNt>2) {
    for (n=1; n<fNt-1; n++)  rno[n]=gRandom->Rndm();   // fNt-2 random numbers
    qsort(rno+1 ,fNt-2 ,sizeof(Double_t) ,DoubleMax);  // sort them
  }
  rno[fNt-1] = 1;

  Double_t InvMas[kMAXP], sum=0;
  for (n=0; n<fNt; n++) {
    sum      += fMass[n];
    InvMas[n] = rno[n]*fTeCmTm + sum;
  }

  //
  //-----> compute the weight of the current event
  //
  Double_t wt=fWtMax;
  Double_t pd[kMAXP];
  for (n=0; n<fNt-1; n++) {
    pd[n] = pdk(InvMas[n+1],InvMas[n],fMass[n+1]);
    wt *= pd[n];
  }

  //
  //-----> complete specification of event (Raubold-Lynch method)
  //
  fDecPro[0].SetPxPyPzE(0, pd[0], 0 , TMath::Sqrt(pd[0]*pd[0]+fMass[0]*fMass[0]) );

  Int_t i=1;
  Int_t j;
  while (1) {
    fDecPro[i].SetPxPyPzE(0, -pd[i-1], 0 , TMath::Sqrt(pd[i-1]*pd[i-1]+fMass[i]*fMass[i]) );

    Double_t cZ   = 2*gRandom->Rndm() - 1;
    Double_t sZ   = TMath::Sqrt(1-cZ*cZ);
    Double_t angY = 2*TMath::Pi() * gRandom->Rndm();
    Double_t cY   = TMath::Cos(angY);
    Double_t sY   = TMath::Sin(angY);
    for (j=0; j<=i; j++) {
      TLorentzVector *v = fDecPro+j;
      Double_t x = v->Px();
      Double_t y = v->Py();
      v->SetPx( cZ*x - sZ*y );
      v->SetPy( sZ*x + cZ*y );   // rotation around Z
               x = v->Px();
      Double_t z = v->Pz();
      v->SetPx( cY*x - sY*z );
      v->SetPz( sY*x + cY*z );   // rotation around Y
    }

    if (i == (fNt-1)) break;

    Double_t beta = pd[i] / sqrt(pd[i]*pd[i] + InvMas[i]*InvMas[i]);
    for (j=0; j<=i; j++) fDecPro[j].Boost(0,beta,0);
    i++;
  }

  //
  //---> final boost of all particles
  //
  for (n=0;n<fNt;n++) fDecPro[n].Boost(fBeta[0],fBeta[1],fBeta[2]);

  //
  //---> return the weigth of event
  //
  return wt;
}

//__________________________________________________________________________________
TLorentzVector *TGenPhaseSpace::GetDecay(Int_t n)
{
  if (n>fNt) return 0;
  return fDecPro+n;
}

//_____________________________________________________________________________________
Bool_t TGenPhaseSpace::SetDecay(TLorentzVector &P, Int_t nt,
   Double_t *mass, Option_t *opt)
{
  //
  // input:
  // TLorentzVector &P:    decay particle
  // Int_t nt:             number of decay products
  // Double_t *mass:       array of decay product masses
  // Option_t *opt:        default -> constant cross section
  //                       "Fermi" -> Fermi energy dependece
  // return value:
  // kTRUE:      the decay is permitted by kinematics
  // kFALSE:     the decay is forbidden by kinematics
  //

  Int_t n;
  fNt = nt;
  if (fNt<2 || fNt>18) return kFALSE;  // no more then 18 particle

  //
  //
  //
  fTeCmTm = P.Mag();           // total energy in C.M. minus the sum of the masses
  for (n=0;n<fNt;n++) {
    fMass[n]  = mass[n];
    fTeCmTm  -= mass[n];
  }

  if (fTeCmTm<=0) return kFALSE;    // not enough energy for this decay

  //
  //------> the max weigth depends on opt:
  //   opt == "Fermi"  --> fermi energy dependence for cross section
  //   else            --> constant cross section as function of TECM (default)
  //
  if (strcasecmp(opt,"fermi")==0) {
    // ffq[] = pi * (2*pi)**(FNt-2) / (FNt-2)!
    Double_t ffq[] = {0
		     ,3.141592, 19.73921, 62.01255, 129.8788, 204.0131
		     ,256.3704, 268.4705, 240.9780, 189.2637
		     ,132.1308,  83.0202,  47.4210,  24.8295
		     ,12.0006,   5.3858,   2.2560,   0.8859 };
    fWtMax = TMath::Power(fTeCmTm,fNt-2) * ffq[fNt-1] / P.Mag();

  } else {
    Double_t emmax = fTeCmTm + fMass[0];
    Double_t emmin = 0;
    Double_t wtmax = 1;
    for (n=1; n<fNt; n++) {
      emmin += fMass[n-1];
      emmax += fMass[n];
      wtmax *= pdk(emmax, emmin, fMass[n]);
    }
    fWtMax = 1/wtmax;
  }

  //
  //---->  save the betas of the decaying particle
  //
  if (P.Beta()) {
    Double_t w = P.Beta()/P.Rho();
    fBeta[0] = P(0)*w;
    fBeta[1] = P(1)*w;
    fBeta[2] = P(2)*w;
  }
  else fBeta[0]=fBeta[1]=fBeta[2]=0;

  return kTRUE;
}
<commit_msg>Add a comment pointing to the example $ROOTSYS/PhaseSpace.C<commit_after>// @(#)root/physics:$Name:  $:$Id: TGenPhaseSpace.cxx,v 1.4 2001/01/09 16:33:15 brun Exp $
// Author: Rene Brun , Valerio Filippini  06/09/2000

//_____________________________________________________________________________________
//
//  Utility class to generate n-body event,
//  with constant cross-section (default)
//  or with Fermi energy dependence (opt="Fermi").
//  The event is generated in the center-of-mass frame,
//  but the decay products are finally boosted
//  using the betas of the original particle.
//
// see example of use in $ROOTSYS/tutorials/PhaseSpace.C

#include "TGenPhaseSpace.h"
#include "TRandom.h"
#include "TMath.h"
#include <stdlib.h>

const Int_t kMAXP = 18;

ClassImp(TGenPhaseSpace)

//_____________________________________________________________________________________
Double_t TGenPhaseSpace::pdk(Double_t a, Double_t b, Double_t c)
{
  Double_t x = (a-b-c)*(a+b+c)*(a-b+c)*(a+b-c);
  x = TMath::Sqrt(x)/(2*a);
  return x;
}

//_____________________________________________________________________________________
Int_t DoubleMax(const void *a, const void *b)
{

  Double_t A = * ((Double_t *) a);
  Double_t B = * ((Double_t *) b);
  if (A > B) return  1;
  if (A < B) return -1;
  return 0;

}

//__________________________________________________________________________________________________
TGenPhaseSpace::TGenPhaseSpace(const TGenPhaseSpace &gen)
{
   fNt      = gen.fNt;
   fWtMax   = gen.fWtMax;
   fTeCmTm  = gen.fTeCmTm;
   fBeta[0] = gen.fBeta[0];
   fBeta[1] = gen.fBeta[1];
   fBeta[2] = gen.fBeta[2];
   for (Int_t i=0;i<fNt;i++) {
      fMass[i]   = gen.fMass[i];
      fDecPro[i] = gen.fDecPro[i];
   }
}

//__________________________________________________________________________________________________
Double_t TGenPhaseSpace::Generate()
{
  //  Generate a random final state.
  //  The function returns the weigth of the current event.
  //  The TLorentzVector of each decay product can be get using GetDecay(n).
  //  The maximum weigth can be get using GetWtMax().
  //
  Double_t rno[kMAXP];
  rno[0] = 0;
  Int_t n;
  if (fNt>2) {
    for (n=1; n<fNt-1; n++)  rno[n]=gRandom->Rndm();   // fNt-2 random numbers
    qsort(rno+1 ,fNt-2 ,sizeof(Double_t) ,DoubleMax);  // sort them
  }
  rno[fNt-1] = 1;

  Double_t InvMas[kMAXP], sum=0;
  for (n=0; n<fNt; n++) {
    sum      += fMass[n];
    InvMas[n] = rno[n]*fTeCmTm + sum;
  }

  //
  //-----> compute the weight of the current event
  //
  Double_t wt=fWtMax;
  Double_t pd[kMAXP];
  for (n=0; n<fNt-1; n++) {
    pd[n] = pdk(InvMas[n+1],InvMas[n],fMass[n+1]);
    wt *= pd[n];
  }

  //
  //-----> complete specification of event (Raubold-Lynch method)
  //
  fDecPro[0].SetPxPyPzE(0, pd[0], 0 , TMath::Sqrt(pd[0]*pd[0]+fMass[0]*fMass[0]) );

  Int_t i=1;
  Int_t j;
  while (1) {
    fDecPro[i].SetPxPyPzE(0, -pd[i-1], 0 , TMath::Sqrt(pd[i-1]*pd[i-1]+fMass[i]*fMass[i]) );

    Double_t cZ   = 2*gRandom->Rndm() - 1;
    Double_t sZ   = TMath::Sqrt(1-cZ*cZ);
    Double_t angY = 2*TMath::Pi() * gRandom->Rndm();
    Double_t cY   = TMath::Cos(angY);
    Double_t sY   = TMath::Sin(angY);
    for (j=0; j<=i; j++) {
      TLorentzVector *v = fDecPro+j;
      Double_t x = v->Px();
      Double_t y = v->Py();
      v->SetPx( cZ*x - sZ*y );
      v->SetPy( sZ*x + cZ*y );   // rotation around Z
               x = v->Px();
      Double_t z = v->Pz();
      v->SetPx( cY*x - sY*z );
      v->SetPz( sY*x + cY*z );   // rotation around Y
    }

    if (i == (fNt-1)) break;

    Double_t beta = pd[i] / sqrt(pd[i]*pd[i] + InvMas[i]*InvMas[i]);
    for (j=0; j<=i; j++) fDecPro[j].Boost(0,beta,0);
    i++;
  }

  //
  //---> final boost of all particles
  //
  for (n=0;n<fNt;n++) fDecPro[n].Boost(fBeta[0],fBeta[1],fBeta[2]);

  //
  //---> return the weigth of event
  //
  return wt;
}

//__________________________________________________________________________________
TLorentzVector *TGenPhaseSpace::GetDecay(Int_t n)
{
  if (n>fNt) return 0;
  return fDecPro+n;
}

//_____________________________________________________________________________________
Bool_t TGenPhaseSpace::SetDecay(TLorentzVector &P, Int_t nt,
   Double_t *mass, Option_t *opt)
{
  //
  // input:
  // TLorentzVector &P:    decay particle
  // Int_t nt:             number of decay products
  // Double_t *mass:       array of decay product masses
  // Option_t *opt:        default -> constant cross section
  //                       "Fermi" -> Fermi energy dependece
  // return value:
  // kTRUE:      the decay is permitted by kinematics
  // kFALSE:     the decay is forbidden by kinematics
  //

  Int_t n;
  fNt = nt;
  if (fNt<2 || fNt>18) return kFALSE;  // no more then 18 particle

  //
  //
  //
  fTeCmTm = P.Mag();           // total energy in C.M. minus the sum of the masses
  for (n=0;n<fNt;n++) {
    fMass[n]  = mass[n];
    fTeCmTm  -= mass[n];
  }

  if (fTeCmTm<=0) return kFALSE;    // not enough energy for this decay

  //
  //------> the max weigth depends on opt:
  //   opt == "Fermi"  --> fermi energy dependence for cross section
  //   else            --> constant cross section as function of TECM (default)
  //
  if (strcasecmp(opt,"fermi")==0) {
    // ffq[] = pi * (2*pi)**(FNt-2) / (FNt-2)!
    Double_t ffq[] = {0
		     ,3.141592, 19.73921, 62.01255, 129.8788, 204.0131
		     ,256.3704, 268.4705, 240.9780, 189.2637
		     ,132.1308,  83.0202,  47.4210,  24.8295
		     ,12.0006,   5.3858,   2.2560,   0.8859 };
    fWtMax = TMath::Power(fTeCmTm,fNt-2) * ffq[fNt-1] / P.Mag();

  } else {
    Double_t emmax = fTeCmTm + fMass[0];
    Double_t emmin = 0;
    Double_t wtmax = 1;
    for (n=1; n<fNt; n++) {
      emmin += fMass[n-1];
      emmax += fMass[n];
      wtmax *= pdk(emmax, emmin, fMass[n]);
    }
    fWtMax = 1/wtmax;
  }

  //
  //---->  save the betas of the decaying particle
  //
  if (P.Beta()) {
    Double_t w = P.Beta()/P.Rho();
    fBeta[0] = P(0)*w;
    fBeta[1] = P(1)*w;
    fBeta[2] = P(2)*w;
  }
  else fBeta[0]=fBeta[1]=fBeta[2]=0;

  return kTRUE;
}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "absl/memory/memory.h"
#include "api/rtp_packet_infos.h"
#include "modules/video_coding/frame_object.h"
#include "modules/video_coding/packet_buffer.h"
#include "modules/video_coding/rtp_frame_reference_finder.h"
#include "system_wrappers/include/clock.h"

namespace webrtc {

namespace {
struct DataReader {
  DataReader(const uint8_t* data, size_t size) : data_(data), size_(size) {}

  void CopyTo(void* destination, size_t size) {
    uint8_t* dest = reinterpret_cast<uint8_t*>(destination);
    size_t num_bytes = std::min(size_ - offset_, size);
    memcpy(dest, data_ + offset_, num_bytes);
    offset_ += num_bytes;

    size -= num_bytes;
    if (size > 0)
      memset(dest + num_bytes, 0, size);
  }

  template <typename T>
  T GetNum() {
    T res;
    if (offset_ + sizeof(res) < size_) {
      memcpy(&res, data_ + offset_, sizeof(res));
      offset_ += sizeof(res);
      return res;
    }

    offset_ = size_;
    return T(0);
  }

  bool MoreToRead() { return offset_ < size_; }

  const uint8_t* data_;
  size_t size_;
  size_t offset_ = 0;
};

class NullCallback : public video_coding::OnCompleteFrameCallback {
  void OnCompleteFrame(
      std::unique_ptr<video_coding::EncodedFrame> frame) override {}
};

class FuzzyPacketBuffer : public video_coding::PacketBuffer {
 public:
  explicit FuzzyPacketBuffer(DataReader* reader)
      : PacketBuffer(nullptr, 2, 4, nullptr), reader(reader) {
    switch (reader->GetNum<uint8_t>() % 3) {
      case 0:
        codec = kVideoCodecVP8;
        break;
      case 1:
        codec = kVideoCodecVP9;
        break;
      case 2:
        codec = kVideoCodecH264;
        break;
    }
  }

  VCMPacket* GetPacket(uint16_t seq_num) override {
    auto packet_it = packets.find(seq_num);
    if (packet_it != packets.end())
      return &packet_it->second;

    VCMPacket* packet = &packets[seq_num];
    packet->video_header.codec = codec;
    switch (codec) {
      case kVideoCodecVP8:
        packet->video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
        break;
      case kVideoCodecVP9:
        packet->video_header.video_type_header.emplace<RTPVideoHeaderVP9>();
        break;
      case kVideoCodecH264:
        packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
        break;
      default:
        RTC_NOTREACHED();
    }
    packet->markerBit = true;
    reader->CopyTo(packet, sizeof(packet));
    return packet;
  }

  bool GetBitstream(const video_coding::RtpFrameObject& frame,
                    uint8_t* destination) override {
    return true;
  }

  void ReturnFrame(video_coding::RtpFrameObject* frame) override {}

 private:
  std::map<uint16_t, VCMPacket> packets;
  VideoCodecType codec;
  DataReader* const reader;
};
}  // namespace

void FuzzOneInput(const uint8_t* data, size_t size) {
  if (size > 20000) {
    return;
  }
  DataReader reader(data, size);
  rtc::scoped_refptr<FuzzyPacketBuffer> pb(new FuzzyPacketBuffer(&reader));
  NullCallback cb;
  video_coding::RtpFrameReferenceFinder reference_finder(&cb);

  while (reader.MoreToRead()) {
    auto frame = absl::make_unique<video_coding::RtpFrameObject>(
        pb, reader.GetNum<uint16_t>(), reader.GetNum<uint16_t>(), 0, 0, 0, 0,
        RtpPacketInfos());
    reference_finder.ManageFrame(std::move(frame));
  }
}

}  // namespace webrtc
<commit_msg>Fix RtpFrameReferenceFinderFuzzer to not generate invalid input<commit_after>/*
 *  Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "absl/memory/memory.h"
#include "api/rtp_packet_infos.h"
#include "modules/video_coding/frame_object.h"
#include "modules/video_coding/packet_buffer.h"
#include "modules/video_coding/rtp_frame_reference_finder.h"
#include "system_wrappers/include/clock.h"

namespace webrtc {

namespace {
struct DataReader {
  DataReader(const uint8_t* data, size_t size) : data_(data), size_(size) {}

  void CopyTo(void* destination, size_t size) {
    uint8_t* dest = reinterpret_cast<uint8_t*>(destination);
    size_t num_bytes = std::min(size_ - offset_, size);
    memcpy(dest, data_ + offset_, num_bytes);
    offset_ += num_bytes;

    size -= num_bytes;
    if (size > 0)
      memset(dest + num_bytes, 0, size);
  }

  template <typename T>
  T GetNum() {
    T res;
    if (offset_ + sizeof(res) < size_) {
      memcpy(&res, data_ + offset_, sizeof(res));
      offset_ += sizeof(res);
      return res;
    }

    offset_ = size_;
    return T(0);
  }

  bool MoreToRead() { return offset_ < size_; }

  const uint8_t* data_;
  size_t size_;
  size_t offset_ = 0;
};

class NullCallback : public video_coding::OnCompleteFrameCallback {
  void OnCompleteFrame(
      std::unique_ptr<video_coding::EncodedFrame> frame) override {}
};

class FuzzyPacketBuffer : public video_coding::PacketBuffer {
 public:
  explicit FuzzyPacketBuffer(DataReader* reader)
      : PacketBuffer(nullptr, 2, 4, nullptr), reader(reader) {
    switch (reader->GetNum<uint8_t>() % 3) {
      case 0:
        codec = kVideoCodecVP8;
        break;
      case 1:
        codec = kVideoCodecVP9;
        break;
      case 2:
        codec = kVideoCodecH264;
        break;
    }
  }

  VCMPacket* GetPacket(uint16_t seq_num) override {
    auto packet_it = packets.find(seq_num);
    if (packet_it != packets.end())
      return &packet_it->second;

    VCMPacket* packet = &packets[seq_num];
    packet->video_header.codec = codec;
    switch (codec) {
      case kVideoCodecVP8:
        packet->video_header.video_type_header.emplace<RTPVideoHeaderVP8>();
        break;
      case kVideoCodecVP9:
        packet->video_header.video_type_header.emplace<RTPVideoHeaderVP9>();
        break;
      case kVideoCodecH264:
        packet->video_header.video_type_header.emplace<RTPVideoHeaderH264>();
        break;
      default:
        RTC_NOTREACHED();
    }
    packet->markerBit = true;
    reader->CopyTo(packet, sizeof(packet));
    return packet;
  }

  bool GetBitstream(const video_coding::RtpFrameObject& frame,
                    uint8_t* destination) override {
    return true;
  }

  void ReturnFrame(video_coding::RtpFrameObject* frame) override {}

 private:
  std::map<uint16_t, VCMPacket> packets;
  VideoCodecType codec;
  DataReader* const reader;
};
}  // namespace

void FuzzOneInput(const uint8_t* data, size_t size) {
  if (size > 20000) {
    return;
  }
  DataReader reader(data, size);
  rtc::scoped_refptr<FuzzyPacketBuffer> pb(new FuzzyPacketBuffer(&reader));
  NullCallback cb;
  video_coding::RtpFrameReferenceFinder reference_finder(&cb);

  while (reader.MoreToRead()) {
    // Make sure that these packets fulfill the contract of RtpFrameObject.
    uint16_t first_seq_num = reader.GetNum<uint16_t>();
    uint16_t last_seq_num = reader.GetNum<uint16_t>();
    VCMPacket* first_packet = pb->GetPacket(first_seq_num);
    VCMPacket* last_packet = pb->GetPacket(last_seq_num);
    first_packet->video_header.is_first_packet_in_frame = true;
    last_packet->video_header.is_last_packet_in_frame = true;

    auto frame = absl::make_unique<video_coding::RtpFrameObject>(
        pb, first_seq_num, last_seq_num, 0, 0, 0, 0, RtpPacketInfos());
    reference_finder.ManageFrame(std::move(frame));
  }
}

}  // namespace webrtc
<|endoftext|>


<commit_before>#include "llvm/ADT/OwningPtr.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Config/config.h"

using namespace llvm;

static cl::opt<std::string>
InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));

static cl::opt<std::string>
OutputFilename("o", cl::desc("Output filename"),
               cl::value_desc("filename"));

int main(int argc, char **argv) {
  LLVMContext &Context = getGlobalContext();
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  cl::ParseCommandLineOptions(argc, argv, "libclc builtin preparation tool\n");

  std::string ErrorMessage;
  std::auto_ptr<Module> M;

  {
    OwningPtr<MemoryBuffer> BufferPtr;
    if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr))
      ErrorMessage = ec.message();
    else {
#if LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4)
      ErrorOr<Module *> ModuleOrErr = parseBitcodeFile(BufferPtr.get(), Context);
      if (error_code ec = ModuleOrErr.getError())
        ErrorMessage = ec.message();
      M.reset(ModuleOrErr.get());
#else
      M.reset(ParseBitcodeFile(BufferPtr.get(), Context, &ErrorMessage));
#endif
    }
  }

  if (M.get() == 0) {
    errs() << argv[0] << ": ";
    if (ErrorMessage.size())
      errs() << ErrorMessage << "\n";
    else
      errs() << "bitcode didn't read correctly.\n";
    return 1;
  }

  // Set linkage of every external definition to linkonce_odr.
  for (Module::iterator i = M->begin(), e = M->end(); i != e; ++i) {
    if (!i->isDeclaration() && i->getLinkage() == GlobalValue::ExternalLinkage)
      i->setLinkage(GlobalValue::LinkOnceODRLinkage);
  }

  for (Module::global_iterator i = M->global_begin(), e = M->global_end();
       i != e; ++i) {
    if (!i->isDeclaration() && i->getLinkage() == GlobalValue::ExternalLinkage)
      i->setLinkage(GlobalValue::LinkOnceODRLinkage);
  }

  if (OutputFilename.empty()) {
    errs() << "no output file\n";
    return 1;
  }

  std::string ErrorInfo;
  OwningPtr<tool_output_file> Out
  (new tool_output_file(OutputFilename.c_str(), ErrorInfo,
#if (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR == 4)
                        sys::fs::F_Binary));
#elif LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 5)
                        sys::fs::F_None));
#else
                        raw_fd_ostream::F_Binary));
#endif
  if (!ErrorInfo.empty()) {
    errs() << ErrorInfo << '\n';
    exit(1);
  }

  WriteBitcodeToFile(M.get(), Out->os());

  // Declare success.
  Out->keep();
  return 0;
}

<commit_msg>Fix build broken by LLVM commit r209103<commit_after>#include "llvm/ADT/OwningPtr.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Config/config.h"

using namespace llvm;

static cl::opt<std::string>
InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));

static cl::opt<std::string>
OutputFilename("o", cl::desc("Output filename"),
               cl::value_desc("filename"));

int main(int argc, char **argv) {
  LLVMContext &Context = getGlobalContext();
  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.

  cl::ParseCommandLineOptions(argc, argv, "libclc builtin preparation tool\n");

  std::string ErrorMessage;
  std::auto_ptr<Module> M;

  {
#if LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4)
    std::unique_ptr<MemoryBuffer> BufferPtr;
#else
    OwningPtr<MemoryBuffer> BufferPtr;
#endif
    if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr))
      ErrorMessage = ec.message();
    else {
#if LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4)
      ErrorOr<Module *> ModuleOrErr = parseBitcodeFile(BufferPtr.get(), Context);
      if (error_code ec = ModuleOrErr.getError())
        ErrorMessage = ec.message();
      M.reset(ModuleOrErr.get());
#else
      M.reset(ParseBitcodeFile(BufferPtr.get(), Context, &ErrorMessage));
#endif
    }
  }

  if (M.get() == 0) {
    errs() << argv[0] << ": ";
    if (ErrorMessage.size())
      errs() << ErrorMessage << "\n";
    else
      errs() << "bitcode didn't read correctly.\n";
    return 1;
  }

  // Set linkage of every external definition to linkonce_odr.
  for (Module::iterator i = M->begin(), e = M->end(); i != e; ++i) {
    if (!i->isDeclaration() && i->getLinkage() == GlobalValue::ExternalLinkage)
      i->setLinkage(GlobalValue::LinkOnceODRLinkage);
  }

  for (Module::global_iterator i = M->global_begin(), e = M->global_end();
       i != e; ++i) {
    if (!i->isDeclaration() && i->getLinkage() == GlobalValue::ExternalLinkage)
      i->setLinkage(GlobalValue::LinkOnceODRLinkage);
  }

  if (OutputFilename.empty()) {
    errs() << "no output file\n";
    return 1;
  }

  std::string ErrorInfo;
  OwningPtr<tool_output_file> Out
  (new tool_output_file(OutputFilename.c_str(), ErrorInfo,
#if (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR == 4)
                        sys::fs::F_Binary));
#elif LLVM_VERSION_MAJOR > 3 || (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 5)
                        sys::fs::F_None));
#else
                        raw_fd_ostream::F_Binary));
#endif
  if (!ErrorInfo.empty()) {
    errs() << ErrorInfo << '\n';
    exit(1);
  }

  WriteBitcodeToFile(M.get(), Out->os());

  // Declare success.
  Out->keep();
  return 0;
}

<|endoftext|>


<commit_before>#include <rtt/os/main.h>

#include <boost/program_options.hpp>
#include <iostream>

#ifdef OROGEN_SERVICE_DISCOVERY_ACTIVATED
#include <service_discovery/service_discovery.h>
#endif // OROGEN_SERVICE_DISCOVERY_ACTIVATED

#include <rtt/typekit/RealTimeTypekit.hpp>
<% deployer.rtt_transports.each do |transport_name| %>
#include <rtt/transports/<%= transport_name %>/TransportPlugin.hpp>
<% end %>

<% if component.typekit || !component.used_typekits.empty? %>#include <rtt/types/TypekitPlugin.hpp><% end %>
<% if typekit = component.typekit %>
#include "typekit/Plugin.hpp"
<% deployer.transports.each do |transport_name| %>
#include "typekit/transports/<%= transport_name %>/TransportPlugin.hpp"
<% end %>
<% end %>
<% deployer.used_typekits.each do |tk| %>
    <% next if tk.virtual? %>
#include <<%= tk.name %>/typekit/Plugin.hpp>
    <% deployer.transports.each do |transport_name| %>
#include <<%= tk.name %>/transports/<%= transport_name %>/TransportPlugin.hpp>
    <% end %>
<% end %>

<% task_activities = deployer.task_activities.
        sort_by(&:name) %>

<% task_activities.each do |task| %>
#include <<%= task.context.header_file %>>
<% end %>
<% if deployer.corba_enabled? %>
#include <rtt/transports/corba/ApplicationServer.hpp>
#include <rtt/transports/corba/TaskContextServer.hpp>
#include <rtt/transports/corba/CorbaDispatcher.hpp>
#include <signal.h>
<% end %>

<% require 'set'
    activity_headers = task_activities.
        map { |t| t.activity_type.header }.
        compact.
        to_set %>
<% activity_headers.to_a.sort.each do |header| %>
#include <<%= header %>>
<% end %>

<% if deployer.browse %>
#include <ocl/TaskBrowser.hpp>
<% end %>

#include <rtt/Logger.hpp>
#include <rtt/base/ActivityInterface.hpp>

namespace po = boost::program_options;

class Deinitializer
{
    friend Deinitializer& operator << (Deinitializer&, RTT::base::ActivityInterface&);

    std::vector<RTT::base::ActivityInterface*> m_activities;

#ifdef OROGEN_SERVICE_DISCOVERY_ACTIVATED
    friend Deinitializer& operator << (Deinitializer&, servicediscovery::ServiceDiscovery&);

    std::vector<servicediscovery::ServiceDiscovery*> m_service_discoveries;
#endif

public:
    ~Deinitializer()
    {
        for (std::vector<RTT::base::ActivityInterface*>::const_iterator it = m_activities.begin();
                it != m_activities.end(); ++it)
        {
            (*it)->stop();
        }

#ifdef OROGEN_SERVICE_DISCOVERY_ACTIVATED
        for(std::vector<servicediscovery::ServiceDiscovery*>::iterator sit = m_service_discoveries.begin();
                sit != m_service_discoveries.end(); ++sit)
        {
            (*sit)->stop();
            delete *sit;
        }
#endif
    }
};

Deinitializer& operator << (Deinitializer& deinit, RTT::base::ActivityInterface& activity)
{
    deinit.m_activities.push_back(&activity);
    return deinit;
}

#ifdef OROGEN_SERVICE_DISCOVERY_ACTIVATED
Deinitializer& operator << (Deinitializer& deinit, servicediscovery::ServiceDiscovery& service_discovery)
{
    deinit.m_service_discoveries.push_back(&service_discovery);
    return deinit;
}
#endif

<% if deployer.corba_enabled? %>
void sigint_quit_orb(int)
{
    RTT::corba::TaskContextServer::ShutdownOrb(false);
}
<% end %>

int ORO_main(int argc, char* argv[])
{
   po::options_description desc("Options");

   desc.add_options()
        ("help", "show all available options supported by this deployment")
        ("prefix", po::value<std::string>(), "Sets a prefix for all TaskContext names")
#ifdef OROGEN_SERVICE_DISCOVERY_ACTIVATED
        ("sd-domain", po::value<std::string>(), "set service discovery domain")
#endif // OROGEN_SERVICE_DISOCVERY_ACTIVATED
        ("rename", po::value< std::vector<std::string> >(), "rename a task of the deployment: --rename oldname:newname");

   po::variables_map vm;
   po::store(po::parse_command_line(argc, argv, desc), vm);
   po::notify(vm);

   if(vm.count("help")) {
       std::cout << desc << std::endl;
       return 0;
   }

   <% if deployer.loglevel %>
   if ( log().getLogLevel() < Logger::<%= deployer.loglevel %> ) {
       log().setLogLevel( Logger::<%= deployer.loglevel %> );
   }
   <% end %>

   RTT::types::TypekitRepository::Import( new RTT::types::RealTimeTypekitPlugin );
   <% if deployer.transports.include?('corba') %>
   RTT::types::TypekitRepository::Import( new RTT::corba::CorbaLibPlugin );
   <% end %>
   <% if deployer.transports.include?('mqueue') %>
   RTT::types::TypekitRepository::Import( new RTT::mqueue::MQLibPlugin );
   <% end %>

   <% if component.typekit %>
   RTT::types::TypekitRepository::Import( new orogen_typekits::<%= component.name %>TypekitPlugin );
   <% deployer.transports.each do |transport_name| %>
   RTT::types::TypekitRepository::Import( new <%= typekit.transport_plugin_name(transport_name) %> );
   <% end %>
   <% end %>
   <% deployer.used_typekits.each do |tk| %>
   <% next if tk.virtual? %>
   RTT::types::TypekitRepository::Import( new orogen_typekits::<%= tk.name %>TypekitPlugin );
       <% deployer.transports.each do |transport_name| %>
   RTT::types::TypekitRepository::Import( new <%= Orocos::Generation::Typekit.transport_plugin_name(transport_name, tk.name) %> );
       <% end %>
   <% end %>

<% if deployer.corba_enabled? %>
    RTT::corba::ApplicationServer::InitOrb(argc, argv);
<% end %>

    std::string prefix = "";

    if( vm.count("prefix"))
        prefix = vm["prefix"].as<std::string>();

    std::string task_name;

    std::map<std::string, std::string> rename_map;

    if ( vm.count("rename") ) {

        const std::vector< std::string>& ren_vec = vm["rename"].as<std::vector <std::string> >();

        for ( unsigned int i = 0; i < ren_vec.size(); i++) {

            const std::string& ren_str = ren_vec.at(i);

            unsigned int colon_pos = ren_str.find(':');
            if ( colon_pos == std::string::npos ) continue;

            rename_map.insert( std::pair<std::string, std::string>(
                ren_str.substr(0,colon_pos), ren_str.substr(colon_pos+1) ));
        }
    }

<% task_activities.each do |task| %>
    task_name = "<%= task.name %>";
    if (rename_map.count(task_name))
        task_name = rename_map[task_name];
    else
        task_name = prefix + task_name;

    <%= task.context.class_name %> task_<%= task.name%>(task_name);
    <%= task.generate_activity_setup %>
    task_<%= task.name %>.setActivity(activity_<%= task.name %>);
    <% task.properties.sort_by { |prop| prop.name }.each do |prop|
        if prop.value %>
    dynamic_cast< RTT::Property<  <%= prop.interface_object.type.cxx_name %> >*>(
            task_<%= task.name %>.properties()->getProperty("<%= prop.name %>"))
        ->set(<%= prop.value.inspect %>);
        <% end %>
    <% end %>

    <% if deployer.corba_enabled? %>
    RTT::corba::TaskContextServer::Create( &task_<%= task.name%> );
    <% if task.realtime? %>
    RTT::corba::CorbaDispatcher::Instance( task_<%= task.name %>.ports(), ORO_SCHED_RT, RTT::os::LowestPriority );
    <% else %>
    RTT::corba::CorbaDispatcher::Instance( task_<%= task.name %>.ports(), ORO_SCHED_OTHER, RTT::os::LowestPriority );
    <% end %>
    <% end %>

<% end %>

   Deinitializer deinit;

#ifdef OROGEN_SERVICE_DISCOVERY_ACTIVATED
    if( vm.count("sd-domain") ) {
<% task_activities.each do |task| %>
    servicediscovery::ServiceConfiguration sd_conf_<%= task.name%>(prefix + "<%= task.name %>", vm["sd-domain"].as<std::string>());
    sd_conf_<%= task.name%>.setDescription("IOR", RTT::corba::TaskContextServer::getIOR(&task_<%= task.name%>));
    servicediscovery::ServiceDiscovery* sd_<%= task.name%> = new servicediscovery::ServiceDiscovery();
    deinit << *sd_<%= task.name%>;
    sd_<%= task.name%>->start(sd_conf_<%= task.name%>);
<% end %>
    }
#endif // OROGEN_SERVICE_DISCOVERY_ACTIVATED

<% if !deployer.loggers.empty?
        deployer.loggers.sort_by { |filename, _| filename }.each do |filename, logger|
            logger.config.each do |type, reported_activity, args| %>
                task_<%= logger.task.name %>.connectPeers(&task_<%= reported_activity.name %>);
                task_<%= logger.task.name %>.report<%= type %>(<%= args.map { |v| "\"#{v}\"" }.join(", ") %>);
            <% end %>
        <% end %>
<% end %>

<% deployer.peers.sort_by { |a, b| [a.name, b.name] }.each do |a, b| %>
    task_<%= a.name %>.connectPeers(&task_<%= b.name %>);
<% end %>

<% deployer.connections.
    sort_by { |src, dst, policy| [src.name, dst.name] }.
    each do |src, dst, policy|
        if src.kind_of?(TaskDeployment) %>
            task_<%= src.activity.name %>.connectPorts(&task_<%= dst.activity.name %>);
        <% else %>
        {
            <%= policy.to_code("policy") %>
            RTT::base::OutputPortInterface* src = dynamic_cast<RTT::base::OutputPortInterface*>(
                    task_<%= src.activity.name %>.ports()->getPort("<%= src.name %>"));
            RTT::base::InputPortInterface* dst = dynamic_cast<RTT::base::InputPortInterface*>(
                    task_<%= dst.activity.name %>.ports()->getPort("<%= dst.name %>"));
            src->createConnection(*dst, policy);
        }
        <% end %>
    <% end %>

    // Start some activities
<% task_activities.each do |task| %>
    deinit << *activity_<%= task.name%>;

    <% if task.start?
        if task.context.needs_configuration? %>
    if (!task_<%= task.name %>.configure())
    {
        RTT::log(RTT::Error) << "cannot configure <%= task.name %>" << RTT::endlog();
        return -1;
    }
        <% end %>
    if (!task_<%= task.name %>.start())
    {
        RTT::log(RTT::Error) << "cannot start <%= task.name %>" << RTT::endlog();
        return -1;
    }
    <% end %>
<% end %>

<% if deployer.corba_enabled? %>
    struct sigaction sigint_handler;
    sigint_handler.sa_handler = &sigint_quit_orb;
    sigemptyset(&sigint_handler.sa_mask);
    sigint_handler.sa_flags     = 0;
    sigint_handler.sa_restorer  = 0;
    if (-1 == sigaction(SIGINT, &sigint_handler, 0))
    {
        std::cerr << "failed to install SIGINT handler" << std::endl;
        return 1;
    }
    sigset_t unblock_sigint;
    sigemptyset(&unblock_sigint);
    sigaddset(&unblock_sigint, SIGINT);
    if (-1 == sigprocmask(SIG_UNBLOCK, &unblock_sigint, NULL))
    {
        std::cerr << "failed to install SIGINT handler" << std::endl;
        return 1;
    }
    RTT::corba::TaskContextServer::RunOrb();
<% elsif deployer.browse %>
    OCL::TaskBrowser browser(& task_<%= deployer.browse.name %>);
    browser.loop();
<% end %>

    return 0;
}

<commit_msg>gen: fix shutdown in orogen-generated components<commit_after>#include <rtt/os/main.h>

#include <boost/program_options.hpp>
#include <iostream>

#ifdef OROGEN_SERVICE_DISCOVERY_ACTIVATED
#include <service_discovery/service_discovery.h>
#endif // OROGEN_SERVICE_DISCOVERY_ACTIVATED

#include <rtt/typekit/RealTimeTypekit.hpp>
<% deployer.rtt_transports.each do |transport_name| %>
#include <rtt/transports/<%= transport_name %>/TransportPlugin.hpp>
<% end %>

<% if component.typekit || !component.used_typekits.empty? %>#include <rtt/types/TypekitPlugin.hpp><% end %>
<% if typekit = component.typekit %>
#include "typekit/Plugin.hpp"
<% deployer.transports.each do |transport_name| %>
#include "typekit/transports/<%= transport_name %>/TransportPlugin.hpp"
<% end %>
<% end %>
<% deployer.used_typekits.each do |tk| %>
    <% next if tk.virtual? %>
#include <<%= tk.name %>/typekit/Plugin.hpp>
    <% deployer.transports.each do |transport_name| %>
#include <<%= tk.name %>/transports/<%= transport_name %>/TransportPlugin.hpp>
    <% end %>
<% end %>

<% task_activities = deployer.task_activities.
        sort_by(&:name) %>

<% task_activities.each do |task| %>
#include <<%= task.context.header_file %>>
<% end %>
<% if deployer.corba_enabled? %>
#include <rtt/transports/corba/ApplicationServer.hpp>
#include <rtt/transports/corba/TaskContextServer.hpp>
#include <rtt/transports/corba/CorbaDispatcher.hpp>
#include <signal.h>
<% end %>

<% require 'set'
    activity_headers = task_activities.
        map { |t| t.activity_type.header }.
        compact.
        to_set %>
<% activity_headers.to_a.sort.each do |header| %>
#include <<%= header %>>
<% end %>

<% if deployer.browse %>
#include <ocl/TaskBrowser.hpp>
<% end %>

#include <rtt/Logger.hpp>
#include <rtt/base/ActivityInterface.hpp>

namespace po = boost::program_options;

class Deinitializer
{
    friend Deinitializer& operator << (Deinitializer&, RTT::base::ActivityInterface&);

    std::vector<RTT::base::ActivityInterface*> m_activities;

#ifdef OROGEN_SERVICE_DISCOVERY_ACTIVATED
    friend Deinitializer& operator << (Deinitializer&, servicediscovery::ServiceDiscovery&);

    std::vector<servicediscovery::ServiceDiscovery*> m_service_discoveries;
#endif

public:
    ~Deinitializer()
    {
        for (std::vector<RTT::base::ActivityInterface*>::const_iterator it = m_activities.begin();
                it != m_activities.end(); ++it)
        {
            (*it)->stop();
        }

#ifdef OROGEN_SERVICE_DISCOVERY_ACTIVATED
        for(std::vector<servicediscovery::ServiceDiscovery*>::iterator sit = m_service_discoveries.begin();
                sit != m_service_discoveries.end(); ++sit)
        {
            (*sit)->stop();
            delete *sit;
        }
#endif
    }
};

Deinitializer& operator << (Deinitializer& deinit, RTT::base::ActivityInterface& activity)
{
    deinit.m_activities.push_back(&activity);
    return deinit;
}

#ifdef OROGEN_SERVICE_DISCOVERY_ACTIVATED
Deinitializer& operator << (Deinitializer& deinit, servicediscovery::ServiceDiscovery& service_discovery)
{
    deinit.m_service_discoveries.push_back(&service_discovery);
    return deinit;
}
#endif

<% if deployer.corba_enabled? %>
int sigint_com[2];
void sigint_quit_orb(int)
{
    uint8_t dummy = 0;
    write(sigint_com[1], &dummy, 1);
}
<% end %>

int ORO_main(int argc, char* argv[])
{
   po::options_description desc("Options");

   desc.add_options()
        ("help", "show all available options supported by this deployment")
        ("prefix", po::value<std::string>(), "Sets a prefix for all TaskContext names")
#ifdef OROGEN_SERVICE_DISCOVERY_ACTIVATED
        ("sd-domain", po::value<std::string>(), "set service discovery domain")
#endif // OROGEN_SERVICE_DISOCVERY_ACTIVATED
        ("rename", po::value< std::vector<std::string> >(), "rename a task of the deployment: --rename oldname:newname");

   po::variables_map vm;
   po::store(po::parse_command_line(argc, argv, desc), vm);
   po::notify(vm);

   if(vm.count("help")) {
       std::cout << desc << std::endl;
       return 0;
   }

   <% if deployer.loglevel %>
   if ( log().getLogLevel() < Logger::<%= deployer.loglevel %> ) {
       log().setLogLevel( Logger::<%= deployer.loglevel %> );
   }
   <% end %>

   RTT::types::TypekitRepository::Import( new RTT::types::RealTimeTypekitPlugin );
   <% if deployer.transports.include?('corba') %>
   RTT::types::TypekitRepository::Import( new RTT::corba::CorbaLibPlugin );
   <% end %>
   <% if deployer.transports.include?('mqueue') %>
   RTT::types::TypekitRepository::Import( new RTT::mqueue::MQLibPlugin );
   <% end %>

   <% if component.typekit %>
   RTT::types::TypekitRepository::Import( new orogen_typekits::<%= component.name %>TypekitPlugin );
   <% deployer.transports.each do |transport_name| %>
   RTT::types::TypekitRepository::Import( new <%= typekit.transport_plugin_name(transport_name) %> );
   <% end %>
   <% end %>
   <% deployer.used_typekits.each do |tk| %>
   <% next if tk.virtual? %>
   RTT::types::TypekitRepository::Import( new orogen_typekits::<%= tk.name %>TypekitPlugin );
       <% deployer.transports.each do |transport_name| %>
   RTT::types::TypekitRepository::Import( new <%= Orocos::Generation::Typekit.transport_plugin_name(transport_name, tk.name) %> );
       <% end %>
   <% end %>

<% if deployer.corba_enabled? %>
    RTT::corba::ApplicationServer::InitOrb(argc, argv);
<% end %>

    std::string prefix = "";

    if( vm.count("prefix"))
        prefix = vm["prefix"].as<std::string>();

    std::string task_name;

    std::map<std::string, std::string> rename_map;

    if ( vm.count("rename") ) {

        const std::vector< std::string>& ren_vec = vm["rename"].as<std::vector <std::string> >();

        for ( unsigned int i = 0; i < ren_vec.size(); i++) {

            const std::string& ren_str = ren_vec.at(i);

            unsigned int colon_pos = ren_str.find(':');
            if ( colon_pos == std::string::npos ) continue;

            rename_map.insert( std::pair<std::string, std::string>(
                ren_str.substr(0,colon_pos), ren_str.substr(colon_pos+1) ));
        }
    }

<% task_activities.each do |task| %>
    task_name = "<%= task.name %>";
    if (rename_map.count(task_name))
        task_name = rename_map[task_name];
    else
        task_name = prefix + task_name;

    <%= task.context.class_name %> task_<%= task.name%>(task_name);
    <%= task.generate_activity_setup %>
    task_<%= task.name %>.setActivity(activity_<%= task.name %>);
    <% task.properties.sort_by { |prop| prop.name }.each do |prop|
        if prop.value %>
    dynamic_cast< RTT::Property<  <%= prop.interface_object.type.cxx_name %> >*>(
            task_<%= task.name %>.properties()->getProperty("<%= prop.name %>"))
        ->set(<%= prop.value.inspect %>);
        <% end %>
    <% end %>

    <% if deployer.corba_enabled? %>
    RTT::corba::TaskContextServer::Create( &task_<%= task.name%> );
    <% if task.realtime? %>
    RTT::corba::CorbaDispatcher::Instance( task_<%= task.name %>.ports(), ORO_SCHED_RT, RTT::os::LowestPriority );
    <% else %>
    RTT::corba::CorbaDispatcher::Instance( task_<%= task.name %>.ports(), ORO_SCHED_OTHER, RTT::os::LowestPriority );
    <% end %>
    <% end %>

<% end %>

   Deinitializer deinit;

#ifdef OROGEN_SERVICE_DISCOVERY_ACTIVATED
    if( vm.count("sd-domain") ) {
<% task_activities.each do |task| %>
    servicediscovery::ServiceConfiguration sd_conf_<%= task.name%>(prefix + "<%= task.name %>", vm["sd-domain"].as<std::string>());
    sd_conf_<%= task.name%>.setDescription("IOR", RTT::corba::TaskContextServer::getIOR(&task_<%= task.name%>));
    servicediscovery::ServiceDiscovery* sd_<%= task.name%> = new servicediscovery::ServiceDiscovery();
    deinit << *sd_<%= task.name%>;
    sd_<%= task.name%>->start(sd_conf_<%= task.name%>);
<% end %>
    }
#endif // OROGEN_SERVICE_DISCOVERY_ACTIVATED

<% if !deployer.loggers.empty?
        deployer.loggers.sort_by { |filename, _| filename }.each do |filename, logger|
            logger.config.each do |type, reported_activity, args| %>
                task_<%= logger.task.name %>.connectPeers(&task_<%= reported_activity.name %>);
                task_<%= logger.task.name %>.report<%= type %>(<%= args.map { |v| "\"#{v}\"" }.join(", ") %>);
            <% end %>
        <% end %>
<% end %>

<% deployer.peers.sort_by { |a, b| [a.name, b.name] }.each do |a, b| %>
    task_<%= a.name %>.connectPeers(&task_<%= b.name %>);
<% end %>

<% deployer.connections.
    sort_by { |src, dst, policy| [src.name, dst.name] }.
    each do |src, dst, policy|
        if src.kind_of?(TaskDeployment) %>
            task_<%= src.activity.name %>.connectPorts(&task_<%= dst.activity.name %>);
        <% else %>
        {
            <%= policy.to_code("policy") %>
            RTT::base::OutputPortInterface* src = dynamic_cast<RTT::base::OutputPortInterface*>(
                    task_<%= src.activity.name %>.ports()->getPort("<%= src.name %>"));
            RTT::base::InputPortInterface* dst = dynamic_cast<RTT::base::InputPortInterface*>(
                    task_<%= dst.activity.name %>.ports()->getPort("<%= dst.name %>"));
            src->createConnection(*dst, policy);
        }
        <% end %>
    <% end %>

    // Start some activities
<% task_activities.each do |task| %>
    deinit << *activity_<%= task.name%>;

    <% if task.start?
        if task.context.needs_configuration? %>
    if (!task_<%= task.name %>.configure())
    {
        RTT::log(RTT::Error) << "cannot configure <%= task.name %>" << RTT::endlog();
        return -1;
    }
        <% end %>
    if (!task_<%= task.name %>.start())
    {
        RTT::log(RTT::Error) << "cannot start <%= task.name %>" << RTT::endlog();
        return -1;
    }
    <% end %>
<% end %>

<% if deployer.corba_enabled? %>
    /** Setup shutdown procedure on SIGINT. We use a pipe-based channel to do
        so, as we can't shutdown the ORB from the signal handler */
    if (pipe(sigint_com) == -1)
    {
        std::cerr << "failed to setup SIGINT handler: " << strerror(errno) << std::endl;
        return 1;
    }

    struct sigaction sigint_handler;
    sigint_handler.sa_handler = &sigint_quit_orb;
    sigemptyset(&sigint_handler.sa_mask);
    sigint_handler.sa_flags     = 0;
    sigint_handler.sa_restorer  = 0;
    if (-1 == sigaction(SIGINT, &sigint_handler, 0))
    {
        std::cerr << "failed to install SIGINT handler" << std::endl;
        return 1;
    }
    sigset_t unblock_sigint;
    sigemptyset(&unblock_sigint);
    sigaddset(&unblock_sigint, SIGINT);
    if (-1 == sigprocmask(SIG_UNBLOCK, &unblock_sigint, NULL))
    {
        std::cerr << "failed to install SIGINT handler" << std::endl;
        return 1;
    }
    RTT::corba::TaskContextServer::ThreadOrb();
    while (true)
    {
        uint8_t dummy;
        int read_count = read(sigint_com[0], &dummy, 1);
        if (read_count == 1)
            break;
    }

    RTT::corba::TaskContextServer::ShutdownOrb();
    RTT::corba::TaskContextServer::DestroyOrb();
<% elsif deployer.browse %>
    OCL::TaskBrowser browser(& task_<%= deployer.browse.name %>);
    browser.loop();
<% end %>

    return 0;
}

<|endoftext|>


<commit_before><commit_msg>Make WidgetGtk::SetBounds use a single call if it can.<commit_after><|endoftext|>