diff options
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 43 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h | 5 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 8 |
3 files changed, 42 insertions, 14 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 73496b0c382..4dd36830a44 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1052,24 +1052,49 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV, return findAbstractVariable(DV, ScopeLoc.getScope(DV->getContext())); } -DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV, - const MDNode *ScopeNode) { +DbgVariable *DwarfDebug::getExistingAbstractVariable(DIVariable &DV, + DIVariable &Cleansed) { LLVMContext &Ctx = DV->getContext(); // More then one inlined variable corresponds to one abstract variable. - DIVariable Var = cleanseInlinedVariable(DV, Ctx); - auto I = AbstractVariables.find(Var); + // FIXME: This duplication of variables when inlining should probably be + // removed. It's done to allow each DIVariable to describe its location + // because the DebugLoc on the dbg.value/declare isn't accurate. We should + // make it accurate then remove this duplication/cleansing stuff. + Cleansed = cleanseInlinedVariable(DV, Ctx); + auto I = AbstractVariables.find(Cleansed); if (I != AbstractVariables.end()) return I->second.get(); + return nullptr; +} - LexicalScope *Scope = LScopes.findAbstractScope(ScopeNode); - if (!Scope) - return nullptr; - +DbgVariable *DwarfDebug::createAbstractVariable(DIVariable &Var, + LexicalScope *Scope) { auto AbsDbgVariable = make_unique<DbgVariable>(Var, nullptr, this); addScopeVariable(Scope, AbsDbgVariable.get()); return (AbstractVariables[Var] = std::move(AbsDbgVariable)).get(); } +DbgVariable *DwarfDebug::getOrCreateAbstractVariable(DIVariable &DV, + const MDNode *ScopeNode) { + DIVariable Cleansed = DV; + if (DbgVariable *Var = getExistingAbstractVariable(DV, Cleansed)) + return Var; + + return createAbstractVariable(Cleansed, + LScopes.getOrCreateAbstractScope(ScopeNode)); +} + +DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV, + const MDNode *ScopeNode) { + DIVariable Cleansed = DV; + if (DbgVariable *Var = getExistingAbstractVariable(DV, Cleansed)) + return Var; + + if (LexicalScope *Scope = LScopes.findAbstractScope(ScopeNode)) + return createAbstractVariable(Cleansed, Scope); + return nullptr; +} + // If Var is a current function argument then add it to CurrentFnArguments list. bool DwarfDebug::addCurrentFnArgument(DbgVariable *Var, LexicalScope *Scope) { if (!LScopes.isCurrentFunctionScope(Scope)) @@ -1513,7 +1538,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { assert(DV && DV.isVariable()); if (!ProcessedVars.insert(DV)) continue; - findAbstractVariable(DV, DV.getContext()); + getOrCreateAbstractVariable(DV, DV.getContext()); } constructAbstractSubprogramScopeDIE(TheCU, AScope); } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h index 2d673791102..a3b0242fd5f 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -343,6 +343,11 @@ class DwarfDebug : public AsmPrinterHandler { } /// \brief Find abstract variable associated with Var. + DbgVariable *getExistingAbstractVariable(DIVariable &DV, + DIVariable &Cleansed); + DbgVariable *createAbstractVariable(DIVariable &DV, LexicalScope *Scope); + DbgVariable *getOrCreateAbstractVariable(DIVariable &Var, + const MDNode *Scope); DbgVariable *findAbstractVariable(DIVariable &Var, DebugLoc Loc); DbgVariable *findAbstractVariable(DIVariable &Var, const MDNode *Scope); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 2325ab8444e..0bac3bec389 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1782,12 +1782,10 @@ std::unique_ptr<DIE> DwarfUnit::constructVariableDIEImpl(const DbgVariable &DV, // Define variable debug information entry. auto VariableDie = make_unique<DIE>(DV.getTag()); DbgVariable *AbsVar = DV.getAbstractVariable(); - // FIXME: any missing abstract variable missing a DIE will result in incorrect - // DWARF. More details in test/DebugInfo/missing-abstract-variable.ll for an - // example of why this is happening. - if (AbsVar && AbsVar->getDIE()) + if (AbsVar) { + assert(AbsVar->getDIE()); addDIEEntry(*VariableDie, dwarf::DW_AT_abstract_origin, *AbsVar->getDIE()); - else { + } else { if (!Name.empty()) addString(*VariableDie, dwarf::DW_AT_name, Name); addSourceLine(*VariableDie, DV.getVariable()); |

