From 4a1cad673c5bf0812099c6c8f551fe6af967c2b3 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Mon, 28 Jun 2010 18:25:03 +0000 Subject: [PATCH] Preserve deleted function's local variables' debug info. Radar 8122864. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@107027 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 35 +++++++++++++++++++++++++ lib/CodeGen/AsmPrinter/DwarfDebug.h | 4 +++ test/FrontendC/2010-06-28-DbgLocalVar.c | 14 ++++++++++ 3 files changed, 53 insertions(+) create mode 100644 test/FrontendC/2010-06-28-DbgLocalVar.c diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 92b4fef9e78..265296ade94 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1386,6 +1386,7 @@ static bool isSubprogramContext(const MDNode *Context) { /// If there are global variables in this scope then create and insert /// DIEs for these variables. DIE *DwarfDebug::updateSubprogramScopeDIE(const MDNode *SPNode) { + ProcessedSPNodes.insert(SPNode); CompileUnit *SPCU = getCompileUnit(SPNode); DIE *SPDie = SPCU->getDIE(SPNode); assert(SPDie && "Unable to find subprogram DIE!"); @@ -2005,6 +2006,40 @@ void DwarfDebug::beginModule(Module *M) { /// void DwarfDebug::endModule() { if (!FirstCU) return; + const Module *M = MMI->getModule(); + if (NamedMDNode *AllSPs = M->getNamedMetadata("llvm.dbg.sp")) { + for (unsigned SI = 0, SE = AllSPs->getNumOperands(); SI != SE; ++SI) { + if (ProcessedSPNodes.count(AllSPs->getOperand(SI)) != 0) continue; + DISubprogram SP(AllSPs->getOperand(SI)); + if (!SP.Verify()) continue; + + // Collect info for variables that were optimized out. + StringRef FName = SP.getLinkageName(); + if (FName.empty()) + FName = SP.getName(); + NamedMDNode *NMD = + M->getNamedMetadata(Twine("llvm.dbg.lv.", getRealLinkageName(FName))); + if (!NMD) continue; + unsigned E = NMD->getNumOperands(); + if (!E) continue; + DbgScope *Scope = new DbgScope(NULL, DIDescriptor(SP), NULL); + for (unsigned I = 0; I != E; ++I) { + DIVariable DV(NMD->getOperand(I)); + if (!DV.Verify()) continue; + Scope->addVariable(new DbgVariable(DV)); + } + + // Construct subprogram DIE and add variables DIEs. + constructSubprogramDIE(SP); + DIE *ScopeDIE = getCompileUnit(SP)->getDIE(SP); + const SmallVector &Variables = Scope->getVariables(); + for (unsigned i = 0, N = Variables.size(); i < N; ++i) { + DIE *VariableDIE = constructVariableDIE(Variables[i], Scope); + if (VariableDIE) + ScopeDIE->addChild(VariableDIE); + } + } + } // Attach DW_AT_inline attribute with inlined subprogram DIEs. for (SmallPtrSet::iterator AI = InlinedSubprogramDIEs.begin(), diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 43f9d17c0a4..9b3427dcaf3 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -219,6 +219,10 @@ class DwarfDebug { DenseMap > InlineInfo; SmallVector InlinedSPNodes; + // ProcessedSPNodes - This is a collection of subprogram MDNodes that + // are processed to create DIEs. + SmallPtrSet ProcessedSPNodes; + /// LabelsBeforeInsn - Maps instruction with label emitted before /// instruction. DenseMap LabelsBeforeInsn; diff --git a/test/FrontendC/2010-06-28-DbgLocalVar.c b/test/FrontendC/2010-06-28-DbgLocalVar.c new file mode 100644 index 00000000000..e5df8856c0d --- /dev/null +++ b/test/FrontendC/2010-06-28-DbgLocalVar.c @@ -0,0 +1,14 @@ +// RUN: %llvmgcc -S -O2 -g %s -o - | llc -O2 -o %t.s +// RUN: grep DW_TAG_structure_type %t.s | count 2 +// Radar 8122864 + +// Code is not generated for function foo, but preserve type information of +// local variable xyz. +static foo() { + struct X { int a; int b; } xyz; +} + +int bar() { + foo(); + return 1; +} -- 2.34.1