mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-29 13:32:33 +00:00
DebugInfo: Ensure concrete out of line variables from inlined functions reference their abstract origins.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@209327 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
fd0096a42c
commit
30436451e2
@ -1024,6 +1024,7 @@ void DwarfDebug::endModule() {
|
||||
|
||||
// clean up.
|
||||
SPMap.clear();
|
||||
AbstractVariables.clear();
|
||||
|
||||
// Reset these for the next Module if we have one.
|
||||
FirstCU = nullptr;
|
||||
@ -1032,21 +1033,25 @@ void DwarfDebug::endModule() {
|
||||
// Find abstract variable, if any, associated with Var.
|
||||
DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV,
|
||||
DebugLoc ScopeLoc) {
|
||||
return findAbstractVariable(DV, ScopeLoc.getScope(DV->getContext()));
|
||||
}
|
||||
|
||||
DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV,
|
||||
const MDNode *ScopeNode) {
|
||||
LLVMContext &Ctx = DV->getContext();
|
||||
// More then one inlined variable corresponds to one abstract variable.
|
||||
DIVariable Var = cleanseInlinedVariable(DV, Ctx);
|
||||
DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var);
|
||||
if (AbsDbgVariable)
|
||||
return AbsDbgVariable;
|
||||
auto I = AbstractVariables.find(Var);
|
||||
if (I != AbstractVariables.end())
|
||||
return I->second.get();
|
||||
|
||||
LexicalScope *Scope = LScopes.findAbstractScope(ScopeLoc.getScope(Ctx));
|
||||
LexicalScope *Scope = LScopes.findAbstractScope(ScopeNode);
|
||||
if (!Scope)
|
||||
return nullptr;
|
||||
|
||||
AbsDbgVariable = new DbgVariable(Var, nullptr, this);
|
||||
addScopeVariable(Scope, AbsDbgVariable);
|
||||
AbstractVariables[Var] = AbsDbgVariable;
|
||||
return AbsDbgVariable;
|
||||
auto AbsDbgVariable = make_unique<DbgVariable>(Var, nullptr, this);
|
||||
addScopeVariable(Scope, AbsDbgVariable.get());
|
||||
return (AbstractVariables[Var] = std::move(AbsDbgVariable)).get();
|
||||
}
|
||||
|
||||
// If Var is a current function argument then add it to CurrentFnArguments list.
|
||||
@ -1226,7 +1231,10 @@ DwarfDebug::collectVariableInfo(SmallPtrSet<const MDNode *, 16> &Processed) {
|
||||
if (!Processed.insert(DV))
|
||||
continue;
|
||||
if (LexicalScope *Scope = LScopes.findLexicalScope(DV.getContext()))
|
||||
addScopeVariable(Scope, new DbgVariable(DV, nullptr, this));
|
||||
addScopeVariable(
|
||||
Scope,
|
||||
new DbgVariable(DV, findAbstractVariable(DV, Scope->getScopeNode()),
|
||||
this));
|
||||
}
|
||||
}
|
||||
|
||||
@ -1516,14 +1524,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
|
||||
assert(DV && DV.isVariable());
|
||||
if (!ProcessedVars.insert(DV))
|
||||
continue;
|
||||
// Check that DbgVariable for DV wasn't created earlier, when
|
||||
// findAbstractVariable() was called for inlined instance of DV.
|
||||
LLVMContext &Ctx = DV->getContext();
|
||||
DIVariable CleanDV = cleanseInlinedVariable(DV, Ctx);
|
||||
if (AbstractVariables.lookup(CleanDV))
|
||||
continue;
|
||||
if (LexicalScope *Scope = LScopes.findAbstractScope(DV.getContext()))
|
||||
addScopeVariable(Scope, new DbgVariable(DV, nullptr, this));
|
||||
findAbstractVariable(DV, DV.getContext());
|
||||
}
|
||||
constructAbstractSubprogramScopeDIE(TheCU, AScope);
|
||||
}
|
||||
@ -1539,12 +1540,16 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
|
||||
PrevCU = &TheCU;
|
||||
|
||||
// Clear debug info
|
||||
for (auto &I : ScopeVariables)
|
||||
DeleteContainerPointers(I.second);
|
||||
// Ownership of DbgVariables is a bit subtle - ScopeVariables owns all the
|
||||
// DbgVariables except those that are also in AbstractVariables (since they
|
||||
// can be used cross-function)
|
||||
for (const auto &I : ScopeVariables)
|
||||
for (const auto *Var : I.second)
|
||||
if (!AbstractVariables.count(Var->getVariable()) || Var->getAbstractVariable())
|
||||
delete Var;
|
||||
ScopeVariables.clear();
|
||||
DeleteContainerPointers(CurrentFnArguments);
|
||||
DbgValues.clear();
|
||||
AbstractVariables.clear();
|
||||
LabelsBeforeInsn.clear();
|
||||
LabelsAfterInsn.clear();
|
||||
PrevLabel = nullptr;
|
||||
|
@ -199,7 +199,7 @@ class DwarfDebug : public AsmPrinterHandler {
|
||||
ScopeVariablesMap ScopeVariables;
|
||||
|
||||
// Collection of abstract variables.
|
||||
DenseMap<const MDNode *, DbgVariable *> AbstractVariables;
|
||||
DenseMap<const MDNode *, std::unique_ptr<DbgVariable>> AbstractVariables;
|
||||
|
||||
// Collection of DebugLocEntry. Stored in a linked list so that DIELocLists
|
||||
// can refer to them in spite of insertions into this list.
|
||||
@ -336,6 +336,7 @@ class DwarfDebug : public AsmPrinterHandler {
|
||||
|
||||
/// \brief Find abstract variable associated with Var.
|
||||
DbgVariable *findAbstractVariable(DIVariable &Var, DebugLoc Loc);
|
||||
DbgVariable *findAbstractVariable(DIVariable &Var, const MDNode *Scope);
|
||||
|
||||
/// \brief Find DIE for the given subprogram and attach appropriate
|
||||
/// DW_AT_low_pc and DW_AT_high_pc attributes. If there are global
|
||||
|
@ -39,6 +39,8 @@
|
||||
; CHECK-NEXT: DW_AT_specification {{.*}} {[[DTOR_DECL]]}
|
||||
; CHECK-NEXT: DW_AT_inline
|
||||
; CHECK-NOT: DW_AT_inline
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: [[D1_THIS_ABS:0x........]]: DW_TAG_formal_parameter
|
||||
; CHECK: [[D2_ABS]]: DW_TAG_subprogram
|
||||
; CHECK-NEXT: DW_AT_{{.*}}linkage_name
|
||||
; CHECK-NEXT: DW_AT_specification {{.*}} {[[DTOR_DECL]]}
|
||||
@ -52,6 +54,7 @@
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[D1_ABS]]}
|
||||
; CHECK: DW_TAG_formal_parameter
|
||||
; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[D1_THIS_ABS]]}
|
||||
; CHECK: DW_TAG_inlined_subroutine
|
||||
; CHECK-NEXT: DW_AT_abstract_origin {{.*}} {[[D2_ABS]]}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user