summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp21
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h2
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfUnit.cpp8
-rw-r--r--test/DebugInfo/2010-04-06-NestedFnDbgInfo.ll4
-rw-r--r--test/DebugInfo/X86/concrete_out_of_line.ll9
-rw-r--r--test/DebugInfo/X86/dbg-value-inlined-parameter.ll4
-rw-r--r--test/DebugInfo/X86/debug-info-blocks.ll14
-rw-r--r--test/DebugInfo/X86/empty-and-one-elem-array.ll10
-rw-r--r--test/DebugInfo/cross-cu-inlining.ll10
-rw-r--r--test/DebugInfo/namespace_function_definition.ll4
10 files changed, 60 insertions, 26 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 5c802f7a2c..6234f12dd2 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -806,6 +806,25 @@ void DwarfDebug::beginModule() {
SectionMap[Asm->getObjFileLowering().getTextSection()];
}
+void DwarfDebug::finishSubprogramDefinitions() {
+ const Module *M = MMI->getModule();
+
+ NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
+ for (MDNode *N : CU_Nodes->operands()) {
+ DICompileUnit TheCU(N);
+ // Construct subprogram DIE and add variables DIEs.
+ DwarfCompileUnit *SPCU =
+ static_cast<DwarfCompileUnit *>(CUMap.lookup(TheCU));
+ 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);
+ }
+ }
+}
+
+
// Collect info for variables that were optimized out.
void DwarfDebug::collectDeadVariables() {
const Module *M = MMI->getModule();
@@ -847,6 +866,8 @@ void DwarfDebug::finalizeModuleInfo() {
// 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/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 1b0b1ebafd..4a4d01246c 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -389,6 +389,8 @@ class DwarfDebug : public AsmPrinterHandler {
/// \brief Collect info for variables that were optimized out.
void collectDeadVariables();
+ void finishSubprogramDefinitions();
+
/// \brief Finish off debug information after all functions have been
/// processed.
void finalizeModuleInfo();
diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index c6e47ec072..2707f8b73d 100644
--- a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -1389,6 +1389,11 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
// DW_TAG_inlined_subroutine may refer to this DIE.
DIE &SPDie = createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, SP);
+ // Abort here and fill this in later, depending on whether or not this
+ // subprogram turns out to have inlined instances or not.
+ if (SP.isDefinition())
+ return &SPDie;
+
applySubprogramAttributes(SP, SPDie);
return &SPDie;
}
@@ -1397,7 +1402,8 @@ void DwarfUnit::applySubprogramAttributes(DISubprogram SP, DIE &SPDie) {
DIE *DeclDie = nullptr;
StringRef DeclLinkageName;
if (DISubprogram SPDecl = SP.getFunctionDeclaration()) {
- DeclDie = getOrCreateSubprogramDIE(SPDecl);
+ DeclDie = getDIE(SPDecl);
+ assert(DeclDie);
DeclLinkageName = SPDecl.getLinkageName();
}
diff --git a/test/DebugInfo/2010-04-06-NestedFnDbgInfo.ll b/test/DebugInfo/2010-04-06-NestedFnDbgInfo.ll
index e81667f679..5f7cb696d7 100644
--- a/test/DebugInfo/2010-04-06-NestedFnDbgInfo.ll
+++ b/test/DebugInfo/2010-04-06-NestedFnDbgInfo.ll
@@ -10,10 +10,10 @@
; Check that the subprogram inside the class definition has low_pc, only
; attached to the definition.
; CHECK: [[FOO_INL:0x........]]: DW_TAG_subprogram
-; CHECK-NEXT: DW_AT_MIPS_linkage_name {{.*}} "_ZZN1B2fnEvEN1A3fooEv"
-; CHECK-NOT: NULL
; CHECK-NOT: DW_TAG
; CHECK: DW_AT_low_pc
+; CHECK-NOT: DW_TAG
+; CHECK: DW_AT_MIPS_linkage_name {{.*}} "_ZZN1B2fnEvEN1A3fooEv"
; And just double check that there's no out of line definition that references
; this subprogram.
; CHECK-NOT: DW_AT_specification {{.*}} {[[FOO_INL]]}
diff --git a/test/DebugInfo/X86/concrete_out_of_line.ll b/test/DebugInfo/X86/concrete_out_of_line.ll
index a8bf7ca5f9..5d4d5802bd 100644
--- a/test/DebugInfo/X86/concrete_out_of_line.ll
+++ b/test/DebugInfo/X86/concrete_out_of_line.ll
@@ -34,17 +34,16 @@
; 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-NEXT: DW_AT_inline
-; CHECK-NOT: DW_AT_inline
-; CHECK-NOT: DW_TAG
+; 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-NEXT: DW_AT_inline
-; CHECK-NOT: DW_AT_inline
+; CHECK-NOT: DW_AT
; CHECK: DW_TAG
; and then that a TAG_subprogram refers to it with AT_abstract_origin.
diff --git a/test/DebugInfo/X86/dbg-value-inlined-parameter.ll b/test/DebugInfo/X86/dbg-value-inlined-parameter.ll
index b901711c2d..74b2f8bc33 100644
--- a/test/DebugInfo/X86/dbg-value-inlined-parameter.ll
+++ b/test/DebugInfo/X86/dbg-value-inlined-parameter.ll
@@ -9,9 +9,9 @@
; incorrect. They should be separate
; CHECK: [[ABS:.*]]: DW_TAG_subprogram
; CHECK-NOT: DW_TAG
-; CHECK: DW_AT_name {{.*}} "foo"
-; CHECK-NOT: DW_TAG
; CHECK: DW_AT_high_pc
+; CHECK-NOT: DW_TAG
+; CHECK: DW_AT_name {{.*}} "foo"
; CHECK: [[ABS_SP:.*]]: DW_TAG_formal_parameter
; CHECK-NEXT: DW_AT_name {{.*}} "sp"
; CHECK: [[ABS_NUMS:.*]]: DW_TAG_formal_parameter
diff --git a/test/DebugInfo/X86/debug-info-blocks.ll b/test/DebugInfo/X86/debug-info-blocks.ll
index b2531f6470..5feab24772 100644
--- a/test/DebugInfo/X86/debug-info-blocks.ll
+++ b/test/DebugInfo/X86/debug-info-blocks.ll
@@ -6,16 +6,20 @@
; test that the DW_AT_location of self is at ( fbreg +{{[0-9]+}}, deref, +{{[0-9]+}} )
; CHECK: DW_TAG_subprogram
-; CHECK: DW_AT_name{{.*}}_block_invoke
+; CHECK: DW_TAG_subprogram
+; CHECK-NOT: DW_TAG
; CHECK: DW_AT_object_pointer
+; CHECK-NOT: DW_TAG
+; CHECK: DW_AT_name{{.*}}_block_invoke
-; CHECK-NOT: DW_TAG_subprogram
+; CHECK-NOT: {{DW_TAG|NULL}}
; CHECK: DW_TAG_formal_parameter
-; CHECK-NEXT: DW_AT_name{{.*}}.block_descriptor
+; CHECK-NOT: DW_TAG
+; CHECK: DW_AT_name{{.*}}.block_descriptor
; CHECK-NOT: DW_TAG
; CHECK: DW_AT_location
-; CHECK-NOT: DW_TAG_subprogram
+; CHECK-NOT: {{DW_TAG|NULL}}
; CHECK: DW_TAG_variable
; CHECK-NEXT: DW_AT_name{{.*}}"self"
; CHECK-NOT: DW_TAG
@@ -31,7 +35,7 @@
; 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 [5]
+; CHECK: [[APTR]]: DW_TAG_pointer_type
; CHECK-NEXT: {[[A]]}
diff --git a/test/DebugInfo/X86/empty-and-one-elem-array.ll b/test/DebugInfo/X86/empty-and-one-elem-array.ll
index f5c37df1e5..974bd73479 100644
--- a/test/DebugInfo/X86/empty-and-one-elem-array.ll
+++ b/test/DebugInfo/X86/empty-and-one-elem-array.ll
@@ -28,11 +28,6 @@ declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
; An empty array should not have an AT_upper_bound attribute. But an array of 1
; should.
-; CHECK: DW_TAG_base_type
-; CHECK-NEXT: DW_AT_name [DW_FORM_strp] ( .debug_str[{{.*}}] = "int")
-; CHECK-NEXT: DW_AT_encoding [DW_FORM_data1] (0x05)
-; CHECK-NEXT: DW_AT_byte_size [DW_FORM_data1] (0x04)
-
; int foo::b[1]:
; CHECK: DW_TAG_structure_type
; CHECK: DW_AT_name{{.*}}"foo"
@@ -41,6 +36,11 @@ declare void @llvm.dbg.declare(metadata, metadata) nounwind readnone
; CHECK-NEXT: DW_AT_name [DW_FORM_strp] ( .debug_str[{{.*}}] = "b")
; CHECK-NEXT: DW_AT_type [DW_FORM_ref4]
+; CHECK: DW_TAG_base_type
+; CHECK-NEXT: DW_AT_name [DW_FORM_strp] ( .debug_str[{{.*}}] = "int")
+; CHECK-NEXT: DW_AT_encoding [DW_FORM_data1] (0x05)
+; CHECK-NEXT: DW_AT_byte_size [DW_FORM_data1] (0x04)
+
; int[1]:
; CHECK: DW_TAG_array_type [{{.*}}] *
; CHECK-NEXT: DW_AT_type [DW_FORM_ref4]
diff --git a/test/DebugInfo/cross-cu-inlining.ll b/test/DebugInfo/cross-cu-inlining.ll
index 44a1a58506..6e0378d57f 100644
--- a/test/DebugInfo/cross-cu-inlining.ll
+++ b/test/DebugInfo/cross-cu-inlining.ll
@@ -23,13 +23,11 @@
; CHECK: DW_TAG_compile_unit
; CHECK: DW_AT_name {{.*}} "a.cpp"
; CHECK: DW_TAG_subprogram
+; CHECK: DW_AT_type [DW_FORM_ref_addr] (0x00000000[[INT:.*]])
; CHECK: DW_TAG_inlined_subroutine
; CHECK-NEXT: DW_AT_abstract_origin {{.*}}[[ABS_FUNC:........]])
; CHECK: DW_TAG_formal_parameter
; CHECK-NEXT: DW_AT_abstract_origin {{.*}}[[ABS_VAR:........]])
-; CHECK: 0x[[INT:.*]]: DW_TAG_base_type
-; CHECK-NOT: DW_TAG
-; CHECK: DW_AT_name {{.*}} "int"
; Check the abstract definition is in the 'b.cpp' CU and doesn't contain any
; concrete information (address range or variable location)
@@ -40,9 +38,13 @@
; CHECK: 0x[[ABS_VAR]]: DW_TAG_formal_parameter
; CHECK-NOT: DW_TAG
; CHECK-NOT: DW_AT_location
-; CHECK: DW_AT_type [DW_FORM_ref_addr] (0x00000000[[INT]])
+; CHECK: DW_AT_type [DW_FORM_ref4] {{.*}} {0x[[INT]]}
; CHECK-NOT: DW_AT_location
+; CHECK: 0x[[INT]]: DW_TAG_base_type
+; CHECK-NOT: DW_TAG
+; CHECK: DW_AT_name {{.*}} "int"
+
; Check the concrete out of line definition references the abstract and
; provides the address range and variable location
; CHECK: DW_TAG_subprogram
diff --git a/test/DebugInfo/namespace_function_definition.ll b/test/DebugInfo/namespace_function_definition.ll
index 15f39fd6d9..590f2b301f 100644
--- a/test/DebugInfo/namespace_function_definition.ll
+++ b/test/DebugInfo/namespace_function_definition.ll
@@ -12,9 +12,9 @@
; CHECK-NEXT: DW_AT_name {{.*}} "ns"
; CHECK: DW_TAG_subprogram
; CHECK-NOT: DW_TAG
-; CHECK: DW_AT_MIPS_linkage_name {{.*}} "_ZN2ns4funcEv"
-; CHECK-NOT: DW_TAG
; CHECK: DW_AT_low_pc
+; CHECK-NOT: DW_TAG
+; CHECK: DW_AT_MIPS_linkage_name {{.*}} "_ZN2ns4funcEv"
; CHECK: NULL
; CHECK: NULL