diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 6234f12dd2b..421cdbd95fa 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -314,7 +314,7 @@ bool DwarfDebug::isSubprogramContext(const MDNode *Context) { // scope then create and insert DIEs for these variables. DIE &DwarfDebug::updateSubprogramScopeDIE(DwarfCompileUnit &SPCU, DISubprogram SP) { - DIE *SPDie = SPCU.getDIE(SP); + DIE *SPDie = SPCU.getOrCreateSubprogramDIE(SP); assert(SPDie && "Unable to find subprogram DIE!"); @@ -525,15 +525,18 @@ void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &TheCU, DISubprogram SP(Scope->getScopeNode()); - if (!ProcessedSPNodes.insert(SP)) + DIE *&AbsDef = AbstractSPDies[SP]; + if (AbsDef) return; // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram // was inlined from another compile unit. DwarfCompileUnit &SPCU = *SPMap[SP]; - DIE *AbsDef = SPCU.getDIE(SP); - assert(AbsDef); - AbstractSPDies.insert(std::make_pair(SP, AbsDef)); + AbsDef = SPCU.getOrCreateSubprogramDIE(SP); + + if (!ProcessedSPNodes.insert(SP)) + return; + SPCU.addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined); createAndAddScopeChildren(SPCU, Scope, *AbsDef); } @@ -781,7 +784,7 @@ void DwarfDebug::beginModule() { CU.createGlobalVariableDIE(DIGlobalVariable(GVs.getElement(i))); DIArray SPs = CUNode.getSubprograms(); for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i) - constructSubprogramDIE(CU, SPs.getElement(i)); + SPMap.insert(std::make_pair(SPs.getElement(i), &CU)); DIArray EnumTypes = CUNode.getEnumTypes(); for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i) CU.getOrCreateTypeDIE(EnumTypes.getElement(i)); @@ -818,8 +821,17 @@ void DwarfDebug::finishSubprogramDefinitions() { DIArray Subprograms = TheCU.getSubprograms(); for (unsigned i = 0, e = Subprograms.getNumElements(); i != e; ++i) { DISubprogram SP(Subprograms.getElement(i)); - if (DIE *D = SPCU->getDIE(SP)) - SPCU->applySubprogramAttributes(SP, *D); + // Perhaps the subprogram is in another CU (such as due to comdat + // folding, etc), in which case ignore it here. + if (SPMap[SP] != SPCU) + continue; + DIE *D = SPCU->getDIE(SP); + if (!D) + // Lazily construct the subprogram if we didn't see either concrete or + // inlined versions during codegen. + D = SPCU->getOrCreateSubprogramDIE(SP); + SPCU->applySubprogramAttributes(SP, *D); + SPCU->addGlobalName(SP.getName(), *D, resolve(SP.getContext())); } } } @@ -863,11 +875,11 @@ void DwarfDebug::collectDeadVariables() { } void DwarfDebug::finalizeModuleInfo() { + finishSubprogramDefinitions(); + // Collect info for variables that were optimized out. collectDeadVariables(); - finishSubprogramDefinitions(); - // Handle anything that needs to be done on a per-unit basis after // all other generation. for (const auto &TheU : getUnits()) { diff --git a/test/DebugInfo/X86/concrete_out_of_line.ll b/test/DebugInfo/X86/concrete_out_of_line.ll index 5d4d5802bd1..5d9f6a5779b 100644 --- a/test/DebugInfo/X86/concrete_out_of_line.ll +++ b/test/DebugInfo/X86/concrete_out_of_line.ll @@ -14,6 +14,19 @@ ; CHECK: [[RELEASE_DECL:0x........]]: DW_TAG_subprogram ; CHECK: [[DTOR_DECL:0x........]]: DW_TAG_subprogram +; CHECK: [[D2_ABS:.*]]: DW_TAG_subprogram +; CHECK-NEXT: DW_AT_inline +; CHECK-NEXT: DW_AT_{{.*}}linkage_name {{.*}}D2 +; CHECK-NEXT: DW_AT_specification {{.*}} {[[DTOR_DECL]]} +; CHECK-NOT: DW_AT +; CHECK: DW_TAG +; CHECK: [[D1_ABS:.*]]: DW_TAG_subprogram +; CHECK-NEXT: DW_AT_inline +; CHECK-NEXT: DW_AT_{{.*}}linkage_name {{.*}}D1 +; CHECK-NEXT: DW_AT_specification {{.*}} {[[DTOR_DECL]]} +; CHECK-NOT: DW_AT +; CHECK: [[D1_THIS_ABS:.*]]: DW_TAG_formal_parameter + ; CHECK: [[RELEASE:0x........]]: DW_TAG_subprogram ; CHECK: DW_AT_specification {{.*}} {[[RELEASE_DECL]]} ; CHECK: DW_TAG_formal_parameter @@ -27,28 +40,14 @@ ; CHECK-NOT: NULL ; CHECK-NOT: DW_TAG ; CHECK: DW_TAG_inlined_subroutine -; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[D1_ABS:0x........]]} +; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[D1_ABS]]} ; CHECK-NOT: NULL ; CHECK-NOT: DW_TAG ; CHECK: DW_TAG_inlined_subroutine -; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[D2_ABS:0x........]]} - -; CHECK: [[D1_ABS]]: DW_TAG_subprogram -; CHECK-NEXT: DW_AT_inline -; CHECK-NEXT: DW_AT_{{.*}}linkage_name -; CHECK-NEXT: DW_AT_specification {{.*}} {[[DTOR_DECL]]} -; CHECK-NOT: DW_AT -; CHECK: [[D1_THIS_ABS:0x........]]: DW_TAG_formal_parameter -; CHECK: [[D2_ABS]]: DW_TAG_subprogram -; CHECK-NEXT: DW_AT_inline -; CHECK-NEXT: DW_AT_{{.*}}linkage_name -; CHECK-NEXT: DW_AT_specification {{.*}} {[[DTOR_DECL]]} -; CHECK-NOT: DW_AT -; CHECK: DW_TAG +; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[D2_ABS]]} ; and then that a TAG_subprogram refers to it with AT_abstract_origin. -; CHECK: DW_TAG_subprogram ; CHECK: DW_TAG_subprogram ; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[D1_ABS]]} ; CHECK: DW_TAG_formal_parameter diff --git a/test/DebugInfo/X86/debug-info-blocks.ll b/test/DebugInfo/X86/debug-info-blocks.ll index 5feab247723..430c1575816 100644 --- a/test/DebugInfo/X86/debug-info-blocks.ll +++ b/test/DebugInfo/X86/debug-info-blocks.ll @@ -5,6 +5,11 @@ ; rdar://problem/9279956 ; test that the DW_AT_location of self is at ( fbreg +{{[0-9]+}}, deref, +{{[0-9]+}} ) +; CHECK: [[A:.*]]: DW_TAG_structure_type +; CHECK-NEXT: DW_AT_APPLE_objc_complete_type +; CHECK-NEXT: DW_AT_name{{.*}}"A" + +; CHECK: DW_TAG_subprogram ; CHECK: DW_TAG_subprogram ; CHECK: DW_TAG_subprogram ; CHECK-NOT: DW_TAG @@ -32,9 +37,6 @@ ; 0x91 = DW_OP_fbreg ; CHECK: DW_AT_location{{.*}}91 {{[0-9]+}} 06 23 {{[0-9]+}} ) -; CHECK: [[A:.*]]: DW_TAG_structure_type -; CHECK-NEXT: DW_AT_APPLE_objc_complete_type -; CHECK-NEXT: DW_AT_name{{.*}}"A" ; CHECK: [[APTR]]: DW_TAG_pointer_type ; CHECK-NEXT: {[[A]]} diff --git a/test/DebugInfo/X86/inline-member-function.ll b/test/DebugInfo/X86/inline-member-function.ll index 4a4a19c1913..3dc6043bf36 100644 --- a/test/DebugInfo/X86/inline-member-function.ll +++ b/test/DebugInfo/X86/inline-member-function.ll @@ -13,21 +13,24 @@ ; return foo().func(i); ; } +; CHECK: DW_TAG_structure_type +; CHECK: DW_TAG_subprogram + +; But make sure we emit DW_AT_object_pointer on the abstract definition. +; CHECK: [[ABSTRACT_ORIGIN:.*]]: DW_TAG_subprogram +; CHECK-NOT: NULL +; CHECK-NOT: TAG +; CHECK: DW_AT_object_pointer + ; Ensure we omit DW_AT_object_pointer on inlined subroutines. ; CHECK: DW_TAG_inlined_subroutine -; CHECK-NEXT: DW_AT_abstract_origin {{.*}}{[[ABSTRACT_ORIGIN:0x[0-9a-e]*]]} +; CHECK-NEXT: DW_AT_abstract_origin {{.*}}{[[ABSTRACT_ORIGIN]]} ; CHECK-NOT: NULL ; CHECK-NOT: DW_AT_object_pointer ; CHECK: DW_TAG_formal_parameter ; CHECK-NOT: DW_AT_artificial ; CHECK: DW_TAG -; But make sure we emit DW_AT_object_pointer on the abstract definition. -; CHECK: [[ABSTRACT_ORIGIN]]: DW_TAG_subprogram -; CHECK-NOT: NULL -; CHECK-NOT: TAG -; CHECK: DW_AT_object_pointer - %struct.foo = type { i8 } @i = global i32 0, align 4 diff --git a/test/DebugInfo/X86/inline-seldag-test.ll b/test/DebugInfo/X86/inline-seldag-test.ll index f139140ee75..615f03a2ad2 100644 --- a/test/DebugInfo/X86/inline-seldag-test.ll +++ b/test/DebugInfo/X86/inline-seldag-test.ll @@ -11,12 +11,13 @@ ; x = f(x); ; } -; CHECK: DW_TAG_inlined_subroutine -; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[F:0x.*]]} -; CHECK: [[F]]: DW_TAG_subprogram +; CHECK: [[F:.*]]: DW_TAG_subprogram ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name {{.*}} "f" +; CHECK: DW_TAG_inlined_subroutine +; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[F]]} + ; Make sure the condition test is attributed to the inline function, not the ; location of the test's operands within the caller. diff --git a/test/DebugInfo/X86/sret.ll b/test/DebugInfo/X86/sret.ll index 004632814c2..fed4334c27f 100644 --- a/test/DebugInfo/X86/sret.ll +++ b/test/DebugInfo/X86/sret.ll @@ -3,8 +3,8 @@ ; Based on the debuginfo-tests/sret.cpp code. -; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0xc68148e4333befda) -; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0xc68148e4333befda) +; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x72aabf538392d298) +; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x72aabf538392d298) %class.A = type { i32 (...)**, i32 } %class.B = type { i8 } diff --git a/test/DebugInfo/debug-info-qualifiers.ll b/test/DebugInfo/debug-info-qualifiers.ll index 2aea7360707..b624d3874cb 100644 --- a/test/DebugInfo/debug-info-qualifiers.ll +++ b/test/DebugInfo/debug-info-qualifiers.ll @@ -21,8 +21,6 @@ ; CHECK-NEXT: DW_AT_rvalue_reference DW_FORM_flag_present ; ; CHECK: DW_TAG_subprogram -; -; CHECK: DW_TAG_subprogram ; CHECK-NOT: DW_TAG_subprogram ; CHECK: DW_AT_name {{.*}}"l" ; CHECK-NOT: DW_TAG_subprogram diff --git a/test/DebugInfo/namespace.ll b/test/DebugInfo/namespace.ll index ca5cf808d18..a9de62c3906 100644 --- a/test/DebugInfo/namespace.ll +++ b/test/DebugInfo/namespace.ll @@ -16,18 +16,6 @@ ; CHECK: [[I:0x[0-9a-f]*]]:{{ *}}DW_TAG_variable ; CHECK-NEXT: DW_AT_name{{.*}}= "i" ; CHECK-NOT: NULL -; CHECK: DW_TAG_subprogram -; CHECK-NOT: DW_TAG -; CHECK: DW_AT_MIPS_linkage_name -; CHECK-NOT: DW_TAG -; CHECK: DW_AT_name{{.*}}= "f1" -; CHECK: [[FUNC1:0x[0-9a-f]*]]:{{ *}}DW_TAG_subprogram -; CHECK-NOT: DW_TAG -; CHECK: DW_AT_MIPS_linkage_name -; CHECK-NOT: DW_TAG -; CHECK: DW_AT_name{{.*}}= "f1" -; CHECK: NULL -; CHECK-NOT: NULL ; CHECK: [[FOO:0x[0-9a-f]*]]:{{ *}}DW_TAG_structure_type ; CHECK-NEXT: DW_AT_name{{.*}}= "foo" ; CHECK-NEXT: DW_AT_declaration @@ -35,7 +23,16 @@ ; CHECK: [[BAR:0x[0-9a-f]*]]:{{ *}}DW_TAG_structure_type ; CHECK-NEXT: DW_AT_name{{.*}}= "bar" ; CHECK: NULL -; CHECK: NULL +; CHECK: [[FUNC1:.*]]: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_MIPS_linkage_name +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}= "f1" +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_MIPS_linkage_name +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name{{.*}}= "f1" ; CHECK: NULL ; CHECK-NOT: NULL @@ -48,6 +45,13 @@ ; CHECK: NULL ; CHECK-NOT: NULL +; CHECK: DW_TAG_imported_module +; Same bug as above, this should be F2, not F1 +; CHECK-NEXT: DW_AT_decl_file{{.*}}(0x0[[F1]]) +; CHECK-NEXT: DW_AT_decl_line{{.*}}(0x0b) +; CHECK-NEXT: DW_AT_import{{.*}}=> {[[NS1]]}) +; CHECK-NOT: NULL + ; CHECK: DW_TAG_subprogram ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_MIPS_linkage_name @@ -99,13 +103,7 @@ ; CHECK-NEXT: DW_AT_import{{.*}}=> {[[NS2]]}) ; CHECK: NULL ; CHECK: NULL -; CHECK-NOT: NULL - -; CHECK: DW_TAG_imported_module -; Same bug as above, this should be F2, not F1 -; CHECK-NEXT: DW_AT_decl_file{{.*}}(0x0[[F1]]) -; CHECK-NEXT: DW_AT_decl_line{{.*}}(0x0b) -; CHECK-NEXT: DW_AT_import{{.*}}=> {[[NS1]]}) +; CHECK: NULL ; CHECK: file_names[ [[F1]]]{{.*}}debug-info-namespace.cpp ; CHECK: file_names[ [[F2]]]{{.*}}foo.cpp diff --git a/test/DebugInfo/varargs.ll b/test/DebugInfo/varargs.ll index a3274142619..ddfcd858f53 100644 --- a/test/DebugInfo/varargs.ll +++ b/test/DebugInfo/varargs.ll @@ -13,6 +13,16 @@ ; ; CHECK: DW_TAG_subprogram ; CHECK-NOT: DW_TAG +; CHECK: DW_AT_name {{.*}} "a" +; CHECK-NOT: DW_TAG +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_TAG +; CHECK: DW_TAG_unspecified_parameters +; +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name {{.*}} "b" ; CHECK-NOT: DW_TAG ; CHECK: DW_TAG_formal_parameter @@ -22,16 +32,6 @@ ; Variadic C++ member function. ; struct A { void a(int c, ...); } ; -; CHECK: DW_TAG_subprogram -; CHECK-NOT: DW_TAG -; CHECK: DW_AT_name {{.*}} "a" -; CHECK-NOT: DW_TAG -; CHECK: DW_TAG_formal_parameter -; CHECK-NOT: DW_TAG -; CHECK: DW_TAG_formal_parameter -; CHECK-NOT: DW_TAG -; CHECK: DW_TAG_unspecified_parameters -; ; Variadic function pointer. ; void (*fptr)(int, ...); ; diff --git a/test/Linker/type-unique-odr-a.ll b/test/Linker/type-unique-odr-a.ll index 54befb75ba4..91c80339ec0 100644 --- a/test/Linker/type-unique-odr-a.ll +++ b/test/Linker/type-unique-odr-a.ll @@ -22,12 +22,6 @@ ; return A().getFoo(); ; } ; -; CHECK: DW_TAG_subprogram -; CHECK-NOT: DW_TAG -; CHECK: DW_AT_MIPS_linkage_name {{.*}} "_Z3bazv" -; CHECK: DW_TAG_subprogram -; CHECK-NOT: DW_TAG -; CHECK: DW_AT_MIPS_linkage_name {{.*}} "_ZL3barv" ; CHECK: DW_TAG_class_type ; CHECK-NEXT: DW_AT_name {{.*}} "A" ; CHECK-NOT: DW_TAG @@ -39,6 +33,12 @@ ; CHECK: DW_AT_MIPS_linkage_name {{.*}} "_ZN1A6getFooEv" ; CHECK-NOT: DW_TAG ; CHECK: DW_AT_name {{.*}} "getFoo" +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_MIPS_linkage_name {{.*}} "_Z3bazv" +; CHECK: DW_TAG_subprogram +; CHECK-NOT: DW_TAG +; CHECK: DW_AT_MIPS_linkage_name {{.*}} "_ZL3barv" ; getFoo and A may only appear once. ; CHECK-NOT: {{(getFoo)|("A")}}