Exemple #1
0
/// createVarinatType - Create variant type or return MainTy.
DIType DebugInfo::createVariantType(tree type, DIType MainTy) {
  
  DIType Ty;
  if (tree TyDef = TYPE_NAME(type)) {
      std::map<tree_node *, WeakVH >::iterator I = TypeCache.find(TyDef);
      if (I != TypeCache.end())
        if (Value *M = I->second)
          return DIType(cast<MDNode>(M));
    if (TREE_CODE(TyDef) == TYPE_DECL &&  DECL_ORIGINAL_TYPE(TyDef)) {
      expanded_location TypeDefLoc = GetNodeLocation(TyDef);
      Ty = DebugFactory.CreateDerivedType(DW_TAG_typedef, 
                                          findRegion(DECL_CONTEXT(TyDef)),
                                          GetNodeName(TyDef), 
                                          getOrCreateFile(TypeDefLoc.file),
                                          TypeDefLoc.line,
                                          0 /*size*/,
                                          0 /*align*/,
                                          0 /*offset */, 
                                          0 /*flags*/, 
                                          MainTy);
      TypeCache[TyDef] = WeakVH(Ty.getNode());
      return Ty;
    }
  }

  if (TYPE_VOLATILE(type)) {
    Ty = DebugFactory.CreateDerivedType(DW_TAG_volatile_type, 
                                        findRegion(TYPE_CONTEXT(type)), 
                                        StringRef(),
                                        getOrCreateFile(main_input_filename),
                                        0 /*line no*/, 
                                        NodeSizeInBits(type),
                                        NodeAlignInBits(type),
                                        0 /*offset */, 
                                        0 /* flags */, 
                                        MainTy);
    MainTy = Ty;
  }

  if (TYPE_READONLY(type)) 
    Ty =  DebugFactory.CreateDerivedType(DW_TAG_const_type, 
                                         findRegion(TYPE_CONTEXT(type)), 
                                         StringRef(),
                                         getOrCreateFile(main_input_filename),
                                         0 /*line no*/, 
                                         NodeSizeInBits(type),
                                         NodeAlignInBits(type),
                                         0 /*offset */, 
                                         0 /* flags */, 
                                         MainTy);
  
  if (TYPE_VOLATILE(type) || TYPE_READONLY(type)) {
    TypeCache[type] = WeakVH(Ty.getNode());
    return Ty;
  }

  // If, for some reason, main type varaint type is seen then use it.
  return MainTy;
}
Exemple #2
0
/// addType - Add type into Tys.
bool DebugInfoFinder::addType(DIType DT) {
  if (DT.isNull())
    return false;

  if (!NodesSeen.insert(DT.getNode()))
    return false;

  TYs.push_back(DT.getNode());
  return true;
}
Exemple #3
0
/// CreateGlobalVariable - Create a new descriptor for the specified global.
DIGlobalVariable
DIFactory::CreateGlobalVariable(DIDescriptor Context, const char * Name,
                                const char * DisplayName,
                                const char * LinkageName,
                                DICompileUnit CompileUnit,
                                unsigned LineNo, DIType Type,bool isLocalToUnit,
                                bool isDefinition, llvm::GlobalVariable *Val) {
  Value *Elts[] = {
    GetTagConstant(dwarf::DW_TAG_variable),
    llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)),
    Context.getNode(),
    MDString::get(VMContext, Name),
    MDString::get(VMContext, DisplayName),
    MDString::get(VMContext, LinkageName),
    CompileUnit.getNode(),
    ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
    Type.getNode(),
    ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit),
    ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition),
    Val
  };

  Value *const *Vs = &Elts[0];
  MDNode *Node = MDNode::get(VMContext,Vs, 12);

  // Create a named metadata so that we do not lose this mdnode.
  NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.gv");
  NMD->addElement(Node);

  return DIGlobalVariable(Node);
}
Exemple #4
0
/// CreateCompositeType - Create a composite type like array, struct, etc.
DICompositeType DIFactory::CreateCompositeTypeEx(unsigned Tag,
                                                 DIDescriptor Context,
                                                 const char * Name,
                                                 DICompileUnit CompileUnit,
                                                 unsigned LineNumber,
                                                 Constant *SizeInBits,
                                                 Constant *AlignInBits,
                                                 Constant *OffsetInBits,
                                                 unsigned Flags,
                                                 DIType DerivedFrom,
                                                 DIArray Elements,
                                                 unsigned RuntimeLang) {

  Value *Elts[] = {
    GetTagConstant(Tag),
    Context.getNode(),
    MDString::get(VMContext, Name),
    CompileUnit.getNode(),
    ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
    SizeInBits,
    AlignInBits,
    OffsetInBits,
    ConstantInt::get(Type::getInt32Ty(VMContext), Flags),
    DerivedFrom.getNode(),
    Elements.getNode(),
    ConstantInt::get(Type::getInt32Ty(VMContext), RuntimeLang)
  };
  return DICompositeType(MDNode::get(VMContext, &Elts[0], 12));
}
Exemple #5
0
/// EmitDeclare - Constructs the debug code for allocation of a new variable.
/// region - "llvm.dbg.declare."
void DebugInfo::EmitDeclare(tree decl, unsigned Tag, const char *Name,
                            tree type, Value *AI, LLVMBuilder &Builder) {

  // Ignore compiler generated temporaries.
  if (DECL_IGNORED_P(decl))
    return;

  assert(!RegionStack.empty() && "Region stack mismatch, stack empty!");

  expanded_location Loc = GetNodeLocation(decl, false);

  // Construct variable.
  DIScope VarScope = DIScope(cast<MDNode>(RegionStack.back()));
  DIType Ty = getOrCreateType(type);
  if (DECL_ARTIFICIAL (decl))
      Ty = DebugFactory.CreateArtificialType(Ty);
  // If type info is not available then do not emit debug info for this var.
  if (!Ty.getNode())
    return;
  llvm::DIVariable D =
    DebugFactory.CreateVariable(Tag, VarScope,
                                Name, getOrCreateFile(Loc.file),
                                Loc.line, Ty, optimize);

  // Insert an llvm.dbg.declare into the current block.
  Instruction *Call = DebugFactory.InsertDeclare(AI, D, 
                                                 Builder.GetInsertBlock());
  
  Call->setDebugLoc(DebugLoc::get(Loc.line, 0, VarScope.getNode()));
}
Exemple #6
0
/// CreateVariable - Create a new descriptor for the specified variable.
DIVariable DIFactory::CreateVariable(unsigned Tag, DIDescriptor Context,
                                     const char * Name,
                                     DICompileUnit CompileUnit, unsigned LineNo,
                                     DIType Type) {
  Value *Elts[] = {
    GetTagConstant(Tag),
    Context.getNode(),
    MDString::get(VMContext, Name),
    CompileUnit.getNode(),
    ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
    Type.getNode(),
  };
  return DIVariable(MDNode::get(VMContext, &Elts[0], 6));
}
Exemple #7
0
/// processType - Process DIType.
void DebugInfoFinder::processType(DIType DT) {
  if (!addType(DT))
    return;

  addCompileUnit(DT.getCompileUnit());
  if (DT.isCompositeType()) {
    DICompositeType DCT(DT.getNode());
    processType(DCT.getTypeDerivedFrom());
    DIArray DA = DCT.getTypeArray();
    if (!DA.isNull())
      for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) {
        DIDescriptor D = DA.getElement(i);
        DIType TypeE = DIType(D.getNode());
        if (!TypeE.isNull())
          processType(TypeE);
        else
          processSubprogram(DISubprogram(D.getNode()));
      }
  } else if (DT.isDerivedType()) {
    DIDerivedType DDT(DT.getNode());
    if (!DDT.isNull())
      processType(DDT.getTypeDerivedFrom());
  }
}
Exemple #8
0
/// CreateComplexVariable - Create a new descriptor for the specified variable
/// which has a complex address expression for its address.
DIVariable DIFactory::CreateComplexVariable(unsigned Tag, DIDescriptor Context,
                                            const std::string &Name,
                                            DICompileUnit CompileUnit,
                                            unsigned LineNo,
                                   DIType Type, SmallVector<Value *, 9> &addr) {
  SmallVector<Value *, 9> Elts;
  Elts.push_back(GetTagConstant(Tag));
  Elts.push_back(Context.getNode());
  Elts.push_back(MDString::get(VMContext, Name));
  Elts.push_back(CompileUnit.getNode());
  Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), LineNo));
  Elts.push_back(Type.getNode());
  Elts.insert(Elts.end(), addr.begin(), addr.end());

  return DIVariable(MDNode::get(VMContext, &Elts[0], 6+addr.size()));
}
Exemple #9
0
/// createPointerType - Create PointerType.
DIType DebugInfo::createPointerType(tree type) {

  DIType FromTy = getOrCreateType(TREE_TYPE(type));
  // type* and type&
  // FIXME: Should BLOCK_POINTER_TYP have its own DW_TAG?
  unsigned Tag = (TREE_CODE(type) == POINTER_TYPE ||
                  TREE_CODE(type) == BLOCK_POINTER_TYPE) ?
    DW_TAG_pointer_type :
    DW_TAG_reference_type;
  unsigned Flags = 0;
  if (type_is_block_byref_struct(type))
    Flags |= llvm::DIType::FlagBlockByrefStruct;

  // Check if this pointer type has a name.
  if (tree TyName = TYPE_NAME(type)) 
    if (TREE_CODE(TyName) == TYPE_DECL && !DECL_ORIGINAL_TYPE(TyName)) {
      expanded_location TypeNameLoc = GetNodeLocation(TyName);
      DIType Ty = 
        DebugFactory.CreateDerivedType(Tag, findRegion(DECL_CONTEXT(TyName)),
                                       GetNodeName(TyName), 
                                       getOrCreateFile(TypeNameLoc.file),
                                       TypeNameLoc.line,
                                       0 /*size*/,
                                       0 /*align*/,
                                       0 /*offset */, 
                                       0 /*flags*/, 
                                       FromTy);
      TypeCache[TyName] = WeakVH(Ty.getNode());
      return Ty;
    }
  
  StringRef PName = FromTy.getName();
  DIType PTy = 
    DebugFactory.CreateDerivedType(Tag, findRegion(TYPE_CONTEXT(type)),
                                   Tag == DW_TAG_pointer_type ? 
                                   StringRef() : PName,
                                   getOrCreateFile(main_input_filename),
                                   0 /*line no*/, 
                                   NodeSizeInBits(type),
                                   NodeAlignInBits(type),
                                   0 /*offset */, 
                                   Flags, 
                                   FromTy);
  return PTy;
}
Exemple #10
0
/// getOriginalTypeSize - If this type is derived from a base type then
/// return base type size.
uint64_t DIDerivedType::getOriginalTypeSize() const {
  unsigned Tag = getTag();
  if (Tag == dwarf::DW_TAG_member || Tag == dwarf::DW_TAG_typedef ||
      Tag == dwarf::DW_TAG_const_type || Tag == dwarf::DW_TAG_volatile_type ||
      Tag == dwarf::DW_TAG_restrict_type) {
    DIType BaseType = getTypeDerivedFrom();
    // If this type is not derived from any type then take conservative 
    // approach.
    if (BaseType.isNull())
      return getSizeInBits();
    if (BaseType.isDerivedType())
      return DIDerivedType(BaseType.getNode()).getOriginalTypeSize();
    else
      return BaseType.getSizeInBits();
  }
    
  return getSizeInBits();
}
/// PopulateDerivedTypeInfo - Populate TypeNo, Aux[], TagName for derived type 
/// from Ty. Derived types are mostly pointers.
///
void PIC16DbgInfo::PopulateDerivedTypeInfo (DIType Ty, unsigned short &TypeNo,
                                            bool &HasAux, int Aux[],
                                            std::string &TagName) {

  switch(Ty.getTag())
  {
    case dwarf::DW_TAG_pointer_type:
      TypeNo = TypeNo << PIC16Dbg::S_DERIVED;
      TypeNo = TypeNo | PIC16Dbg::DT_PTR;
      break;
    default:
      TypeNo = TypeNo << PIC16Dbg::S_DERIVED;
  }
  
  // We also need to encode the information about the base type of
  // pointer in TypeNo.
  DIType BaseType = DIDerivedType(Ty.getNode()).getTypeDerivedFrom();
  PopulateDebugInfo(BaseType, TypeNo, HasAux, Aux, TagName);
}
/// PopulateArrayTypeInfo - Populate TypeNo, Aux[] for array from Ty.
void PIC16DbgInfo::PopulateArrayTypeInfo (DIType Ty, unsigned short &TypeNo,
                                          bool &HasAux, int Aux[],
                                          std::string &TagName) {

  DICompositeType CTy = DICompositeType(Ty.getNode());
  DIArray Elements = CTy.getTypeArray();
  unsigned short size = 1;
  unsigned short Dimension[4]={0,0,0,0};
  for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
    DIDescriptor Element = Elements.getElement(i);
    if (Element.getTag() == dwarf::DW_TAG_subrange_type) {
      TypeNo = TypeNo << PIC16Dbg::S_DERIVED;
      TypeNo = TypeNo | PIC16Dbg::DT_ARY;
      DISubrange SubRange = DISubrange(Element.getNode());
      Dimension[i] = SubRange.getHi() - SubRange.getLo() + 1;
      // Each dimension is represented by 2 bytes starting at byte 9.
      Aux[8+i*2+0] = Dimension[i];
      Aux[8+i*2+1] = Dimension[i] >> 8;
      size = size * Dimension[i];
    }
  }
Exemple #13
0
/// CreateSubprogram - Create a new descriptor for the specified subprogram.
/// See comments in DISubprogram for descriptions of these fields.  This
/// method does not unique the generated descriptors.
DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context,
                                         const char * Name,
                                         const char * DisplayName,
                                         const char * LinkageName,
                                         DICompileUnit CompileUnit,
                                         unsigned LineNo, DIType Type,
                                         bool isLocalToUnit,
                                         bool isDefinition) {

  Value *Elts[] = {
    GetTagConstant(dwarf::DW_TAG_subprogram),
    llvm::Constant::getNullValue(Type::getInt32Ty(VMContext)),
    Context.getNode(),
    MDString::get(VMContext, Name),
    MDString::get(VMContext, DisplayName),
    MDString::get(VMContext, LinkageName),
    CompileUnit.getNode(),
    ConstantInt::get(Type::getInt32Ty(VMContext), LineNo),
    Type.getNode(),
    ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit),
    ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition)
  };
  return DISubprogram(MDNode::get(VMContext, &Elts[0], 11));
}
Exemple #14
0
/// CreateDerivedType - Create a derived type like const qualified type,
/// pointer, typedef, etc.
DIDerivedType DIFactory::CreateDerivedType(unsigned Tag,
                                           DIDescriptor Context,
                                           const char * Name,
                                           DICompileUnit CompileUnit,
                                           unsigned LineNumber,
                                           uint64_t SizeInBits,
                                           uint64_t AlignInBits,
                                           uint64_t OffsetInBits,
                                           unsigned Flags,
                                           DIType DerivedFrom) {
  Value *Elts[] = {
    GetTagConstant(Tag),
    Context.getNode(),
    MDString::get(VMContext, Name),
    CompileUnit.getNode(),
    ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber),
    ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits),
    ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits),
    ConstantInt::get(Type::getInt64Ty(VMContext), OffsetInBits),
    ConstantInt::get(Type::getInt32Ty(VMContext), Flags),
    DerivedFrom.getNode(),
  };
  return DIDerivedType(MDNode::get(VMContext, &Elts[0], 10));
}
Exemple #15
0
/// findRegion - Find the region (context) of a GCC tree.
DIDescriptor DebugInfo::findRegion(tree exp) {
  if (exp == NULL_TREE)
    return getOrCreateFile(main_input_filename);

  tree Node = exp;
  location_t *p_locus = 0;
  tree_code code = TREE_CODE(exp);
  enum tree_code_class tree_cc = TREE_CODE_CLASS(code);
  switch (tree_cc) {
  case tcc_declaration:  /* A decl node */
    p_locus = &DECL_SOURCE_LOCATION(exp);
    break;

  case tcc_expression:  /* an expression */
  case tcc_comparison:  /* a comparison expression */
  case tcc_unary:  /* a unary arithmetic expression */
  case tcc_binary:  /* a binary arithmetic expression */
    Node = TREE_BLOCK(exp);
    p_locus = EXPR_LOCUS(exp);
    break;

  case tcc_exceptional:
    switch (code) {
    case BLOCK:
      p_locus = &BLOCK_SOURCE_LOCATION(Node);
      break;
    default:
      gcc_unreachable ();
    }
    break;
  default:
    break;
  }

  std::map<tree_node *, WeakVH>::iterator I = RegionMap.find(Node);
  if (I != RegionMap.end())
    if (MDNode *R = dyn_cast_or_null<MDNode>(I->second))
      return DIDescriptor(R);

  if (TYPE_P (Node)) {
    DIType Ty = getOrCreateType(Node);
    return DIDescriptor(Ty.getNode());
  } else if (DECL_P (Node)) {
    switch (TREE_CODE(Node)) {
    default:
      /// What kind of DECL is this?
      return findRegion (DECL_CONTEXT (Node));
    case NAMESPACE_DECL: {
      DIDescriptor NSContext = findRegion(DECL_CONTEXT(Node));
      DINameSpace NS = getOrCreateNameSpace(Node, NSContext);
      return DIDescriptor(NS.getNode());
    }
    case FUNCTION_DECL: {
      DISubprogram SP = CreateSubprogramFromFnDecl(Node);
      return SP;
    }
    }
  } else if (TREE_CODE(Node) == BLOCK) {
    // Recursively establish ancestor scopes.
    DIDescriptor context = findRegion(BLOCK_SUPERCONTEXT(Node));
    // If we don't have a location, use the last-seen info.
    unsigned int line;
    const char *fullpath;
    if (LOCATION_FILE(*p_locus) == (char*)0) {
      fullpath = CurFullPath;
      line = CurLineNo;
    } else {
      fullpath = LOCATION_FILE(*p_locus);
      line = LOCATION_LINE(*p_locus);
    }
    DIFile F(getOrCreateFile(fullpath));
    DILexicalBlock lexical_block = 
      DebugFactory.CreateLexicalBlock(context, F, line, 0U);
    RegionMap[Node] = WeakVH(lexical_block.getNode());
    return DIDescriptor(lexical_block);
  }

  // Otherwise main compile unit covers everything.
  return getOrCreateFile(main_input_filename);
}
Exemple #16
0
/// getOrCreateType - Get the type from the cache or create a new type if
/// necessary.
DIType DebugInfo::getOrCreateType(tree type) {
  DEBUGASSERT(type != NULL_TREE && type != error_mark_node &&
              "Not a type.");
  if (type == NULL_TREE || type == error_mark_node) return DIType();

  // Should only be void if a pointer/reference/return type.  Returning NULL
  // allows the caller to produce a non-derived type.
  if (TREE_CODE(type) == VOID_TYPE) return DIType();
  
  // Check to see if the compile unit already has created this type.
  std::map<tree_node *, WeakVH >::iterator I = TypeCache.find(type);
  if (I != TypeCache.end())
    if (Value *M = I->second)
      return DIType(cast<MDNode>(M));

  DIType MainTy;
  if (type != TYPE_MAIN_VARIANT(type) && TYPE_MAIN_VARIANT(type))
    MainTy = getOrCreateType(TYPE_MAIN_VARIANT(type));

  DIType Ty = createVariantType(type, MainTy);
  if (Ty.isValid())
    return Ty;

  // Work out details of type.
  switch (TREE_CODE(type)) {
    case ERROR_MARK:
    case LANG_TYPE:
    case TRANSLATION_UNIT_DECL:
    default: {
      DEBUGASSERT(0 && "Unsupported type");
      return DIType();
    }
    
    case POINTER_TYPE:
    case REFERENCE_TYPE:
      // Do not cache pointer type. The pointer may point to forward declared
      // struct.
      return createPointerType(type);
      break;

    case BLOCK_POINTER_TYPE: {
      DEBUGASSERT (generic_block_literal_struct_type && 
                   "Generic struct type for Blocks is missing!");
      tree tmp_type = build_pointer_type(generic_block_literal_struct_type);
      Ty = createPointerType(tmp_type);
      break;
    }

    case OFFSET_TYPE: {
      // gen_type_die(TYPE_OFFSET_BASETYPE(type), context_die);
      // gen_type_die(TREE_TYPE(type), context_die);
      // gen_ptr_to_mbr_type_die(type, context_die);
      // PR 7104
      break;
    }

    case FUNCTION_TYPE:
    case METHOD_TYPE: 
      Ty = createMethodType(type);
      break;
      
    case VECTOR_TYPE:
    case ARRAY_TYPE: 
      Ty = createArrayType(type);
      break;
    
    case ENUMERAL_TYPE: 
      Ty = createEnumType(type);
      break;
    
    case RECORD_TYPE:
    case QUAL_UNION_TYPE:
    case UNION_TYPE: 
      return createStructType(type);
      break;

    case INTEGER_TYPE:
    case REAL_TYPE:   
    case COMPLEX_TYPE:
    case BOOLEAN_TYPE:
      Ty = createBasicType(type);
      break;
  }
  TypeCache[type] = WeakVH(Ty.getNode());
  return Ty;
}