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();
// 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()) {
/// \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();
// 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;
}
DIE *DeclDie = nullptr;
StringRef DeclLinkageName;
if (DISubprogram SPDecl = SP.getFunctionDeclaration()) {
- DeclDie = getOrCreateSubprogramDIE(SPDecl);
+ DeclDie = getDIE(SPDecl);
+ assert(DeclDie);
DeclLinkageName = SPDecl.getLinkageName();
}
; 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]]}
; 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.
; 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
; 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
; 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]]}
; 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"
; 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]
; 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)
; 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
; 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