diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp index 1bb546e54b2..580785588a7 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -372,40 +372,46 @@ void DwarfCompileUnit::addSectionDelta(DIE &Die, dwarf::Attribute Attribute, Value); } -void -DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE, - const SmallVectorImpl &Range) { +void DwarfCompileUnit::addScopeRangeList(DIE &ScopeDIE, + SmallVector Range) { // Emit offset in .debug_range as a relocatable label. emitDIE will handle // emitting it appropriately. - MCSymbol *RangeSym = - Asm->GetTempSymbol("debug_ranges", DD->getNextRangeNumber()); - auto *RangeSectionSym = DD->getRangeSectionSym(); + RangeSpanList List( + Asm->GetTempSymbol("debug_ranges", DD->getNextRangeNumber()), + std::move(Range)); + // Under fission, ranges are specified by constant offsets relative to the // CU's DW_AT_GNU_ranges_base. - if (DD->useSplitDwarf()) - addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, RangeSym, RangeSectionSym); + if (isDwoUnit()) + addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(), + RangeSectionSym); else - addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, RangeSym, RangeSectionSym); - - RangeSpanList List(RangeSym); - for (const InsnRange &R : Range) - List.addRange(RangeSpan(DD->getLabelBeforeInsn(R.first), - DD->getLabelAfterInsn(R.second))); + addSectionLabel(ScopeDIE, dwarf::DW_AT_ranges, List.getSym(), + RangeSectionSym); // Add the range list to the set of ranges to be emitted. (Skeleton ? Skeleton : this)->CURangeLists.push_back(std::move(List)); } +void DwarfCompileUnit::attachRangesOrLowHighPC( + DIE &Die, SmallVector Ranges) { + if (Ranges.size() == 1) { + const auto &single = Ranges.front(); + attachLowHighPC(Die, single.getStart(), single.getEnd()); + } else + addScopeRangeList(Die, std::move(Ranges)); +} + void DwarfCompileUnit::attachRangesOrLowHighPC( DIE &Die, const SmallVectorImpl &Ranges) { - assert(!Ranges.empty()); - if (Ranges.size() == 1) - attachLowHighPC(Die, DD->getLabelBeforeInsn(Ranges.front().first), - DD->getLabelAfterInsn(Ranges.front().second)); - else - addScopeRangeList(Die, Ranges); + SmallVector List; + List.reserve(Ranges.size()); + for (const InsnRange &R : Ranges) + List.push_back(RangeSpan(DD->getLabelBeforeInsn(R.first), + DD->getLabelAfterInsn(R.second))); + attachRangesOrLowHighPC(Die, std::move(List)); } // This scope represents inlined body of a function. Construct DIE to diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h index a73cb27c25f..1f50dbce886 100644 --- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h +++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h @@ -53,7 +53,7 @@ class DwarfCompileUnit : public DwarfUnit { SmallVector CURangeLists; // List of ranges for a given compile unit. - SmallVector CURanges; + SmallVector CURanges; // The base address of this unit, if any. Used for relative references in // ranges/locs. @@ -121,12 +121,12 @@ public: /// \brief A helper function to construct a RangeSpanList for a given /// lexical scope. - void addScopeRangeList(DIE &ScopeDIE, - const SmallVectorImpl &Range); + void addScopeRangeList(DIE &ScopeDIE, SmallVector Range); + + void attachRangesOrLowHighPC(DIE &D, SmallVector Ranges); void attachRangesOrLowHighPC(DIE &D, const SmallVectorImpl &Ranges); - /// \brief This scope represents inlined body of a function. Construct /// DIE to represent this concrete inlined copy of the function. std::unique_ptr constructInlinedScopeDIE(LexicalScope *Scope); @@ -237,6 +237,7 @@ public: /// getRanges - Get the list of ranges for this unit. const SmallVectorImpl &getRanges() const { return CURanges; } + SmallVector takeRanges() { return std::move(CURanges); } void setBaseAddress(const MCSymbol *Base) { BaseAddress = Base; } const MCSymbol *getBaseAddress() const { return BaseAddress; } diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 0da1bb8584b..9109a3bb8c7 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -578,23 +578,16 @@ void DwarfDebug::finalizeModuleInfo() { // .subsections_via_symbols in mach-o. This would mean turning on // ranges for all subprogram DIEs for mach-o. DwarfCompileUnit &U = SkCU ? *SkCU : TheCU; - unsigned NumRanges = TheCU.getRanges().size(); - if (NumRanges) { - if (NumRanges > 1) { - U.addSectionLabel(U.getUnitDie(), dwarf::DW_AT_ranges, - Asm->GetTempSymbol("cu_ranges", U.getUniqueID()), - DwarfDebugRangeSectionSym); - + if (unsigned NumRanges = TheCU.getRanges().size()) { + if (NumRanges > 1) // A DW_AT_low_pc attribute may also be specified in combination with // DW_AT_ranges to specify the default base address for use in // location lists (see Section 2.6.2) and range lists (see Section // 2.17.3). U.addUInt(U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, 0); - } else { - const RangeSpan &Range = TheCU.getRanges().back(); - TheCU.setBaseAddress(Range.getStart()); - U.attachLowHighPC(U.getUnitDie(), Range.getStart(), Range.getEnd()); - } + else + TheCU.setBaseAddress(TheCU.getRanges().front().getStart()); + U.attachRangesOrLowHighPC(U.getUnitDie(), TheCU.takeRanges()); } } @@ -1787,7 +1780,6 @@ void DwarfDebug::emitDebugLoc() { for (const auto &DebugLoc : DotDebugLocEntries) { Asm->OutStreamer.EmitLabel(DebugLoc.Label); const DwarfCompileUnit *CU = DebugLoc.CU; - assert(!CU->getRanges().empty()); for (const auto &Entry : DebugLoc.List) { // Set up the range. This range is relative to the entry point of the // compile unit. This is a hard coded 0 for low_pc when we're emitting @@ -2015,23 +2007,6 @@ void DwarfDebug::emitDebugRanges() { Asm->OutStreamer.EmitIntValue(0, Size); Asm->OutStreamer.EmitIntValue(0, Size); } - - // Now emit a range for the CU itself. - if (TheCU->getRanges().size() > 1) { - Asm->OutStreamer.EmitLabel( - Asm->GetTempSymbol("cu_ranges", TheCU->getUniqueID())); - for (const RangeSpan &Range : TheCU->getRanges()) { - const MCSymbol *Begin = Range.getStart(); - const MCSymbol *End = Range.getEnd(); - assert(Begin && "Range without a begin symbol?"); - assert(End && "Range without an end symbol?"); - Asm->OutStreamer.EmitSymbolValue(Begin, Size); - Asm->OutStreamer.EmitSymbolValue(End, Size); - } - // And terminate the list with two 0 values. - Asm->OutStreamer.EmitIntValue(0, Size); - Asm->OutStreamer.EmitIntValue(0, Size); - } } } diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.h b/lib/CodeGen/AsmPrinter/DwarfUnit.h index 141d22b735c..bd31ea4a32d 100644 --- a/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -55,7 +55,8 @@ private: SmallVector Ranges; public: - RangeSpanList(MCSymbol *Sym) : RangeSym(Sym) {} + RangeSpanList(MCSymbol *Sym, SmallVector Ranges) + : RangeSym(Sym), Ranges(std::move(Ranges)) {} MCSymbol *getSym() const { return RangeSym; } const SmallVectorImpl &getRanges() const { return Ranges; } void addRange(RangeSpan Range) { Ranges.push_back(Range); }