diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index d3309c1e6e8..6960ec94551 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -509,6 +509,21 @@ DwarfDebug::constructInlinedScopeDIE(DwarfCompileUnit &TheCU, return ScopeDIE; } +static std::unique_ptr constructVariableDIE(DwarfCompileUnit &TheCU, + DbgVariable &DV, + const LexicalScope &Scope, + DIE *&ObjectPointer) { + AbstractOrInlined AOI = AOI_None; + if (Scope.isAbstractScope()) + AOI = AOI_Abstract; + else if (Scope.getInlinedAt()) + AOI = AOI_Inlined; + auto Var = TheCU.constructVariableDIE(DV, AOI); + if (DV.isObjectPointer()) + ObjectPointer = Var.get(); + return Var; +} + DIE *DwarfDebug::createScopeChildrenDIE( DwarfCompileUnit &TheCU, LexicalScope *Scope, SmallVectorImpl> &Children) { @@ -517,12 +532,9 @@ DIE *DwarfDebug::createScopeChildrenDIE( // Collect arguments for current function. if (LScopes.isCurrentFunctionScope(Scope)) { for (DbgVariable *ArgDV : CurrentFnArguments) - if (ArgDV) { + if (ArgDV) Children.push_back( - TheCU.constructVariableDIE(*ArgDV, Scope->isAbstractScope())); - if (ArgDV->isObjectPointer()) - ObjectPointer = Children.back().get(); - } + constructVariableDIE(TheCU, *ArgDV, *Scope, ObjectPointer)); // If this is a variadic function, add an unspecified parameter. DISubprogram SP(Scope->getScopeNode()); @@ -535,12 +547,9 @@ DIE *DwarfDebug::createScopeChildrenDIE( } // Collect lexical scope children first. - for (DbgVariable *DV : ScopeVariables.lookup(Scope)) { - Children.push_back( - TheCU.constructVariableDIE(*DV, Scope->isAbstractScope())); - if (DV->isObjectPointer()) - ObjectPointer = Children.back().get(); - } + for (DbgVariable *DV : ScopeVariables.lookup(Scope)) + Children.push_back(constructVariableDIE(TheCU, *DV, *Scope, ObjectPointer)); + for (LexicalScope *LS : Scope->getChildren()) if (std::unique_ptr Nested = constructScopeDIE(TheCU, LS)) Children.push_back(std::move(Nested)); @@ -897,7 +906,7 @@ void DwarfDebug::collectDeadVariables() { if (!DV.isVariable()) continue; DbgVariable NewVar(DV, nullptr, this); - SPDIE->addChild(SPCU->constructVariableDIE(NewVar, false)); + SPDIE->addChild(SPCU->constructVariableDIE(NewVar)); } } } diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp index 852eda14d86..d37dcf27378 100644 --- a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1807,14 +1807,15 @@ void DwarfUnit::constructContainingTypeDIEs() { /// constructVariableDIE - Construct a DIE for the given DbgVariable. std::unique_ptr DwarfUnit::constructVariableDIE(DbgVariable &DV, - bool isScopeAbstract) { - auto D = constructVariableDIEImpl(DV, isScopeAbstract); + AbstractOrInlined AbsIn) { + auto D = constructVariableDIEImpl(DV, AbsIn); DV.setDIE(*D); return D; } -std::unique_ptr DwarfUnit::constructVariableDIEImpl(const DbgVariable &DV, - bool isScopeAbstract) { +std::unique_ptr +DwarfUnit::constructVariableDIEImpl(const DbgVariable &DV, + AbstractOrInlined AbsIn) { StringRef Name = DV.getName(); // Define variable debug information entry. @@ -1830,10 +1831,10 @@ std::unique_ptr DwarfUnit::constructVariableDIEImpl(const DbgVariable &DV, addType(*VariableDie, DV.getType()); } - if (DV.isArtificial()) + if (AbsIn != AOI_Inlined && DV.isArtificial()) addFlag(*VariableDie, dwarf::DW_AT_artificial); - if (isScopeAbstract) + if (AbsIn == AOI_Abstract) return VariableDie; // Add variable address. diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.h b/lib/CodeGen/AsmPrinter/DwarfUnit.h index cf4bc991b25..5beae1e29c4 100644 --- a/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -61,6 +61,8 @@ public: void addRange(RangeSpan Range) { Ranges.push_back(Range); } }; +enum AbstractOrInlined { AOI_None, AOI_Inlined, AOI_Abstract }; + //===----------------------------------------------------------------------===// /// Unit - This dwarf writer support class manages information associated /// with a source file. @@ -413,7 +415,7 @@ public: /// constructVariableDIE - Construct a DIE for the given DbgVariable. std::unique_ptr constructVariableDIE(DbgVariable &DV, - bool isScopeAbstract); + AbstractOrInlined AbsIn = AOI_None); /// constructSubprogramArguments - Construct function argument DIEs. DIE *constructSubprogramArguments(DIE &Buffer, DIArray Args); @@ -451,7 +453,7 @@ private: /// \brief Construct a DIE for the given DbgVariable without initializing the /// DbgVariable's DIE reference. std::unique_ptr constructVariableDIEImpl(const DbgVariable &DV, - bool isScopeAbstract); + AbstractOrInlined AbsIn); /// constructTypeDIE - Construct basic type die from DIBasicType. void constructTypeDIE(DIE &Buffer, DIBasicType BTy); diff --git a/test/DebugInfo/X86/inline-member-function.ll b/test/DebugInfo/X86/inline-member-function.ll index 791d6466719..a3fcb99c5ce 100644 --- a/test/DebugInfo/X86/inline-member-function.ll +++ b/test/DebugInfo/X86/inline-member-function.ll @@ -18,6 +18,8 @@ ; CHECK-NEXT: DW_AT_abstract_origin {{.*}}{[[ABSTRACT_ORIGIN:0x[0-9a-e]*]]} ; CHECK-NOT: NULL ; CHECK-NOT: DW_AT_object_pointer +; CHECK: DW_TAG_formal_parameter +; CHECK-NOT: DW_AT_artificial ; CHECK: DW_TAG ; But make sure we emit DW_AT_object_pointer on the declaration.