Index: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h +++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFContext.h @@ -58,7 +58,7 @@ /// information parsing. The actual data is supplied through DWARFObj. class DWARFContext : public DIContext { DWARFUnitSection CUs; - std::deque TUs; + DWARFUnitSection TUs; std::unique_ptr CUIndex; std::unique_ptr GdbIndex; std::unique_ptr TUIndex; @@ -76,7 +76,7 @@ std::unique_ptr AppleObjC; DWARFUnitSection DWOCUs; - std::deque DWOTUs; + DWARFUnitSection DWOTUs; std::unique_ptr AbbrevDWO; std::unique_ptr LocDWO; @@ -141,7 +141,6 @@ using cu_iterator_range = DWARFUnitSection::iterator_range; using tu_iterator_range = DWARFUnitSection::iterator_range; - using tu_section_iterator_range = iterator_range; /// Get compile units in this context. cu_iterator_range compile_units() { @@ -150,9 +149,9 @@ } /// Get type units in this context. - tu_section_iterator_range type_unit_sections() { + tu_iterator_range type_units() { parseTypeUnits(); - return tu_section_iterator_range(TUs.begin(), TUs.end()); + return tu_iterator_range(TUs.begin(), TUs.end()); } /// Get compile units in the DWO context. @@ -162,9 +161,9 @@ } /// Get type units in the DWO context. - tu_section_iterator_range dwo_type_unit_sections() { + tu_iterator_range dwo_type_units() { parseDWOTypeUnits(); - return tu_section_iterator_range(DWOTUs.begin(), DWOTUs.end()); + return tu_iterator_range(DWOTUs.begin(), DWOTUs.end()); } /// Get the number of compile units in this context. Index: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -279,7 +279,7 @@ class SectionParser { public: using cu_range = DWARFUnitSection::iterator_range; - using tu_range = iterator_range::iterator>; + using tu_range = DWARFUnitSection::iterator_range; using LineToUnitMap = std::map; SectionParser(DWARFDataExtractor &Data, const DWARFContext &C, cu_range CUs, Index: llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h =================================================================== --- llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ llvm/trunk/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -106,8 +106,8 @@ /// Describes one section's Units. class DWARFUnitSection final : public SmallVector, 1> { - bool Parsed = false; - std::function(uint32_t)> Parser; + std::function(uint32_t, const DWARFSection *)> + Parser; public: using UnitVector = SmallVectorImpl>; @@ -116,16 +116,18 @@ DWARFUnit *getUnitForOffset(uint32_t Offset) const; DWARFUnit *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E); - void parse(DWARFContext &C, const DWARFSection &Section, - DWARFSectionKind SectionKind); - void parseDWO(DWARFContext &C, const DWARFSection &DWOSection, - DWARFSectionKind SectionKind, bool Lazy = false); + void addUnitsForSection(DWARFContext &C, const DWARFSection &Section, + DWARFSectionKind SectionKind); + void addUnitsForDWOSection(DWARFContext &C, const DWARFSection &DWOSection, + DWARFSectionKind SectionKind, bool Lazy = false); + private: - void parseImpl(DWARFContext &Context, const DWARFObject &Obj, - const DWARFSection &Section, const DWARFDebugAbbrev *DA, - const DWARFSection *RS, StringRef SS, const DWARFSection &SOS, - const DWARFSection *AOS, const DWARFSection &LS, bool LE, - bool IsDWO, bool Lazy, DWARFSectionKind SectionKind); + void addUnitsImpl(DWARFContext &Context, const DWARFObject &Obj, + const DWARFSection &Section, const DWARFDebugAbbrev *DA, + const DWARFSection *RS, StringRef SS, + const DWARFSection &SOS, const DWARFSection *AOS, + const DWARFSection &LS, bool LE, bool IsDWO, bool Lazy, + DWARFSectionKind SectionKind); }; /// Represents base address of the CU. Index: llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -100,14 +100,12 @@ // sort them by their starting offsets and remove duplicates. static ContributionCollection collectContributionData(DWARFContext::cu_iterator_range CUs, - DWARFContext::tu_section_iterator_range TUSs) { + DWARFContext::tu_iterator_range TUs) { ContributionCollection Contributions; for (const auto &CU : CUs) Contributions.push_back(CU->getStringOffsetsTableContribution()); - for (const auto &TUS : TUSs) - for (const auto &TU : TUS) - Contributions.push_back(TU->getStringOffsetsTableContribution()); - + for (const auto &TU : TUs) + Contributions.push_back(TU->getStringOffsetsTableContribution()); // Sort the contributions so that any invalid ones are placed at // the start of the contributions vector. This way they are reported // first. @@ -136,9 +134,9 @@ static void dumpDWARFv5StringOffsetsSection( raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj, const DWARFSection &StringOffsetsSection, StringRef StringSection, - DWARFContext::cu_iterator_range CUs, - DWARFContext::tu_section_iterator_range TUSs, bool LittleEndian) { - auto Contributions = collectContributionData(CUs, TUSs); + DWARFContext::cu_iterator_range CUs, DWARFContext::tu_iterator_range TUs, + bool LittleEndian) { + auto Contributions = collectContributionData(CUs, TUs); DWARFDataExtractor StrOffsetExt(Obj, StringOffsetsSection, LittleEndian, 0); DataExtractor StrData(StringSection, LittleEndian, 0); uint64_t SectionSize = StringOffsetsSection.Data.size(); @@ -215,18 +213,19 @@ // a header containing size and version number. Alternatively, it may be a // monolithic series of string offsets, as generated by the pre-DWARF v5 // implementation of split DWARF. -static void dumpStringOffsetsSection( - raw_ostream &OS, StringRef SectionName, const DWARFObject &Obj, - const DWARFSection &StringOffsetsSection, StringRef StringSection, - DWARFContext::cu_iterator_range CUs, - DWARFContext::tu_section_iterator_range TUSs, bool LittleEndian, - unsigned MaxVersion) { +static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName, + const DWARFObject &Obj, + const DWARFSection &StringOffsetsSection, + StringRef StringSection, + DWARFContext::cu_iterator_range CUs, + DWARFContext::tu_iterator_range TUs, + bool LittleEndian, unsigned MaxVersion) { // If we have at least one (compile or type) unit with DWARF v5 or greater, // we assume that the section is formatted like a DWARF v5 string offsets // section. if (MaxVersion >= 5) dumpDWARFv5StringOffsetsSection(OS, SectionName, Obj, StringOffsetsSection, - StringSection, CUs, TUSs, LittleEndian); + StringSection, CUs, TUs, LittleEndian); else { DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0); uint32_t offset = 0; @@ -356,23 +355,21 @@ dumpDebugInfo(ExplicitDWO, ".debug_info.dwo", DObj->getInfoDWOSection(), dwo_compile_units()); - auto dumpDebugType = [&](const char *Name, - tu_section_iterator_range TUSections) { + auto dumpDebugType = [&](const char *Name, tu_iterator_range TUs) { OS << '\n' << Name << " contents:\n"; DumpOffset = DumpOffsets[DIDT_ID_DebugTypes]; - for (const auto &TUS : TUSections) - for (const auto &TU : TUS) - if (DumpOffset) - TU->getDIEForOffset(*DumpOffset) - .dump(OS, 0, DumpOpts.noImplicitRecursion()); - else - TU->dump(OS, DumpOpts); + for (const auto &TU : TUs) + if (DumpOffset) + TU->getDIEForOffset(*DumpOffset) + .dump(OS, 0, DumpOpts.noImplicitRecursion()); + else + TU->dump(OS, DumpOpts); }; if ((DumpType & DIDT_DebugTypes)) { if (Explicit || getNumTypeUnits()) - dumpDebugType(".debug_types", type_unit_sections()); + dumpDebugType(".debug_types", type_units()); if (ExplicitDWO || getNumDWOTypeUnits()) - dumpDebugType(".debug_types.dwo", dwo_type_unit_sections()); + dumpDebugType(".debug_types.dwo", dwo_type_units()); } if (shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc, @@ -430,7 +427,7 @@ DWARFDataExtractor LineData(*DObj, DObj->getLineSection(), isLittleEndian(), 0); DWARFDebugLine::SectionParser Parser(LineData, *this, compile_units(), - type_unit_sections()); + type_units()); DumpLineSection(Parser, DumpOpts); } @@ -439,7 +436,7 @@ DWARFDataExtractor LineData(*DObj, DObj->getLineDWOSection(), isLittleEndian(), 0); DWARFDebugLine::SectionParser Parser(LineData, *this, dwo_compile_units(), - dwo_type_unit_sections()); + dwo_type_units()); DumpLineSection(Parser, DumpOpts); } @@ -547,16 +544,16 @@ if (shouldDump(Explicit, ".debug_str_offsets", DIDT_ID_DebugStrOffsets, DObj->getStringOffsetSection().Data)) - dumpStringOffsetsSection( - OS, "debug_str_offsets", *DObj, DObj->getStringOffsetSection(), - DObj->getStringSection(), compile_units(), type_unit_sections(), - isLittleEndian(), getMaxVersion()); + dumpStringOffsetsSection(OS, "debug_str_offsets", *DObj, + DObj->getStringOffsetSection(), + DObj->getStringSection(), compile_units(), + type_units(), isLittleEndian(), getMaxVersion()); if (shouldDump(ExplicitDWO, ".debug_str_offsets.dwo", DIDT_ID_DebugStrOffsets, DObj->getStringOffsetDWOSection().Data)) dumpStringOffsetsSection( OS, "debug_str_offsets.dwo", *DObj, DObj->getStringOffsetDWOSection(), - DObj->getStringDWOSection(), dwo_compile_units(), - dwo_type_unit_sections(), isLittleEndian(), getMaxVersion()); + DObj->getStringDWOSection(), dwo_compile_units(), dwo_type_units(), + isLittleEndian(), getMaxVersion()); if (shouldDump(Explicit, ".gnu_index", DIDT_ID_GdbIndex, DObj->getGdbIndexSection())) { @@ -584,7 +581,9 @@ } DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) { - DWOCUs.parseDWO(*this, DObj->getInfoDWOSection(), DW_SECT_INFO, true); + if (DWOCUs.empty()) + DWOCUs.addUnitsForDWOSection(*this, DObj->getInfoDWOSection(), DW_SECT_INFO, + true); if (const auto &CUI = getCUIndex()) { if (const auto *R = CUI.getFromHash(Hash)) @@ -844,28 +843,30 @@ } void DWARFContext::parseCompileUnits() { - CUs.parse(*this, DObj->getInfoSection(), DW_SECT_INFO); + if (!CUs.empty()) + return; + CUs.addUnitsForSection(*this, DObj->getInfoSection(), DW_SECT_INFO); } void DWARFContext::parseTypeUnits() { if (!TUs.empty()) return; DObj->forEachTypesSections([&](const DWARFSection &S) { - TUs.emplace_back(); - TUs.back().parse(*this, S, DW_SECT_TYPES); + TUs.addUnitsForSection(*this, S, DW_SECT_TYPES); }); } void DWARFContext::parseDWOCompileUnits() { - DWOCUs.parseDWO(*this, DObj->getInfoDWOSection(), DW_SECT_INFO); + if (!DWOCUs.empty()) + return; + DWOCUs.addUnitsForDWOSection(*this, DObj->getInfoDWOSection(), DW_SECT_INFO); } void DWARFContext::parseDWOTypeUnits() { if (!DWOTUs.empty()) return; DObj->forEachTypesDWOSections([&](const DWARFSection &S) { - DWOTUs.emplace_back(); - DWOTUs.back().parseDWO(*this, S, DW_SECT_TYPES); + DWOTUs.addUnitsForDWOSection(*this, S, DW_SECT_TYPES); }); } Index: llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLine.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -1047,17 +1047,16 @@ // line-table section. static DWARFDebugLine::SectionParser::LineToUnitMap buildLineToUnitMap(DWARFDebugLine::SectionParser::cu_range CUs, - DWARFDebugLine::SectionParser::tu_range TUSections) { + DWARFDebugLine::SectionParser::tu_range TUs) { DWARFDebugLine::SectionParser::LineToUnitMap LineToUnit; for (const auto &CU : CUs) if (auto CUDIE = CU->getUnitDIE()) if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list))) LineToUnit.insert(std::make_pair(*StmtOffset, &*CU)); - for (const auto &TUS : TUSections) - for (const auto &TU : TUS) - if (auto TUDIE = TU->getUnitDIE()) - if (auto StmtOffset = toSectionOffset(TUDIE.find(DW_AT_stmt_list))) - LineToUnit.insert(std::make_pair(*StmtOffset, &*TU)); + for (const auto &TU : TUs) + if (auto TUDIE = TU->getUnitDIE()) + if (auto StmtOffset = toSectionOffset(TUDIE.find(DW_AT_stmt_list))) + LineToUnit.insert(std::make_pair(*StmtOffset, &*TU)); return LineToUnit; } Index: llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp +++ llvm/trunk/lib/DebugInfo/DWARF/DWARFUnit.cpp @@ -33,40 +33,43 @@ using namespace llvm; using namespace dwarf; -void DWARFUnitSection::parse(DWARFContext &C, const DWARFSection &Section, - DWARFSectionKind SectionKind) { +void DWARFUnitSection::addUnitsForSection(DWARFContext &C, + const DWARFSection &Section, + DWARFSectionKind SectionKind) { const DWARFObject &D = C.getDWARFObj(); - parseImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangeSection(), - D.getStringSection(), D.getStringOffsetSection(), - &D.getAddrSection(), D.getLineSection(), D.isLittleEndian(), false, - false, SectionKind); + addUnitsImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangeSection(), + D.getStringSection(), D.getStringOffsetSection(), + &D.getAddrSection(), D.getLineSection(), D.isLittleEndian(), + false, false, SectionKind); } -void DWARFUnitSection::parseDWO(DWARFContext &C, - const DWARFSection &DWOSection, - DWARFSectionKind SectionKind, bool Lazy) { +void DWARFUnitSection::addUnitsForDWOSection(DWARFContext &C, + const DWARFSection &DWOSection, + DWARFSectionKind SectionKind, + bool Lazy) { const DWARFObject &D = C.getDWARFObj(); - parseImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(), - D.getStringDWOSection(), D.getStringOffsetDWOSection(), - &D.getAddrSection(), D.getLineDWOSection(), C.isLittleEndian(), - true, Lazy, SectionKind); + addUnitsImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(), + D.getStringDWOSection(), D.getStringOffsetDWOSection(), + &D.getAddrSection(), D.getLineDWOSection(), C.isLittleEndian(), + true, Lazy, SectionKind); } -void DWARFUnitSection::parseImpl(DWARFContext &Context, const DWARFObject &Obj, - const DWARFSection &Section, const DWARFDebugAbbrev *DA, - const DWARFSection *RS, StringRef SS, const DWARFSection &SOS, - const DWARFSection *AOS, const DWARFSection &LS, bool LE, - bool IsDWO, bool Lazy, DWARFSectionKind SectionKind) { - if (Parsed) - return; +void DWARFUnitSection::addUnitsImpl( + DWARFContext &Context, const DWARFObject &Obj, const DWARFSection &Section, + const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS, + const DWARFSection &SOS, const DWARFSection *AOS, const DWARFSection &LS, + bool LE, bool IsDWO, bool Lazy, DWARFSectionKind SectionKind) { DWARFDataExtractor Data(Obj, Section, LE, 0); // Lazy initialization of Parser, now that we have all section info. if (!Parser) { const DWARFUnitIndex *Index = nullptr; if (IsDWO) Index = &getDWARFUnitIndex(Context, SectionKind); - Parser = [=, &Context, &Section, &SOS, - &LS](uint32_t Offset) -> std::unique_ptr { + Parser = [=, &Context, &Obj, &Section, &SOS, &LS]( + uint32_t Offset, + const DWARFSection *CurSection) -> std::unique_ptr { + const DWARFSection &InfoSection = CurSection ? *CurSection : Section; + DWARFDataExtractor Data(Obj, InfoSection, LE, 0); if (!Data.isValidOffset(Offset)) return nullptr; DWARFUnitHeader Header; @@ -74,13 +77,13 @@ return nullptr; std::unique_ptr U; if (Header.isTypeUnit()) - U = llvm::make_unique( - Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, - *this); + U = llvm::make_unique(Context, InfoSection, Header, DA, + RS, SS, SOS, AOS, LS, LE, IsDWO, + *this); else - U = llvm::make_unique( - Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, - *this); + U = llvm::make_unique(Context, InfoSection, Header, + DA, RS, SS, SOS, AOS, LS, LE, + IsDWO, *this); return U; }; } @@ -93,13 +96,12 @@ ++I; continue; } - auto U = Parser(Offset); + auto U = Parser(Offset, &Section); if (!U) break; Offset = U->getNextUnitOffset(); I = std::next(this->insert(I, std::move(U))); } - Parsed = true; } DWARFUnit *DWARFUnitSection::getUnitForOffset(uint32_t Offset) const { @@ -132,7 +134,7 @@ if (!Parser) return nullptr; - auto U = Parser(Offset); + auto U = Parser(Offset, nullptr); if (!U) U = nullptr; Index: llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp =================================================================== --- llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp +++ llvm/trunk/unittests/DebugInfo/DWARF/DWARFDebugLineTest.cpp @@ -130,7 +130,7 @@ std::function RecordUnrecoverable; SmallVector, 2> CUs; - std::deque TUs; + SmallVector, 2> TUs; }; // Fixtures must derive from "Test", but parameterised fixtures from