Index: llvm/trunk/lib/DebugInfo/DWARFContext.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/DWARFContext.cpp +++ llvm/trunk/lib/DebugInfo/DWARFContext.cpp @@ -314,84 +314,28 @@ } void DWARFContext::parseCompileUnits() { - if (!CUs.empty()) - return; - uint32_t offset = 0; - const DataExtractor &DIData = DataExtractor(getInfoSection().Data, - isLittleEndian(), 0); - while (DIData.isValidOffset(offset)) { - std::unique_ptr CU(new DWARFCompileUnit(*this, - getDebugAbbrev(), getInfoSection().Data, getRangeSection(), - getStringSection(), StringRef(), getAddrSection(), - &getInfoSection().Relocs, isLittleEndian(), CUs)); - if (!CU->extract(DIData, &offset)) { - break; - } - CUs.push_back(std::move(CU)); - offset = CUs.back()->getNextUnitOffset(); - } + CUs.parse(*this, getInfoSection().Data, getInfoSection().Relocs); } void DWARFContext::parseTypeUnits() { if (!TUs.empty()) return; for (const auto &I : getTypesSections()) { - uint32_t offset = 0; - const DataExtractor &DIData = - DataExtractor(I.second.Data, isLittleEndian(), 0); TUs.push_back(DWARFUnitSection()); - auto &TUS = TUs.back(); - while (DIData.isValidOffset(offset)) { - std::unique_ptr TU(new DWARFTypeUnit(*this, - getDebugAbbrev(), I.second.Data, getRangeSection(), - getStringSection(), StringRef(), getAddrSection(), - &I.second.Relocs, isLittleEndian(), TUS)); - if (!TU->extract(DIData, &offset)) - break; - TUS.push_back(std::move(TU)); - offset = TUS.back()->getNextUnitOffset(); - } + TUs.back().parse(*this, I.second.Data, I.second.Relocs); } } void DWARFContext::parseDWOCompileUnits() { - if (!DWOCUs.empty()) - return; - uint32_t offset = 0; - const DataExtractor &DIData = - DataExtractor(getInfoDWOSection().Data, isLittleEndian(), 0); - while (DIData.isValidOffset(offset)) { - std::unique_ptr DWOCU(new DWARFCompileUnit(*this, - getDebugAbbrevDWO(), getInfoDWOSection().Data, getRangeDWOSection(), - getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(), - &getInfoDWOSection().Relocs, isLittleEndian(), DWOCUs)); - if (!DWOCU->extract(DIData, &offset)) { - break; - } - DWOCUs.push_back(std::move(DWOCU)); - offset = DWOCUs.back()->getNextUnitOffset(); - } + DWOCUs.parseDWO(*this, getInfoDWOSection().Data, getInfoDWOSection().Relocs); } void DWARFContext::parseDWOTypeUnits() { if (!DWOTUs.empty()) return; for (const auto &I : getTypesDWOSections()) { - uint32_t offset = 0; - const DataExtractor &DIData = - DataExtractor(I.second.Data, isLittleEndian(), 0); DWOTUs.push_back(DWARFUnitSection()); - auto &TUS = DWOTUs.back(); - while (DIData.isValidOffset(offset)) { - std::unique_ptr TU(new DWARFTypeUnit(*this, - getDebugAbbrevDWO(), I.second.Data, getRangeDWOSection(), - getStringDWOSection(), getStringOffsetDWOSection(), getAddrSection(), - &I.second.Relocs, isLittleEndian(), TUS)); - if (!TU->extract(DIData, &offset)) - break; - TUS.push_back(std::move(TU)); - offset = TUS.back()->getNextUnitOffset(); - } + DWOTUs.back().parseDWO(*this, I.second.Data, I.second.Relocs); } } Index: llvm/trunk/lib/DebugInfo/DWARFUnit.h =================================================================== --- llvm/trunk/lib/DebugInfo/DWARFUnit.h +++ llvm/trunk/lib/DebugInfo/DWARFUnit.h @@ -36,7 +36,15 @@ /// same section this Unit originated from. virtual DWARFUnit *getUnitForOffset(uint32_t Offset) const = 0; + void parse(DWARFContext &C, StringRef SectionData, const RelocAddrMap &Map); + void parseDWO(DWARFContext &C, StringRef SectionData, const RelocAddrMap &Map); + protected: + virtual void parseImpl(DWARFContext &Context, const DWARFDebugAbbrev *DA, + StringRef Section, StringRef RS, StringRef SS, + StringRef SOS, StringRef AOS, const RelocAddrMap &M, + bool isLittleEndian) = 0; + ~DWARFUnitSectionBase() {} }; @@ -52,10 +60,12 @@ } }; + bool Parsed; + public: - DWARFUnitSection() {} + DWARFUnitSection() : Parsed(false) {} DWARFUnitSection(DWARFUnitSection &&DUS) : - SmallVector, 1>(std::move(DUS)) {} + SmallVector, 1>(std::move(DUS)), Parsed(DUS.Parsed) {} typedef llvm::SmallVectorImpl> UnitVector; typedef typename UnitVector::iterator iterator; @@ -68,6 +78,25 @@ return CU->get(); return nullptr; } + + private: + void parseImpl(DWARFContext &Context, const DWARFDebugAbbrev *DA, + StringRef Section, StringRef RS, StringRef SS, StringRef SOS, + StringRef AOS, const RelocAddrMap &M, bool LE) override { + if (Parsed) + return; + DataExtractor Data(Section, LE, 0); + uint32_t Offset = 0; + while (Data.isValidOffset(Offset)) { + auto U = make_unique(Context, DA, Section, RS, SS, SOS, AOS, &M, + Data.isLittleEndian(), *this); + if (!U->extract(Data, &Offset)) + break; + this->push_back(std::move(U)); + Offset = this->back()->getNextUnitOffset(); + } + Parsed = true; + } }; class DWARFUnit { Index: llvm/trunk/lib/DebugInfo/DWARFUnit.cpp =================================================================== --- llvm/trunk/lib/DebugInfo/DWARFUnit.cpp +++ llvm/trunk/lib/DebugInfo/DWARFUnit.cpp @@ -17,6 +17,21 @@ using namespace llvm; using namespace dwarf; + +void DWARFUnitSectionBase::parse(DWARFContext &C, StringRef SectionData, + const RelocAddrMap &Map) { + parseImpl(C, C.getDebugAbbrev(), SectionData, C.getRangeSection(), + C.getStringSection(), StringRef(), C.getAddrSection(), Map, + C.isLittleEndian()); +} + +void DWARFUnitSectionBase::parseDWO(DWARFContext &C, StringRef SectionData, + const RelocAddrMap &Map) { + parseImpl(C, C.getDebugAbbrevDWO(), SectionData, C.getRangeDWOSection(), + C.getStringDWOSection(), C.getStringOffsetDWOSection(), + C.getAddrSection(), Map, C.isLittleEndian()); +} + DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFDebugAbbrev *DA, StringRef IS, StringRef RS, StringRef SS, StringRef SOS, StringRef AOS, const RelocAddrMap *M, bool LE,