diff --git a/include/llvm/DIBuilder.h b/include/llvm/DIBuilder.h index 39ff317a748..44ce3e42132 100644 --- a/include/llvm/DIBuilder.h +++ b/include/llvm/DIBuilder.h @@ -562,6 +562,20 @@ namespace llvm { MDNode *TParam = 0, MDNode *Decl = 0); + /// FIXME: this is added for dragonegg. Once we update dragonegg + /// to call resolve function, this will be removed. + DISubprogram createFunction(DIScopeRef Scope, StringRef Name, + StringRef LinkageName, + DIFile File, unsigned LineNo, + DICompositeType Ty, bool isLocalToUnit, + bool isDefinition, + unsigned ScopeLine, + unsigned Flags = 0, + bool isOptimized = false, + Function *Fn = 0, + MDNode *TParam = 0, + MDNode *Decl = 0); + /// createMethod - Create a new descriptor for the specified C++ method. /// See comments in DISubprogram for descriptions of these fields. /// @param Scope Function scope. diff --git a/include/llvm/DebugInfo.h b/include/llvm/DebugInfo.h index 3f1c1c802dc..3e4a960ea7b 100644 --- a/include/llvm/DebugInfo.h +++ b/include/llvm/DebugInfo.h @@ -434,7 +434,7 @@ class DISubprogram : public DIScope { public: explicit DISubprogram(const MDNode *N = 0) : DIScope(N) {} - DIScope getContext() const { return getFieldAs(2); } + DIScopeRef getContext() const { return getFieldAs(2); } StringRef getName() const { return getStringField(3); } StringRef getDisplayName() const { return getStringField(4); } StringRef getLinkageName() const { return getStringField(5); } diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index b8bc0a90c31..f91f54e773c 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -1300,7 +1300,7 @@ DIE *CompileUnit::getOrCreateSubprogramDIE(DISubprogram SP) { // Construct the context before querying for the existence of the DIE in case // such construction creates the DIE (as is the case for member function // declarations). - DIE *ContextDIE = getOrCreateContextDIE(SP.getContext()); + DIE *ContextDIE = getOrCreateContextDIE(resolve(SP.getContext())); if (!ContextDIE) ContextDIE = CUDie.get(); diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index cfe4ea6e3f4..f400eb99219 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -393,9 +393,10 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(CompileUnit *SPCU, // function then gdb prefers the definition at top level and but does not // expect specification DIE in parent function. So avoid creating // specification DIE for a function defined inside a function. - if (SP.isDefinition() && !SP.getContext().isCompileUnit() && - !SP.getContext().isFile() && - !isSubprogramContext(SP.getContext())) { + DIScope SPContext = resolve(SP.getContext()); + if (SP.isDefinition() && !SPContext.isCompileUnit() && + !SPContext.isFile() && + !isSubprogramContext(SPContext)) { SPCU->addFlag(SPDie, dwarf::DW_AT_declaration); // Add arguments. diff --git a/lib/IR/DIBuilder.cpp b/lib/IR/DIBuilder.cpp index 746fc5f4f81..199476f7144 100644 --- a/lib/IR/DIBuilder.cpp +++ b/lib/IR/DIBuilder.cpp @@ -1040,6 +1040,28 @@ DIVariable DIBuilder::createComplexVariable(unsigned Tag, DIDescriptor Scope, return DIVariable(MDNode::get(VMContext, Elts)); } +/// createFunction - Create a new descriptor for the specified function. +/// FIXME: this is added for dragonegg. Once we update dragonegg +/// to call resolve function, this will be removed. +DISubprogram DIBuilder::createFunction(DIScopeRef 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) { + // dragonegg does not generate identifier for types, so using an empty map + // to resolve the context should be fine. + DITypeIdentifierMap EmptyMap; + return createFunction(Context.resolve(EmptyMap), Name, LinkageName, File, + LineNo, Ty, isLocalToUnit, isDefinition, ScopeLine, + Flags, isOptimized, Fn, TParams, Decl); +} + /// createFunction - Create a new descriptor for the specified function. DISubprogram DIBuilder::createFunction(DIDescriptor Context, StringRef Name, @@ -1058,7 +1080,7 @@ DISubprogram DIBuilder::createFunction(DIDescriptor Context, Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_subprogram), File.getFileNode(), - getNonCompileUnitScope(Context), + DIScope(getNonCompileUnitScope(Context)).getRef(), MDString::get(VMContext, Name), MDString::get(VMContext, Name), MDString::get(VMContext, LinkageName), @@ -1107,7 +1129,7 @@ DISubprogram DIBuilder::createMethod(DIDescriptor Context, Value *Elts[] = { GetTagConstant(VMContext, dwarf::DW_TAG_subprogram), F.getFileNode(), - getNonCompileUnitScope(Context), + DIScope(getNonCompileUnitScope(Context)).getRef(), MDString::get(VMContext, Name), MDString::get(VMContext, Name), MDString::get(VMContext, LinkageName), diff --git a/lib/IR/DebugInfo.cpp b/lib/IR/DebugInfo.cpp index a6ea942059b..290aa62abf4 100644 --- a/lib/IR/DebugInfo.cpp +++ b/lib/IR/DebugInfo.cpp @@ -511,8 +511,8 @@ bool DISubprogram::Verify() const { if (!isSubprogram()) return false; - // Make sure context @ field 2 and type @ field 7 are MDNodes. - if (!fieldIsMDNode(DbgNode, 2)) + // Make sure context @ field 2 is a ScopeRef and type @ field 7 is a MDNode. + if (!fieldIsScopeRef(DbgNode, 2)) return false; if (!fieldIsMDNode(DbgNode, 7)) return false; @@ -1071,7 +1071,7 @@ void DebugInfoFinder::processLexicalBlock(DILexicalBlock LB) { void DebugInfoFinder::processSubprogram(DISubprogram SP) { if (!addSubprogram(SP)) return; - processScope(SP.getContext()); + processScope(SP.getContext().resolve(TypeIdentifierMap)); processType(SP.getType()); DIArray TParams = SP.getTemplateParams(); for (unsigned I = 0, E = TParams.getNumElements(); I != E; ++I) { diff --git a/test/DebugInfo/tu-composite.ll b/test/DebugInfo/tu-composite.ll index 54bc3bc9b7f..0d71d8acdc8 100644 --- a/test/DebugInfo/tu-composite.ll +++ b/test/DebugInfo/tu-composite.ll @@ -6,9 +6,16 @@ ; Make sure we correctly handle containing type of a struct being a type identifier. ; CHECK-NEXT: DW_AT_containing_type [DW_FORM_ref4] (cu + {{.*}} => {[[TYPE]]}) ; CHECK-NEXT: DW_AT_name [DW_FORM_strp] {{.*}}= "C") + +; Make sure we correctly handle context of a subprogram being a type identifier. ; CHECK: [[SP:.*]]: DW_TAG_subprogram +; CHECK: DW_AT_name [DW_FORM_strp] {{.*}}= "foo") ; Make sure we correctly handle containing type of a subprogram being a type identifier. ; CHECK: DW_AT_containing_type [DW_FORM_ref4] (cu + {{.*}} => {[[TYPE]]}) +; CHECK: DW_TAG_formal_parameter +; CHECK: NULL +; CHECK: NULL + ; CHECK: [[TYPE2:.*]]: DW_TAG_structure_type ; CHECK: DW_TAG_structure_type ; CHECK: DW_AT_name [DW_FORM_strp] {{.*}}= "D") @@ -128,7 +135,7 @@ attributes #1 = { nounwind readnone } !10 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !11, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] !11 = metadata !{metadata !12} !12 = metadata !{i32 786468, null, null, metadata !"int", i32 0, i64 32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ] [int] [line 0, size 32, align 32, offset 0, enc DW_ATE_signed] -!13 = metadata !{i32 786478, metadata !1, metadata !4, metadata !"foo", metadata !"foo", metadata !"_ZN1C3fooEv", i32 2, metadata !14, i1 false, i1 false, i32 1, i32 0, metadata !"_ZTS1C", i32 256, i1 false, null, null, i32 0, metadata !17, i32 2} ; [ DW_TAG_subprogram ] [line 2] [foo] +!13 = metadata !{i32 786478, metadata !1, metadata !"_ZTS1C", metadata !"foo", metadata !"foo", metadata !"_ZN1C3fooEv", i32 2, metadata !14, i1 false, i1 false, i32 1, i32 0, metadata !"_ZTS1C", i32 256, i1 false, null, null, i32 0, metadata !17, i32 2} ; [ DW_TAG_subprogram ] [line 2] [foo] !14 = metadata !{i32 786453, i32 0, null, metadata !"", i32 0, i64 0, i64 0, i64 0, i32 0, null, metadata !15, i32 0, null, null, null} ; [ DW_TAG_subroutine_type ] [line 0, size 0, align 0, offset 0] [from ] !15 = metadata !{null, metadata !16} !16 = metadata !{i32 786447, null, null, metadata !"", i32 0, i64 64, i64 64, i64 0, i32 1088, metadata !"_ZTS1C"} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from _ZTS1C] diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 0055bb09814..8a8da01a99e 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -404,7 +404,7 @@ struct BreakpointPrinter : public ModulePass { "A MDNode in llvm.dbg.sp should be null or a DISubprogram."); if (!SP) continue; - getContextName(SP.getContext(), Name); + getContextName(SP.getContext().resolve(TypeIdentifierMap), Name); Name = Name + SP.getDisplayName().str(); if (!Name.empty() && Processed.insert(Name)) { Out << Name << "\n";