/// createForwardDecl - Create a temporary forward-declared type that /// can be RAUW'd if the full type is seen. DICompositeType DIBuilder::createForwardDecl(unsigned Tag, StringRef Name, DIDescriptor Scope, DIFile F, unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits, uint64_t AlignInBits, StringRef UniqueIdentifier) { // Create a temporary MDNode. Value *Elts[] = { GetTagConstant(VMContext, Tag), F.getFileNode(), getNonCompileUnitScope(Scope), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), Line), ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), ConstantInt::get(Type::getInt32Ty(VMContext), 0), ConstantInt::get(Type::getInt32Ty(VMContext), DIDescriptor::FlagFwdDecl), NULL, DIArray(), ConstantInt::get(Type::getInt32Ty(VMContext), RuntimeLang), NULL, NULL, //TemplateParams UniqueIdentifier.empty() ? NULL : MDString::get(VMContext, UniqueIdentifier) }; MDNode *Node = MDNode::getTemporary(VMContext, Elts); DICompositeType RetTy(Node); assert(RetTy.isCompositeType() && "createForwardDecl result should be a DIType"); if (!UniqueIdentifier.empty()) retainType(RetTy); return RetTy; }
/// createEnumerationType - Create debugging information entry for an /// enumeration. DICompositeType DIBuilder::createEnumerationType( DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, DIArray Elements, DIType UnderlyingType, StringRef UniqueIdentifier) { // TAG_enumeration_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_enumeration_type), File.getFileNode(), getNonCompileUnitScope(Scope), 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), 0), ConstantInt::get(Type::getInt32Ty(VMContext), 0), UnderlyingType, Elements, ConstantInt::get(Type::getInt32Ty(VMContext), 0), NULL, NULL, UniqueIdentifier.empty() ? NULL : MDString::get(VMContext, UniqueIdentifier) }; MDNode *Node = MDNode::get(VMContext, Elts); AllEnumTypes.push_back(Node); if (!UniqueIdentifier.empty()) retainType(Node); return DICompositeType(Node); }
/// createForwardDecl - Create a temporary forward-declared type that /// can be RAUW'd if the full type is seen. DIType DIBuilder::createForwardDecl(unsigned Tag, StringRef Name, DIDescriptor Scope, DIFile F, unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits, uint64_t AlignInBits) { // Create a temporary MDNode. Value *Elts[] = { GetTagConstant(VMContext, Tag), F.getFileNode(), getNonCompileUnitScope(Scope), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), Line), ConstantInt::get(Type::getInt64Ty(VMContext), SizeInBits), ConstantInt::get(Type::getInt64Ty(VMContext), AlignInBits), ConstantInt::get(Type::getInt32Ty(VMContext), 0), ConstantInt::get(Type::getInt32Ty(VMContext), DIDescriptor::FlagFwdDecl), NULL, DIArray(), ConstantInt::get(Type::getInt32Ty(VMContext), RuntimeLang) }; MDNode *Node = MDNode::getTemporary(VMContext, Elts); assert(DIType(Node).Verify() && "createForwardDecl result should be verifiable"); return DIType(Node); }
DICompositeType DIBuilder::createReplaceableForwardDecl( unsigned Tag, StringRef Name, DIDescriptor Scope, DIFile F, unsigned Line, unsigned RuntimeLang, uint64_t SizeInBits, uint64_t AlignInBits, StringRef UniqueIdentifier) { // Create a temporary MDNode. Value *Elts[] = { HeaderBuilder::get(Tag) .concat(Name) .concat(Line) .concat(SizeInBits) .concat(AlignInBits) .concat(0) // Offset .concat(DIDescriptor::FlagFwdDecl) .concat(RuntimeLang) .get(VMContext), F.getFileNode(), DIScope(getNonCompileUnitScope(Scope)).getRef(), nullptr, DIArray(), nullptr, nullptr, // TemplateParams UniqueIdentifier.empty() ? nullptr : MDString::get(VMContext, UniqueIdentifier)}; MDNode *Node = MDNode::getTemporary(VMContext, Elts); DICompositeType RetTy(Node); assert(RetTy.isCompositeType() && "createReplaceableForwardDecl result should be a DIType"); if (!UniqueIdentifier.empty()) retainType(RetTy); return RetTy; }
/// createUnionType - Create debugging information entry for an union. DICompositeType DIBuilder::createUnionType(DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags, DIArray Elements, unsigned RunTimeLang) { // TAG_union_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_union_type), File.getFileNode(), getNonCompileUnitScope(Scope), 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::getInt64Ty(VMContext), 0), ConstantInt::get(Type::getInt32Ty(VMContext), Flags), NULL, Elements, ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeLang), Constant::getNullValue(Type::getInt32Ty(VMContext)), NULL }; return DICompositeType(MDNode::get(VMContext, Elts)); }
static DISubprogram createFunctionHelper(LLVMContext &VMContext, DIDescriptor Context, StringRef Name, StringRef LinkageName, DIFile File, unsigned LineNo, DICompositeType Ty, bool isLocalToUnit, bool isDefinition, unsigned ScopeLine, unsigned Flags, bool isOptimized, Function *Fn, MDNode *TParams, MDNode *Decl, MDNode *Vars, std::function<MDNode *(ArrayRef<Value *>)> CreateFunc) { assert(Ty.getTag() == dwarf::DW_TAG_subroutine_type && "function types should be subroutines"); Value *Elts[] = { HeaderBuilder::get(dwarf::DW_TAG_subprogram) .concat(Name) .concat(Name) .concat(LinkageName) .concat(LineNo) .concat(isLocalToUnit) .concat(isDefinition) .concat(0) .concat(0) .concat(Flags) .concat(isOptimized) .concat(ScopeLine) .get(VMContext), File.getFileNode(), DIScope(getNonCompileUnitScope(Context)).getRef(), Ty, nullptr, Fn, TParams, Decl, Vars}; DISubprogram S(CreateFunc(Elts)); assert(S.isSubprogram() && "createFunction should return a valid DISubprogram"); return S; }
/// 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; }
/// createStructType - Create debugging information entry for a struct. DICompositeType DIBuilder::createStructType(DIDescriptor Context, StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags, DIType DerivedFrom, DIArray Elements, unsigned RunTimeLang, MDNode *VTableHolder) { // TAG_structure_type is encoded in DICompositeType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_structure_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), 0), ConstantInt::get(Type::getInt32Ty(VMContext), Flags), DerivedFrom, Elements, ConstantInt::get(Type::getInt32Ty(VMContext), RunTimeLang), VTableHolder, NULL, }; DICompositeType R(MDNode::get(VMContext, Elts)); assert(R.Verify() && "createStructType should return a verifiable DIType"); return R; }
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; }
/// createObjCIVar - Create debugging information entry for Objective-C /// instance variable. DIType DIBuilder::createObjCIVar(StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, DIType Ty, StringRef PropertyName, StringRef GetterName, StringRef SetterName, unsigned PropertyAttributes) { // TAG_member is encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_member), File.getFileNode(), getNonCompileUnitScope(File), 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::getInt64Ty(VMContext), OffsetInBits), ConstantInt::get(Type::getInt32Ty(VMContext), Flags), Ty, MDString::get(VMContext, PropertyName), MDString::get(VMContext, GetterName), MDString::get(VMContext, SetterName), ConstantInt::get(Type::getInt32Ty(VMContext), PropertyAttributes) }; return DIType(MDNode::get(VMContext, Elts)); }
DICompositeType DIBuilder::createStructType(DIDescriptor Context, StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags, DIType DerivedFrom, DIArray Elements, unsigned RunTimeLang, DIType VTableHolder, StringRef UniqueIdentifier) { // TAG_structure_type is encoded in DICompositeType format. Value *Elts[] = { HeaderBuilder::get(dwarf::DW_TAG_structure_type) .concat(Name) .concat(LineNumber) .concat(SizeInBits) .concat(AlignInBits) .concat(0) .concat(Flags) .concat(RunTimeLang) .get(VMContext), File.getFileNode(), DIScope(getNonCompileUnitScope(Context)).getRef(), DerivedFrom.getRef(), Elements, VTableHolder.getRef(), nullptr, UniqueIdentifier.empty() ? nullptr : MDString::get(VMContext, UniqueIdentifier)}; DICompositeType R(MDNode::get(VMContext, Elts)); assert(R.isCompositeType() && "createStructType should return a DICompositeType"); if (!UniqueIdentifier.empty()) retainType(R); return R; }
DICompositeType DIBuilder::createUnionType(DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, unsigned Flags, DIArray Elements, unsigned RunTimeLang, StringRef UniqueIdentifier) { // TAG_union_type is encoded in DICompositeType format. Value *Elts[] = { HeaderBuilder::get(dwarf::DW_TAG_union_type) .concat(Name) .concat(LineNumber) .concat(SizeInBits) .concat(AlignInBits) .concat(0) // Offset .concat(Flags) .concat(RunTimeLang) .get(VMContext), File.getFileNode(), DIScope(getNonCompileUnitScope(Scope)).getRef(), nullptr, Elements, nullptr, nullptr, UniqueIdentifier.empty() ? nullptr : MDString::get(VMContext, UniqueIdentifier)}; DICompositeType R(MDNode::get(VMContext, Elts)); if (!UniqueIdentifier.empty()) retainType(R); return R; }
DICompositeType DIBuilder::createEnumerationType( DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, DIArray Elements, DIType UnderlyingType, StringRef UniqueIdentifier) { // TAG_enumeration_type is encoded in DICompositeType format. Value *Elts[] = { HeaderBuilder::get(dwarf::DW_TAG_enumeration_type) .concat(Name) .concat(LineNumber) .concat(SizeInBits) .concat(AlignInBits) .concat(0) // Offset .concat(0) // Flags .concat(0) .get(VMContext), File.getFileNode(), DIScope(getNonCompileUnitScope(Scope)).getRef(), UnderlyingType.getRef(), Elements, nullptr, nullptr, UniqueIdentifier.empty() ? nullptr : MDString::get(VMContext, UniqueIdentifier)}; DICompositeType CTy(MDNode::get(VMContext, Elts)); AllEnumTypes.push_back(CTy); if (!UniqueIdentifier.empty()) retainType(CTy); return CTy; }
DINameSpace DIBuilder::createNameSpace(DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNo) { Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_namespace) .concat(Name) .concat(LineNo) .get(VMContext), File.getFileNode(), getNonCompileUnitScope(Scope)}; DINameSpace R(MDNode::get(VMContext, Elts)); assert(R.Verify() && "createNameSpace should return a verifiable DINameSpace"); return R; }
DILexicalBlockFile DIBuilder::createLexicalBlockFile(DIDescriptor Scope, DIFile File, unsigned Discriminator) { Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_lexical_block) .concat(Discriminator) .get(VMContext), File.getFileNode(), Scope}; DILexicalBlockFile R(MDNode::get(VMContext, Elts)); assert( R.Verify() && "createLexicalBlockFile should return a verifiable DILexicalBlockFile"); return R; }
/// createLexicalBlockFile - This creates a new MDNode that encapsulates /// an existing scope with a new filename. DILexicalBlockFile DIBuilder::createLexicalBlockFile(DIDescriptor Scope, DIFile File) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_lexical_block), File.getFileNode(), Scope }; DILexicalBlockFile R(MDNode::get(VMContext, Elts)); assert( R.Verify() && "createLexicalBlockFile should return a verifiable DILexicalBlockFile"); return R; }
/// createNameSpace - This creates new descriptor for a namespace /// with the specified parent scope. DINameSpace DIBuilder::createNameSpace(DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNo) { Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_namespace), File.getFileNode(), getNonCompileUnitScope(Scope), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), LineNo) }; DINameSpace R(MDNode::get(VMContext, Elts)); assert(R.Verify() && "createNameSpace should return a verifiable DINameSpace"); return R; }
DIDerivedType DIBuilder::createTypedef(DIType Ty, StringRef Name, DIFile File, unsigned LineNo, DIDescriptor Context) { // typedefs are encoded in DIDerivedType format. Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_typedef) .concat(Name) .concat(LineNo) .concat(0) // Size .concat(0) // Align .concat(0) // Offset .concat(0) // Flags .get(VMContext), File.getFileNode(), DIScope(getNonCompileUnitScope(Context)).getRef(), Ty.getRef()}; return DIDerivedType(MDNode::get(VMContext, Elts)); }
DILexicalBlock DIBuilder::createLexicalBlock(DIDescriptor Scope, DIFile File, unsigned Line, unsigned Col) { // Defeat MDNode uniqing for lexical blocks by using unique id. static unsigned int unique_id = 0; Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_lexical_block), File.getFileNode(), getNonCompileUnitScope(Scope), ConstantInt::get(Type::getInt32Ty(VMContext), Line), ConstantInt::get(Type::getInt32Ty(VMContext), Col), ConstantInt::get(Type::getInt32Ty(VMContext), unique_id++) }; DILexicalBlock R(MDNode::get(VMContext, Elts)); assert(R.Verify() && "createLexicalBlock should return a verifiable DILexicalBlock"); return R; }
/// createMethod - Create a new descriptor for the specified C++ method. DISubprogram DIBuilder::createMethod(DIDescriptor Context, StringRef Name, StringRef LinkageName, DIFile F, unsigned LineNo, DICompositeType Ty, bool isLocalToUnit, bool isDefinition, unsigned VK, unsigned VIndex, DIType VTableHolder, unsigned Flags, bool isOptimized, Function *Fn, MDNode *TParam) { assert(Ty.getTag() == dwarf::DW_TAG_subroutine_type && "function types should be subroutines"); Value *TElts[] = { GetTagConstant(VMContext, DW_TAG_base_type) }; Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_subprogram), F.getFileNode(), getNonCompileUnitScope(Context), MDString::get(VMContext, Name), MDString::get(VMContext, Name), MDString::get(VMContext, LinkageName), ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), Ty, ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit), ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition), ConstantInt::get(Type::getInt32Ty(VMContext), (unsigned)VK), ConstantInt::get(Type::getInt32Ty(VMContext), VIndex), VTableHolder.generateRef(), ConstantInt::get(Type::getInt32Ty(VMContext), Flags), ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized), Fn, TParam, Constant::getNullValue(Type::getInt32Ty(VMContext)), MDNode::getTemporary(VMContext, TElts), // FIXME: Do we want to use different scope/lines? ConstantInt::get(Type::getInt32Ty(VMContext), LineNo) }; MDNode *Node = MDNode::get(VMContext, Elts); if (isDefinition) AllSubprograms.push_back(Node); DISubprogram S(Node); assert(S.isSubprogram() && "createMethod should return a valid DISubprogram"); return S; }
/// createFunction - Create a new descriptor for the specified function. DISubprogram DIBuilder::createFunction(DIDescriptor Context, StringRef Name, StringRef LinkageName, DIFile File, unsigned LineNo, DICompositeType Ty, bool isLocalToUnit, bool isDefinition, unsigned ScopeLine, unsigned Flags, bool isOptimized, Function *Fn, MDNode *TParams, MDNode *Decl) { assert(Ty.getTag() == dwarf::DW_TAG_subroutine_type && "function types should be subroutines"); Value *TElts[] = { GetTagConstant(VMContext, DW_TAG_base_type) }; Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_subprogram), File.getFileNode(), getNonCompileUnitScope(Context), MDString::get(VMContext, Name), MDString::get(VMContext, Name), MDString::get(VMContext, LinkageName), ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), Ty, ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit), ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition), ConstantInt::get(Type::getInt32Ty(VMContext), 0), ConstantInt::get(Type::getInt32Ty(VMContext), 0), NULL, ConstantInt::get(Type::getInt32Ty(VMContext), Flags), ConstantInt::get(Type::getInt1Ty(VMContext), isOptimized), Fn, TParams, Decl, MDNode::getTemporary(VMContext, TElts), ConstantInt::get(Type::getInt32Ty(VMContext), ScopeLine) }; MDNode *Node = MDNode::get(VMContext, Elts); // Create a named metadata so that we do not lose this mdnode. if (isDefinition) AllSubprograms.push_back(Node); DISubprogram S(Node); assert(S.isSubprogram() && "createFunction should return a valid DISubprogram"); return S; }
/// createTypedef - Create debugging information entry for a typedef. DIDerivedType DIBuilder::createTypedef(DIType Ty, StringRef Name, DIFile File, unsigned LineNo, DIDescriptor Context) { // typedefs are encoded in DIDerivedType format. assert(Ty.Verify() && "Invalid typedef type!"); Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_typedef), File.getFileNode(), getNonCompileUnitScope(Context), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Size ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Align ConstantInt::get(Type::getInt64Ty(VMContext), 0), // Offset ConstantInt::get(Type::getInt32Ty(VMContext), 0), // Flags Ty }; return DIDerivedType(MDNode::get(VMContext, Elts)); }
/// createMemberType - Create debugging information entry for a member. DIDerivedType DIBuilder::createMemberType( DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, DIType Ty) { // TAG_member is encoded in DIDerivedType format. Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_member), File.getFileNode(), getNonCompileUnitScope(Scope), 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::getInt64Ty(VMContext), OffsetInBits), ConstantInt::get(Type::getInt32Ty(VMContext), Flags), Ty }; return DIDerivedType(MDNode::get(VMContext, Elts)); }
DIDerivedType DIBuilder::createObjCIVar(StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, DIType Ty, MDNode *PropertyNode) { // TAG_member is encoded in DIDerivedType format. Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_member) .concat(Name) .concat(LineNumber) .concat(SizeInBits) .concat(AlignInBits) .concat(OffsetInBits) .concat(Flags) .get(VMContext), File.getFileNode(), getNonCompileUnitScope(File), Ty, PropertyNode}; return DIDerivedType(MDNode::get(VMContext, Elts)); }
DIDerivedType DIBuilder::createStaticMemberType(DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber, DIType Ty, unsigned Flags, llvm::Constant *Val) { // TAG_member is encoded in DIDerivedType format. Flags |= DIDescriptor::FlagStaticMember; Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_member) .concat(Name) .concat(LineNumber) .concat(0) // Size .concat(0) // Align .concat(0) // Offset .concat(Flags) .get(VMContext), File.getFileNode(), DIScope(getNonCompileUnitScope(Scope)).getRef(), Ty.getRef(), Val}; return DIDerivedType(MDNode::get(VMContext, Elts)); }
DIDerivedType DIBuilder::createMemberType(DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, DIType Ty) { // TAG_member is encoded in DIDerivedType format. Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_member) .concat(Name) .concat(LineNumber) .concat(SizeInBits) .concat(AlignInBits) .concat(OffsetInBits) .concat(Flags) .get(VMContext), File.getFileNode(), DIScope(getNonCompileUnitScope(Scope)).getRef(), Ty.getRef()}; return DIDerivedType(MDNode::get(VMContext, Elts)); }
/// createStaticMemberType - Create debugging information entry for a /// C++ static data member. DIType DIBuilder::createStaticMemberType(DIDescriptor Scope, StringRef Name, DIFile File, unsigned LineNumber, DIType Ty, unsigned Flags, llvm::Value *Val) { // TAG_member is encoded in DIDerivedType format. Flags |= DIDescriptor::FlagStaticMember; Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_member), File.getFileNode(), getNonCompileUnitScope(Scope), MDString::get(VMContext, Name), ConstantInt::get(Type::getInt32Ty(VMContext), LineNumber), ConstantInt::get(Type::getInt64Ty(VMContext), 0/*SizeInBits*/), ConstantInt::get(Type::getInt64Ty(VMContext), 0/*AlignInBits*/), ConstantInt::get(Type::getInt64Ty(VMContext), 0/*OffsetInBits*/), ConstantInt::get(Type::getInt32Ty(VMContext), Flags), Ty, Val }; return DIType(MDNode::get(VMContext, Elts)); }
DILexicalBlock DIBuilder::createLexicalBlock(DIDescriptor Scope, DIFile File, unsigned Line, unsigned Col) { // FIXME: This isn't thread safe nor the right way to defeat MDNode uniquing. // I believe the right way is to have a self-referential element in the node. // Also: why do we bother with line/column - they're not used and the // documentation (SourceLevelDebugging.rst) claims the line/col are necessary // for uniquing, yet then we have this other solution (because line/col were // inadequate) anyway. Remove all 3 and replace them with a self-reference. // Defeat MDNode uniquing for lexical blocks by using unique id. static unsigned int unique_id = 0; Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_lexical_block) .concat(Line) .concat(Col) .concat(unique_id++) .get(VMContext), File.getFileNode(), getNonCompileUnitScope(Scope)}; DILexicalBlock R(MDNode::get(VMContext, Elts)); assert(R.Verify() && "createLexicalBlock should return a verifiable DILexicalBlock"); return R; }
DISubprogram DIBuilder::createMethod(DIDescriptor Context, StringRef Name, StringRef LinkageName, DIFile F, unsigned LineNo, DICompositeType Ty, bool isLocalToUnit, bool isDefinition, unsigned VK, unsigned VIndex, DIType VTableHolder, unsigned Flags, bool isOptimized, Function *Fn, MDNode *TParam) { assert(Ty.getTag() == dwarf::DW_TAG_subroutine_type && "function types should be subroutines"); assert(getNonCompileUnitScope(Context) && "Methods should have both a Context and a context that isn't " "the compile unit."); Value *Elts[] = {HeaderBuilder::get(dwarf::DW_TAG_subprogram) .concat(Name) .concat(Name) .concat(LinkageName) .concat(LineNo) .concat(isLocalToUnit) .concat(isDefinition) .concat(VK) .concat(VIndex) .concat(Flags) .concat(isOptimized) .concat(LineNo) // FIXME: Do we want to use different scope/lines? .get(VMContext), F.getFileNode(), DIScope(Context).getRef(), Ty, VTableHolder.getRef(), Fn, TParam, nullptr, nullptr}; MDNode *Node = MDNode::get(VMContext, Elts); if (isDefinition) AllSubprograms.push_back(Node); DISubprogram S(Node); assert(S.isSubprogram() && "createMethod should return a valid DISubprogram"); return S; }
bool runOnFunction(Function &F) override { DecoupleLoopsPass &DLP = Pass::getAnalysis<DecoupleLoopsPass>(); const LoopInfo *LI = DLP.getLI(&F); DIFile *File = nullptr; // The file in which this loop is defined. vector<int> lines; // Line per instruction in the order of traversal. vector<int> cols; // Column per instruction in the order of traversal. vector<int> BBs; // Basic-block for each line. vector<int> Loops; // Loop for each line. vector<bool> branchLines; // true if instruction n is a branch instruction vector<bool> workLines; vector<bool> iterLines; int bb_count = 0; int loop_count = 0; for (Loop *L : *LI) { // Ignore loops we cannot decouple. if (!DLP.hasWork(L)) continue; for (Loop::block_iterator BI = L->block_begin(), BE = L->block_end(); BI != BE; ++BI, ++bb_count) { BasicBlock *BB = *BI; for (Instruction &Inst : *BB) { DILocation *Loc = Inst.getDebugLoc(); if (!Loc) { continue; } if (!File) { File = Loc->getFile(); } int line = Loc->getLine(); int col = Loc->getColumn(); lines.push_back(line); cols.push_back(col); BBs.push_back(bb_count); Loops.push_back(loop_count); branchLines.push_back(dyn_cast<BranchInst>(&Inst) ? true : false); workLines.push_back(DLP.isWork(Inst, L) ? true : false); iterLines.push_back(DLP.isIter(Inst, L) ? true : false); } } ++loop_count; } if (File != nullptr) { int prevLoop = -1; raw_os_ostream roos(cout); for (int i = 0; i < lines.size(); ++i) { int line = lines[i]; if (line == -1) continue; // Already traversed. if (Loops[i] != prevLoop) { prevLoop = Loops[i]; roos << "Loop " << Loops[i] << "\n"; } roos << File->getFilename() << ":" << line; int prevBB = -1; for (int j = 0; j < lines.size(); ++j) { if (lines[j] != line) continue; // Destructive and messy (and slow). lines[j] = -1; if (BBs[j] != prevBB) { prevBB = BBs[j]; roos << " ; BB" << BBs[j] << ":"; } roos << " " << cols[j] << ":"; if (branchLines[j]) roos << "b-"; if (workLines[j]) roos << "w"; if (iterLines[j]) roos << "i"; } roos << '\n'; } } else { llvm::errs() << "ERROR: No debugging information found!\n"; } return false; }