DICompositeType DIBuilder::createClassType(DIDescriptor Context, StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, DIType DerivedFrom, DIArray Elements, DIType VTableHolder, MDNode *TemplateParams, StringRef UniqueIdentifier) { assert((!Context || Context.isScope() || Context.isType()) && "createClassType should be called with a valid Context"); // TAG_class_type is encoded in DICompositeType format. Value *Elts[] = { HeaderBuilder::get(dwarf::DW_TAG_class_type) .concat(Name) .concat(LineNumber) .concat(SizeInBits) .concat(AlignInBits) .concat(OffsetInBits) .concat(Flags) .concat(0) .get(VMContext), File.getFileNode(), DIScope(getNonCompileUnitScope(Context)).getRef(), DerivedFrom.getRef(), Elements, VTableHolder.getRef(), TemplateParams, UniqueIdentifier.empty() ? nullptr : MDString::get(VMContext, UniqueIdentifier)}; DICompositeType R(MDNode::get(VMContext, Elts)); assert(R.isCompositeType() && "createClassType should return a DICompositeType"); if (!UniqueIdentifier.empty()) retainType(R); return R; }
/// constructArrayTypeDIE - Construct array type DIE from DICompositeType. void CompileUnit::constructArrayTypeDIE(DIE &Buffer, DICompositeType *CTy) { Buffer.setTag(dwarf::DW_TAG_array_type); if (CTy->getTag() == dwarf::DW_TAG_vector_type) addUInt(&Buffer, dwarf::DW_AT_GNU_vector, dwarf::DW_FORM_flag, 1); // Emit derived type. addType(&Buffer, CTy->getTypeDerivedFrom()); DIArray Elements = CTy->getTypeArray(); // Get an anonymous type for index type. DIE *IdxTy = getIndexTyDie(); if (!IdxTy) { // Construct an anonymous type for index type. IdxTy = new DIE(dwarf::DW_TAG_base_type); addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t)); addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1, dwarf::DW_ATE_signed); addDie(IdxTy); setIndexTyDie(IdxTy); } // Add subranges to array type. for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) { DIDescriptor Element = Elements.getElement(i); if (Element.getTag() == dwarf::DW_TAG_subrange_type) constructSubrangeDIE(Buffer, DISubrange(Element), IdxTy); } }
/// addGlobalType - Add a new global type to the compile unit. /// void CompileUnit::addGlobalType(DIType Ty) { DIDescriptor Context = Ty.getContext(); if (Ty.isCompositeType() && !Ty.getName().empty() && !Ty.isForwardDecl() && (Context.isCompileUnit() || Context.isFile() || Context.isNameSpace())) if (DIEEntry *Entry = getDIEEntry(Ty)) GlobalTypes[Ty.getName()] = Entry->getEntry(); }
void DebugInfoFinder::processType(DIType DT) { if (!addType(DT)) return; processScope(DT.getContext().resolve(TypeIdentifierMap)); if (DT.isCompositeType()) { DICompositeType DCT(DT); processType(DCT.getTypeDerivedFrom().resolve(TypeIdentifierMap)); if (DT.isSubroutineType()) { DITypeArray DTA = DISubroutineType(DT).getTypeArray(); for (unsigned i = 0, e = DTA.getNumElements(); i != e; ++i) processType(DTA.getElement(i).resolve(TypeIdentifierMap)); return; } DIArray DA = DCT.getElements(); for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) { DIDescriptor D = DA.getElement(i); if (D.isType()) processType(DIType(D)); else if (D.isSubprogram()) processSubprogram(DISubprogram(D)); } } else if (DT.isDerivedType()) { DIDerivedType DDT(DT); processType(DDT.getTypeDerivedFrom().resolve(TypeIdentifierMap)); } }
void DebugDatabase::addType(MDNode *type) { DIType diType(type); string query; query = "INSERT INTO VariableType "; query += "(designId, dw_tag, name, size, alignment, offset, derivedTypeId) "; query += "VALUES (" + std::to_string(designId); query += "," + std::to_string(diType.getTag()); query += "," + addQuotesToStr(diType.getName().str()); query += "," + std::to_string(diType.getSizeInBits()); query += "," + std::to_string(diType.getAlignInBits()); query += "," + std::to_string(diType.getOffsetInBits()); if (diType.isBasicType()) { query += ",NULL"; } else if (diType.isDerivedType()) { DIDerivedType typeDerived(type); MDNode *derivedMD = typeDerived.getTypeDerivedFrom().resolve(typeMap); if (derivedMD) query += "," + std::to_string(getTypeId(derivedMD)); else query += ",NULL"; } else { assert(false); } query += ");"; runQuery(query); int typeId = mysql_insert_id(connection); typeToIds[&(*type)] = typeId; if (diType.isCompositeType()) { DICompositeType typeComposite(type); DIArray members = typeComposite.getTypeArray(); for (unsigned int i = 0; i < members.getNumElements(); ++i) { DIDescriptor s = members.getElement(i); query = "INSERT INTO VariableTypeMember "; query += "(ownerVariableTypeId, idx, variableTypeId, subrangeCount) "; query += "VALUES (" + std::to_string(typeId); query += "," + std::to_string(i); if (s.isSubrange()) { DISubrange subRange = (DISubrange)s; assert(subRange.getLo() == 0); query += ",NULL"; query += "," + std::to_string(subRange.getCount()); } else if (s.isType()) { MDNode *mdNode = &*s; query += "," + std::to_string(getTypeId(mdNode)); query += ",NULL"; } query += ");"; runQuery(query); } } }
/// addTemplateParams - Add template parameters in buffer. void CompileUnit::addTemplateParams(DIE &Buffer, DIArray TParams) { // Add template parameters. for (unsigned i = 0, e = TParams.getNumElements(); i != e; ++i) { DIDescriptor Element = TParams.getElement(i); if (Element.isTemplateTypeParameter()) Buffer.addChild(getOrCreateTemplateTypeParameterDIE( DITemplateTypeParameter(Element))); else if (Element.isTemplateValueParameter()) Buffer.addChild(getOrCreateTemplateValueParameterDIE( DITemplateValueParameter(Element))); } }
/// addToContextOwner - Add Die into the list of its context owner's children. void CompileUnit::addToContextOwner(DIE *Die, DIDescriptor Context) { if (Context.isType()) { DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context)); ContextDIE->addChild(Die); } else if (Context.isNameSpace()) { DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context)); ContextDIE->addChild(Die); } else if (Context.isSubprogram()) { DIE *ContextDIE = DD->createSubprogramDIE(DISubprogram(Context)); ContextDIE->addChild(Die); } else if (DIE *ContextDIE = getDIE(Context)) ContextDIE->addChild(Die); else addDie(Die); }
/// 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)); }
/// 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); }
/// CreateBlock - This creates a descriptor for a lexical block with the /// specified parent VMContext. DILexicalBlock DIFactory::CreateLexicalBlock(DIDescriptor Context) { Value *Elts[] = { GetTagConstant(dwarf::DW_TAG_lexical_block), Context.getNode() }; return DILexicalBlock(MDNode::get(VMContext, &Elts[0], 2)); }
/// findLexicalScope - Find lexical scope, either regular or inlined, for the /// given DebugLoc. Return NULL if not found. LexicalScope *LexicalScopes::findLexicalScope(DebugLoc DL) { MDNode *Scope = NULL; MDNode *IA = NULL; DL.getScopeAndInlinedAt(Scope, IA, MF->getFunction()->getContext()); if (!Scope) return NULL; // The scope that we were created with could have an extra file - which // isn't what we care about in this case. DIDescriptor D = DIDescriptor(Scope); if (D.isLexicalBlockFile()) Scope = DILexicalBlockFile(Scope).getScope(); if (IA) return InlinedLexicalScopeMap.lookup(DebugLoc::getFromDILocation(IA)); return LexicalScopeMap.lookup(Scope); }
/// createClassType - Create debugging information entry for a class. DICompositeType DIBuilder::createClassType(DIDescriptor Context, StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, DIType DerivedFrom, DIArray Elements, MDNode *VTableHolder, MDNode *TemplateParams) { assert((!Context || Context.Verify()) && "createClassType should be called with a valid Context"); // TAG_class_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_class_type), File.getFileNode(), getNonCompileUnitScope(Context), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), ConstantInt::get(Type::getInt32Ty(VMContext), OffsetInBits), ConstantInt::get(Type::getInt32Ty(VMContext), Flags), DerivedFrom, Elements, ConstantInt::get(Type::getInt32Ty(VMContext), 0), VTableHolder, TemplateParams }; DICompositeType R(MDNode::get(VMContext, Elts)); assert(R.Verify() && "createClassType should return a verifiable DIType"); return R; }
void DebugInfoFinder::processSubprogram(DISubprogram SP) { if (!addSubprogram(SP)) return; processScope(SP.getContext().resolve(TypeIdentifierMap)); processType(SP.getType()); DIArray TParams = SP.getTemplateParams(); for (unsigned I = 0, E = TParams.getNumElements(); I != E; ++I) { DIDescriptor Element = TParams.getElement(I); if (Element.isTemplateTypeParameter()) { DITemplateTypeParameter TType(Element); processType(TType.getType().resolve(TypeIdentifierMap)); } else if (Element.isTemplateValueParameter()) { DITemplateValueParameter TVal(Element); processType(TVal.getType().resolve(TypeIdentifierMap)); } } }
/// replaceAllUsesWith - Replace all uses of debug info referenced by /// this descriptor. After this completes, the current debug info value /// is erased. void DIDerivedType::replaceAllUsesWith(DIDescriptor &D) { if (isNull()) return; assert (!D.isNull() && "Can not replace with null"); // Since we use a TrackingVH for the node, its easy for clients to manufacture // legitimate situations where they want to replaceAllUsesWith() on something // which, due to uniquing, has merged with the source. We shield clients from // this detail by allowing a value to be replaced with replaceAllUsesWith() // itself. if (getNode() != D.getNode()) { MDNode *Node = DbgNode; Node->replaceAllUsesWith(D.getNode()); delete Node; } }
void DIDescriptor::replaceAllUsesWith(LLVMContext &, DIDescriptor D) { assert(DbgNode && "Trying to replace an unverified type!"); assert(DbgNode->isTemporary() && "Expected temporary node"); TempMDNode Temp(get()); // Since we use a TrackingVH for the node, its easy for clients to manufacture // legitimate situations where they want to replaceAllUsesWith() on something // which, due to uniquing, has merged with the source. We shield clients from // this detail by allowing a value to be replaced with replaceAllUsesWith() // itself. if (Temp.get() == D.get()) { DbgNode = MDNode::replaceWithUniqued(std::move(Temp)); return; } Temp->replaceAllUsesWith(D.get()); DbgNode = D.get(); }
DIImportedEntity DIBuilder::createImportedDeclaration(DIScope Context, DIDescriptor Decl, unsigned Line, StringRef Name) { // Make sure to use the unique identifier based metadata reference for // types that have one. Value *V = Decl.isType() ? static_cast<Value*>(DIType(Decl).getRef()) : Decl; return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_declaration, Context, V, Line, Name, AllImportedModules); }
/// processType - Process DIType. void DebugInfoFinder::processType(DIType DT) { if (!addType(DT)) return; if (DT.isCompositeType()) { DICompositeType DCT(DT); processType(DCT.getTypeDerivedFrom()); DIArray DA = DCT.getTypeArray(); for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) { DIDescriptor D = DA.getElement(i); if (D.isType()) processType(DIType(D)); else if (D.isSubprogram()) processSubprogram(DISubprogram(D)); } } else if (DT.isDerivedType()) { DIDerivedType DDT(DT); processType(DDT.getTypeDerivedFrom()); } }
/// 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.getGV()); 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.getGV()); 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]; } }
/// processModule - Process entire module and collect debug info. void DebugInfoFinder::processModule(const Module &M) { if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) { TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes); for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { DICompileUnit CU(CU_Nodes->getOperand(i)); addCompileUnit(CU); DIArray GVs = CU.getGlobalVariables(); for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i) { DIGlobalVariable DIG(GVs.getElement(i)); if (addGlobalVariable(DIG)) { processScope(DIG.getContext()); processType(DIG.getType()); } } DIArray SPs = CU.getSubprograms(); for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) processSubprogram(DISubprogram(SPs.getElement(i))); DIArray EnumTypes = CU.getEnumTypes(); for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i) processType(DIType(EnumTypes.getElement(i))); DIArray RetainedTypes = CU.getRetainedTypes(); for (unsigned i = 0, e = RetainedTypes.getNumElements(); i != e; ++i) processType(DIType(RetainedTypes.getElement(i))); DIArray Imports = CU.getImportedEntities(); for (unsigned i = 0, e = Imports.getNumElements(); i != e; ++i) { DIImportedEntity Import = DIImportedEntity( Imports.getElement(i)); DIDescriptor Entity = Import.getEntity(); if (Entity.isType()) processType(DIType(Entity)); else if (Entity.isSubprogram()) processSubprogram(DISubprogram(Entity)); else if (Entity.isNameSpace()) processScope(DINameSpace(Entity).getContext()); } // FIXME: We really shouldn't be bailing out after visiting just one CU return; } } }
/// getOrCreateRegularScope - Find or create a regular lexical scope. LexicalScope *LexicalScopes::getOrCreateRegularScope(MDNode *Scope) { DIDescriptor D = DIDescriptor(Scope); if (D.isLexicalBlockFile()) { Scope = DILexicalBlockFile(Scope).getScope(); D = DIDescriptor(Scope); } LexicalScope *WScope = LexicalScopeMap.lookup(Scope); if (WScope) return WScope; LexicalScope *Parent = NULL; if (D.isLexicalBlock()) Parent = getOrCreateLexicalScope(DebugLoc::getFromDILexicalBlock(Scope)); WScope = new LexicalScope(Parent, DIDescriptor(Scope), NULL, false); LexicalScopeMap.insert(std::make_pair(Scope, WScope)); if (!Parent && DIDescriptor(Scope).isSubprogram() && DISubprogram(Scope).describes(MF->getFunction())) CurrentFnLexicalScope = WScope; return WScope; }
void DebugInfoFinder::processModule(const Module &M) { InitializeTypeMap(M); if (NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu")) { for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { DICompileUnit CU(CU_Nodes->getOperand(i)); addCompileUnit(CU); DIArray GVs = CU.getGlobalVariables(); for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i) { DIGlobalVariable DIG(GVs.getElement(i)); if (addGlobalVariable(DIG)) { processScope(DIG.getContext()); processType(DIG.getType().resolve(TypeIdentifierMap)); } } DIArray SPs = CU.getSubprograms(); for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) processSubprogram(DISubprogram(SPs.getElement(i))); DIArray EnumTypes = CU.getEnumTypes(); for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i) processType(DIType(EnumTypes.getElement(i))); DIArray RetainedTypes = CU.getRetainedTypes(); for (unsigned i = 0, e = RetainedTypes.getNumElements(); i != e; ++i) processType(DIType(RetainedTypes.getElement(i))); DIArray Imports = CU.getImportedEntities(); for (unsigned i = 0, e = Imports.getNumElements(); i != e; ++i) { DIImportedEntity Import = DIImportedEntity(Imports.getElement(i)); if (!Import) continue; DIDescriptor Entity = Import.getEntity().resolve(TypeIdentifierMap); if (Entity.isType()) processType(DIType(Entity)); else if (Entity.isSubprogram()) processSubprogram(DISubprogram(Entity)); else if (Entity.isNameSpace()) processScope(DINameSpace(Entity).getContext()); } } } }
/// 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)); }
/// 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()); } }
/// 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())); }
/// CreateBasicType - Create a basic type like int, float, etc. DIBasicType DIFactory::CreateBasicTypeEx(DIDescriptor Context, const char * Name, DICompileUnit CompileUnit, unsigned LineNumber, Constant *SizeInBits, Constant *AlignInBits, Constant *OffsetInBits, unsigned Flags, unsigned Encoding) { Value *Elts[] = { GetTagConstant(dwarf::DW_TAG_base_type), Context.getNode(), MDString::get(VMContext, Name), CompileUnit.getNode(), ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), SizeInBits, AlignInBits, OffsetInBits, ConstantInt::get(Type::getInt32Ty(VMContext), Flags), ConstantInt::get(Type::getInt32Ty(VMContext), Encoding) }; return DIBasicType(MDNode::get(VMContext, &Elts[0], 10)); }
/// 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)); }
/// 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)); }
/// constructTypeDIE - Construct type DIE from DICompositeType. void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) { // Get core information. StringRef Name = CTy.getName(); uint64_t Size = CTy.getSizeInBits() >> 3; unsigned Tag = CTy.getTag(); Buffer.setTag(Tag); switch (Tag) { case dwarf::DW_TAG_vector_type: case dwarf::DW_TAG_array_type: constructArrayTypeDIE(Buffer, &CTy); break; case dwarf::DW_TAG_enumeration_type: { DIArray Elements = CTy.getTypeArray(); // Add enumerators to enumeration type. for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) { DIE *ElemDie = NULL; DIDescriptor Enum(Elements.getElement(i)); if (Enum.isEnumerator()) { ElemDie = constructEnumTypeDIE(DIEnumerator(Enum)); Buffer.addChild(ElemDie); } } } break; case dwarf::DW_TAG_subroutine_type: { // Add return type. DIArray Elements = CTy.getTypeArray(); DIDescriptor RTy = Elements.getElement(0); addType(&Buffer, DIType(RTy)); bool isPrototyped = true; // Add arguments. for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) { DIDescriptor Ty = Elements.getElement(i); if (Ty.isUnspecifiedParameter()) { DIE *Arg = new DIE(dwarf::DW_TAG_unspecified_parameters); Buffer.addChild(Arg); isPrototyped = false; } else { DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter); addType(Arg, DIType(Ty)); Buffer.addChild(Arg); } } // Add prototype flag. if (isPrototyped) addUInt(&Buffer, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1); } break; case dwarf::DW_TAG_structure_type: case dwarf::DW_TAG_union_type: case dwarf::DW_TAG_class_type: { // Add elements to structure type. DIArray Elements = CTy.getTypeArray(); // A forward struct declared type may not have elements available. unsigned N = Elements.getNumElements(); if (N == 0) break; // Add elements to structure type. for (unsigned i = 0; i < N; ++i) { DIDescriptor Element = Elements.getElement(i); DIE *ElemDie = NULL; if (Element.isSubprogram()) { DISubprogram SP(Element); ElemDie = DD->createSubprogramDIE(DISubprogram(Element)); if (SP.isProtected()) addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag, dwarf::DW_ACCESS_protected); else if (SP.isPrivate()) addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag, dwarf::DW_ACCESS_private); else addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag, dwarf::DW_ACCESS_public); if (SP.isExplicit()) addUInt(ElemDie, dwarf::DW_AT_explicit, dwarf::DW_FORM_flag, 1); } else if (Element.isVariable()) { DIVariable DV(Element); ElemDie = new DIE(dwarf::DW_TAG_variable); addString(ElemDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, DV.getName()); addType(ElemDie, DV.getType()); addUInt(ElemDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); addUInt(ElemDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1); addSourceLine(ElemDie, DV); } else if (Element.isDerivedType()) ElemDie = createMemberDIE(DIDerivedType(Element)); else continue; Buffer.addChild(ElemDie); } if (CTy.isAppleBlockExtension()) addUInt(&Buffer, dwarf::DW_AT_APPLE_block, dwarf::DW_FORM_flag, 1); unsigned RLang = CTy.getRunTimeLang(); if (RLang) addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class, dwarf::DW_FORM_data1, RLang); DICompositeType ContainingType = CTy.getContainingType(); if (DIDescriptor(ContainingType).isCompositeType()) addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, getOrCreateTypeDIE(DIType(ContainingType))); else { DIDescriptor Context = CTy.getContext(); addToContextOwner(&Buffer, Context); } if (CTy.isObjcClassComplete()) addUInt(&Buffer, dwarf::DW_AT_APPLE_objc_complete_type, dwarf::DW_FORM_flag, 1); if (Tag == dwarf::DW_TAG_class_type) addTemplateParams(Buffer, CTy.getTemplateParams()); break; } default: break; } // Add name if not anonymous or intermediate type. if (!Name.empty()) addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); if (Tag == dwarf::DW_TAG_enumeration_type || Tag == dwarf::DW_TAG_class_type || Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type) { // Add size if non-zero (derived types might be zero-sized.) if (Size) addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size); else { // Add zero size if it is not a forward declaration. if (CTy.isForwardDecl()) addUInt(&Buffer, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); else addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, 0); } // Add source line info if available. if (!CTy.isForwardDecl()) addSourceLine(&Buffer, CTy); } }