summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart Hastings <stuart@apple.com>2010-04-06 17:19:32 +0000
committerStuart Hastings <stuart@apple.com>2010-04-06 17:19:32 +0000
commit983327b3516faac156d7a7ce26a80e24685221f4 (patch)
tree2ad6a6f38f7fd4c65ba73c79c8967007b607c0a0
parentf77cdabb58eaf05dbec3f663c8b33d8ba1eed2db (diff)
downloadllvm-983327b3516faac156d7a7ce26a80e24685221f4.tar.gz
llvm-983327b3516faac156d7a7ce26a80e24685221f4.tar.bz2
llvm-983327b3516faac156d7a7ce26a80e24685221f4.tar.xz
Revise debug info machinery to digest nested functions and classes.
A certain GDB testsuite case (local.cc) has a function nested inside a class nested inside another function. GCC presents the innermost function to llvm-convert first. Heretofore, the debug info mistakenly placed the inner function at module scope. This patch walks the GCC context links and instantiates the outer class and function so the debug info is properly nested. Radar 7426545. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@100530 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp30
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h3
-rw-r--r--test/FrontendC++/2010-02-17-DbgArtificialArg.cpp4
3 files changed, 28 insertions, 9 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index b472d1e533..0af6b3315a 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -800,12 +800,26 @@ void DwarfDebug::addToContextOwner(DIE *Die, DIDescriptor Context) {
} else if (Context.isNameSpace()) {
DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context.getNode()));
ContextDIE->addChild(Die);
+ } else if (Context.isSubprogram()) {
+ DIE *ContextDIE = createSubprogramDIE(DISubprogram(Context.getNode()),
+ /*MakeDecl=*/false);
+ ContextDIE->addChild(Die);
} else if (DIE *ContextDIE = ModuleCU->getDIE(Context.getNode()))
ContextDIE->addChild(Die);
else
ModuleCU->addDie(Die);
}
+/// isFunctionContext - True if given Context is nested within a function.
+bool DwarfDebug::isFunctionContext(DIE *context) {
+ if (context == (DIE *)0)
+ return false;
+ if (context->getTag() == dwarf::DW_TAG_subprogram)
+ return true;
+ else
+ return isFunctionContext(context->getParent());
+}
+
/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
/// given DIType.
DIE *DwarfDebug::getOrCreateTypeDIE(DIType Ty) {
@@ -987,6 +1001,10 @@ void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
if (DIDescriptor(ContainingType.getNode()).isCompositeType())
addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
getOrCreateTypeDIE(DIType(ContainingType.getNode())));
+ else {
+ DIDescriptor Context = CTy.getContext();
+ addToContextOwner(&Buffer, Context);
+ }
break;
}
default:
@@ -1802,19 +1820,15 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
void DwarfDebug::constructSubprogramDIE(MDNode *N) {
DISubprogram SP(N);
- // Check for pre-existence.
- if (ModuleCU->getDIE(N))
- return;
-
if (!SP.isDefinition())
// This is a method declaration which will be handled while constructing
// class type.
return;
- DIE *SubprogramDie = createSubprogramDIE(SP);
-
- // Add to map.
- ModuleCU->insertDIE(N, SubprogramDie);
+ // Check for pre-existence.
+ DIE *SubprogramDie = ModuleCU->getDIE(N);
+ if (!SubprogramDie)
+ SubprogramDie = createSubprogramDIE(SP);
// Add to context owner.
addToContextOwner(SubprogramDie, SP.getContext());
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index c7baf5f5d3..6d6d02b4df 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -332,6 +332,9 @@ private:
/// addToContextOwner - Add Die into the list of its context owner's children.
void addToContextOwner(DIE *Die, DIDescriptor Context);
+ /// isFunctionContext - True if given Context is nested within a function.
+ bool isFunctionContext(DIE *context);
+
/// addType - Add a new type attribute to the specified entity.
void addType(DIE *Entity, DIType Ty);
diff --git a/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp b/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp
index 2a9f1f156b..ff45412b44 100644
--- a/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp
+++ b/test/FrontendC++/2010-02-17-DbgArtificialArg.cpp
@@ -1,4 +1,4 @@
-// RUN: %llvmgcc -g -S %s -o - | grep DW_TAG_pointer_type | grep "i32 524303, metadata .., metadata ..., metadata .., i32 ., i64 .., i64 .., i64 0, i32 64, metadata ..."
+// RUN: %llvmgcc -g -S %s -o - | FileCheck %s
// Here, second to last argument "i32 64" indicates that artificial type is set.
// Test to artificial attribute attahed to "this" pointer type.
// Radar 7655792 and 7655002
@@ -10,5 +10,7 @@ public:
int foo() {
A a;
+ // Matching "i32 64, metadata !<number>} ; [ DW_TAG_pointer_type ]"
+ // CHECK: i32 64, metadata {{![0-9]+\} ; \[ DW_TAG_pointer_type \]}}
return a.fn1(1);
}