diff options
author | Stuart Hastings <stuart@apple.com> | 2010-03-31 21:10:54 +0000 |
---|---|---|
committer | Stuart Hastings <stuart@apple.com> | 2010-03-31 21:10:54 +0000 |
commit | a88cb38d0220d5b0e4394f3280e1cec5f30ef4fc (patch) | |
tree | fd74ea125af5132ea76c7a0f065c777a56e775ca /lib/CodeGen/AsmPrinter/DwarfDebug.cpp | |
parent | a0c6057061be055faa542d05b2213f2bd779e160 (diff) |
Debug info can now properly represent functions inside classes inside other functions. Partial fix for Radar 7424645.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@100048 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/AsmPrinter/DwarfDebug.cpp')
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index d81c304356..e3cf13a5d9 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -780,12 +780,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) { @@ -967,6 +981,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: @@ -1325,8 +1343,7 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) { // function then gdb prefers the definition at top level and but does not // expect specification DIE in parent function. So avoid creating // specification DIE for a function defined inside a function. - if (SP.isDefinition() && !SP.getContext().isCompileUnit() && - !SP.getContext().isFile() && !SP.getContext().isSubprogram()) { + if (SP.isDefinition() && !isFunctionContext(SPDie->getParent())) { addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); // Add arguments. @@ -1754,19 +1771,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()); |