Index: lib/CodeGen/AsmPrinter/DwarfDebug.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.h +++ lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -184,6 +184,38 @@ } }; +//===----------------------------------------------------------------------===// +/// This class is used to track label information. +/// +/// Labels can be created from \c DBG_LABEL instructions. +class DbgLabel { + const DILabel *Label; /// Label Descriptor. + const MCSymbol *Sym; /// Symbol before DBG_LABEL instruction. + DIE *TheDIE = nullptr; /// Label DIE. + +public: + // We need MCSymbol information to generate DW_AT_low_pc. + DbgLabel(const DILabel *V, const MCSymbol *Sym) + : Label(V), Sym(Sym) {} + + // Accessors. + const DILabel *getLabel() const { return Label; } + const MCSymbol *getSymbol() const { return Sym; } + void setDIE(DIE &D) { TheDIE = &D; } + DIE *getDIE() const { return TheDIE; } + StringRef getName() const { return Label->getName(); } + + // Translate tag to proper Dwarf tag. + dwarf::Tag getTag() const { + return dwarf::DW_TAG_label; + } + +private: + template T *resolve(TypedDINodeRef Ref) const { + return Ref.resolve(); + } +}; + /// Helper used to pair up a symbol and its DWARF compile unit. struct SymbolCU { SymbolCU(DwarfCompileUnit *CU, const MCSymbol *Sym) : Sym(Sym), CU(CU) {} @@ -212,6 +244,9 @@ /// Collection of abstract variables. SmallVector, 64> ConcreteVariables; + /// Collection of abstract labels. + SmallVector, 64> GotoLabels; + /// Collection of DebugLocEntry. Stored in a linked list so that DIELocLists /// can refer to them in spite of insertions into this list. DebugLocStream DebugLocs; @@ -327,6 +362,11 @@ DbgVariable *createConcreteVariable(DwarfCompileUnit &TheCU, LexicalScope &Scope, InlinedVariable IV); + /// Convert InlinedLabel to DWARF-related DbgLabel. + DbgLabel *createGotoLabel(DwarfCompileUnit &TheCU, + LexicalScope &Scope, + InlinedLabel IL); + /// Construct a DIE for this abstract scope. void constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU, LexicalScope *Scope); @@ -439,6 +479,9 @@ void collectVariableInfo(DwarfCompileUnit &TheCU, const DISubprogram *SP, DenseSet &ProcessedVars); + /// Populate LexicalScope entries with labels' info. + void collectLabelInfo(DwarfCompileUnit &TheCU); + /// Build the location list for all DBG_VALUEs in the /// function that describe the same variable. void buildLocationList(SmallVectorImpl &DebugLoc, Index: lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -1073,6 +1073,16 @@ return ConcreteVariables.back().get(); } +DbgLabel *DwarfDebug::createGotoLabel(DwarfCompileUnit &TheCU, + LexicalScope &Scope, + InlinedLabel IL) { + LabelInfo LInfo = IL.second; + MCSymbol *Sym = getLabelBeforeInsn(LInfo.second); + GotoLabels.push_back(make_unique(IL.first, Sym)); + InfoHolder.addScopeLabel(&Scope, GotoLabels.back().get()); + return GotoLabels.back().get(); +} + /// Determine whether a *singular* DBG_VALUE is valid for the entirety of its /// enclosing lexical scope. The check ensures there are no other instructions /// in the same lexical scope preceding the DBG_VALUE and that its range is @@ -1196,6 +1206,25 @@ } } +// Find labels for each lexical scope. +void DwarfDebug::collectLabelInfo(DwarfCompileUnit &TheCU) { + // For each InlinedLabel collected from MI instructions, convert to + // DWARF-related DbgLabel. + for (const auto &I : DbgLabels) { + LexicalScope *Scope = nullptr; + LabelInfo LInfo = I.second; + if (const DILocation *IA = LInfo.first) + Scope = LScopes.findInlinedScope(I.first->getScope(), IA); + else + Scope = LScopes.findLexicalScope(I.first->getScope()); + // If label scope is not found then skip this label. + if (!Scope) + continue; + + createGotoLabel(TheCU, *Scope, I); + } +} + // Process beginning of an instruction. void DwarfDebug::beginInstruction(const MachineInstr *MI) { DebugHandlerBase::beginInstruction(MI); @@ -1352,6 +1381,8 @@ DenseSet ProcessedVars; collectVariableInfo(TheCU, SP, ProcessedVars); + collectLabelInfo(TheCU); + // Add the range of this function to the list of ranges for the CU. TheCU.addRange(RangeSpan(Asm->getFunctionBegin(), Asm->getFunctionEnd())); @@ -1397,6 +1428,7 @@ // DbgVariables except those that are also in AbstractVariables (since they // can be used cross-function) InfoHolder.getScopeVariables().clear(); + InfoHolder.getScopeLabels().clear(); PrevLabel = nullptr; CurFn = nullptr; } Index: lib/CodeGen/AsmPrinter/DwarfFile.h =================================================================== --- lib/CodeGen/AsmPrinter/DwarfFile.h +++ lib/CodeGen/AsmPrinter/DwarfFile.h @@ -25,6 +25,7 @@ class AsmPrinter; class DbgVariable; +class DbgLabel; class DwarfCompileUnit; class DwarfUnit; class LexicalScope; @@ -58,6 +59,9 @@ /// Collection of DbgVariables of each lexical scope. DenseMap ScopeVariables; + // Collection of dbg labels of a scope. + DenseMap> ScopeLabels; + // Collection of abstract subprogram DIEs. DenseMap AbstractSPDies; DenseMap> AbstractVariables; @@ -117,10 +121,16 @@ /// \returns false if the variable was merged with a previous one. bool addScopeVariable(LexicalScope *LS, DbgVariable *Var); + void addScopeLabel(LexicalScope *LS, DbgLabel *Label); + DenseMap &getScopeVariables() { return ScopeVariables; } + DenseMap> &getScopeLabels() { + return ScopeLabels; + } + DenseMap &getAbstractSPDies() { return AbstractSPDies; } Index: lib/CodeGen/AsmPrinter/DwarfFile.cpp =================================================================== --- lib/CodeGen/AsmPrinter/DwarfFile.cpp +++ lib/CodeGen/AsmPrinter/DwarfFile.cpp @@ -118,3 +118,8 @@ } return true; } + +void DwarfFile::addScopeLabel(LexicalScope *LS, DbgLabel *Label) { + SmallVectorImpl &Labels = ScopeLabels[LS]; + Labels.push_back(Label); +}