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; }
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); } } }
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); }
/// 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); }
/// 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()); } }
/// 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; } } }
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()); } } } }
/// 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, 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[] = { 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.generateRef(), TemplateParams, UniqueIdentifier.empty() ? NULL : 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; }