summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp32
-rw-r--r--llvm/test/DebugInfo/X86/concrete_out_of_line.ll31
-rw-r--r--llvm/test/DebugInfo/X86/debug-info-blocks.ll8
-rw-r--r--llvm/test/DebugInfo/X86/inline-member-function.ll17
-rw-r--r--llvm/test/DebugInfo/X86/inline-seldag-test.ll7
-rw-r--r--llvm/test/DebugInfo/X86/sret.ll4
-rw-r--r--llvm/test/DebugInfo/debug-info-qualifiers.ll2
-rw-r--r--llvm/test/DebugInfo/namespace.ll36
-rw-r--r--llvm/test/DebugInfo/varargs.ll14
-rw-r--r--llvm/test/Linker/type-unique-odr-a.ll12
10 files changed, 88 insertions, 75 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 6234f12dd2b..421cdbd95fa 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/llvm/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/llvm/test/DebugInfo/X86/concrete_out_of_line.ll b/llvm/test/DebugInfo/X86/concrete_out_of_line.ll
index 5d4d5802bd1..5d9f6a5779b 100644
--- a/llvm/test/DebugInfo/X86/concrete_out_of_line.ll
+++ b/llvm/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,29 +40,15 @@
; 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
; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[D1_THIS_ABS]]}
diff --git a/llvm/test/DebugInfo/X86/debug-info-blocks.ll b/llvm/test/DebugInfo/X86/debug-info-blocks.ll
index 5feab247723..430c1575816 100644
--- a/llvm/test/DebugInfo/X86/debug-info-blocks.ll
+++ b/llvm/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/llvm/test/DebugInfo/X86/inline-member-function.ll b/llvm/test/DebugInfo/X86/inline-member-function.ll
index 4a4a19c1913..3dc6043bf36 100644
--- a/llvm/test/DebugInfo/X86/inline-member-function.ll
+++ b/llvm/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/llvm/test/DebugInfo/X86/inline-seldag-test.ll b/llvm/test/DebugInfo/X86/inline-seldag-test.ll
index f139140ee75..615f03a2ad2 100644
--- a/llvm/test/DebugInfo/X86/inline-seldag-test.ll
+++ b/llvm/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/llvm/test/DebugInfo/X86/sret.ll b/llvm/test/DebugInfo/X86/sret.ll
index 004632814c2..fed4334c27f 100644
--- a/llvm/test/DebugInfo/X86/sret.ll
+++ b/llvm/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/llvm/test/DebugInfo/debug-info-qualifiers.ll b/llvm/test/DebugInfo/debug-info-qualifiers.ll
index 2aea7360707..b624d3874cb 100644
--- a/llvm/test/DebugInfo/debug-info-qualifiers.ll
+++ b/llvm/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/llvm/test/DebugInfo/namespace.ll b/llvm/test/DebugInfo/namespace.ll
index ca5cf808d18..a9de62c3906 100644
--- a/llvm/test/DebugInfo/namespace.ll
+++ b/llvm/test/DebugInfo/namespace.ll
@@ -16,27 +16,24 @@
; CHECK: [[I:0x[0-9a-f]*]]:{{ *}}DW_TAG_variable
; CHECK-NEXT: DW_AT_name{{.*}}= "i"
; CHECK-NOT: NULL
-; CHECK: DW_TAG_subprogram
+; CHECK: [[FOO:0x[0-9a-f]*]]:{{ *}}DW_TAG_structure_type
+; CHECK-NEXT: DW_AT_name{{.*}}= "foo"
+; CHECK-NEXT: DW_AT_declaration
+; CHECK-NOT: NULL
+; CHECK: [[BAR:0x[0-9a-f]*]]:{{ *}}DW_TAG_structure_type
+; CHECK-NEXT: DW_AT_name{{.*}}= "bar"
+; 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: [[FUNC1:0x[0-9a-f]*]]:{{ *}}DW_TAG_subprogram
+; 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
-; CHECK: [[FOO:0x[0-9a-f]*]]:{{ *}}DW_TAG_structure_type
-; CHECK-NEXT: DW_AT_name{{.*}}= "foo"
-; CHECK-NEXT: DW_AT_declaration
-; CHECK-NOT: NULL
-; CHECK: [[BAR:0x[0-9a-f]*]]:{{ *}}DW_TAG_structure_type
-; CHECK-NEXT: DW_AT_name{{.*}}= "bar"
-; CHECK: NULL
-; CHECK: NULL
-; CHECK: NULL
; CHECK-NOT: NULL
; CHECK: DW_TAG_imported_module
@@ -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/llvm/test/DebugInfo/varargs.ll b/llvm/test/DebugInfo/varargs.ll
index a3274142619..ddfcd858f53 100644
--- a/llvm/test/DebugInfo/varargs.ll
+++ b/llvm/test/DebugInfo/varargs.ll
@@ -13,25 +13,25 @@
;
; CHECK: DW_TAG_subprogram
; CHECK-NOT: DW_TAG
-; CHECK: DW_AT_name {{.*}} "b"
+; 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 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: DW_AT_name {{.*}} "b"
; CHECK-NOT: DW_TAG
; CHECK: DW_TAG_formal_parameter
; CHECK-NOT: DW_TAG
; CHECK: DW_TAG_unspecified_parameters
;
+; Variadic C++ member function.
+; struct A { void a(int c, ...); }
+;
; Variadic function pointer.
; void (*fptr)(int, ...);
;
diff --git a/llvm/test/Linker/type-unique-odr-a.ll b/llvm/test/Linker/type-unique-odr-a.ll
index 54befb75ba4..91c80339ec0 100644
--- a/llvm/test/Linker/type-unique-odr-a.ll
+++ b/llvm/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")}}
OpenPOWER on IntegriCloud