Emit declarations before definitions if they are available. This causes DW_AT_specification to
point back in the file in the included testcase. Fixes PR11300.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@143726 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 0f4ea05..b022c43 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -194,11 +194,7 @@
DISubprogram SP(SPNode);
DISubprogram SPDecl = SP.getFunctionDeclaration();
- if (SPDecl.isSubprogram())
- // Refer function declaration directly.
- SPCU->addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
- SPCU->getOrCreateSubprogramDIE(SPDecl));
- else {
+ if (!SPDecl.isSubprogram()) {
// There is not any need to generate specification DIE for a function
// defined at compile unit level. If a function is defined inside another
// function then gdb prefers the definition at top level and but does not
@@ -512,14 +508,31 @@
/// construct SubprogramDIE - Construct subprogram DIE.
void DwarfDebug::constructSubprogramDIE(CompileUnit *TheCU,
const MDNode *N) {
+ CompileUnit *&CURef = SPMap[N];
+ if (CURef)
+ return;
+ CURef = TheCU;
+
DISubprogram SP(N);
if (!SP.isDefinition())
// This is a method declaration which will be handled while constructing
// class type.
return;
+ DISubprogram SPDecl = SP.getFunctionDeclaration();
+ DIE *DeclDie = NULL;
+ if (SPDecl.isSubprogram()) {
+ DeclDie = TheCU->getOrCreateSubprogramDIE(SPDecl);
+ }
+
DIE *SubprogramDie = TheCU->getOrCreateSubprogramDIE(SP);
+ if (DeclDie) {
+ // Refer function declaration directly.
+ TheCU->addDIEEntry(SubprogramDie, dwarf::DW_AT_specification,
+ dwarf::DW_FORM_ref4, DeclDie);
+ }
+
// Add to map.
TheCU->insertDIE(N, SubprogramDie);
@@ -529,7 +542,6 @@
// Expose as global.
TheCU->addGlobal(SP.getName(), SubprogramDie);
- SPMap[N] = TheCU;
return;
}