[DebugInfo/DWARF] [4/4] Unify handling of compile and type units. NFC
This is patch 4 of 4 NFC refactorings to handle type units and compile
units more consistently and with less concern about the object-file
section that they came from.
Patch 4 combines separate DWARFUnitVectors for compile and type units
into a single DWARFUnitVector that contains both. For now the
implementation distinguishes compile units from type units by putting
all compile units at the front of the vector, reflecting the DWARF v4
distinction between .debug_info and .debug_types sections. A future
patch will change this to allow the free mixing of unit kinds, as is
specified by DWARF v5.
Differential Revision: https://reviews.llvm.org/D49744
llvm-svn: 338633
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 79e463d..683da06 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -351,9 +351,9 @@
}
};
dumpDebugInfo(Explicit, ".debug_info", DObj->getInfoSection(),
- compile_units());
+ info_section_units());
dumpDebugInfo(ExplicitDWO, ".debug_info.dwo", DObj->getInfoDWOSection(),
- dwo_compile_units());
+ dwo_info_section_units());
auto dumpDebugType = [&](const char *Name, tu_iterator_range TUs) {
OS << '\n' << Name << " contents:\n";
@@ -367,9 +367,9 @@
};
if ((DumpType & DIDT_DebugTypes)) {
if (Explicit || getNumTypeUnits())
- dumpDebugType(".debug_types", type_units());
+ dumpDebugType(".debug_types", types_section_units());
if (ExplicitDWO || getNumDWOTypeUnits())
- dumpDebugType(".debug_types.dwo", dwo_type_units());
+ dumpDebugType(".debug_types.dwo", dwo_types_section_units());
}
if (shouldDump(Explicit, ".debug_loc", DIDT_ID_DebugLoc,
@@ -581,13 +581,12 @@
}
DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
- if (DWOCUs.empty())
- DWOCUs.addUnitsForDWOSection(*this, DObj->getInfoDWOSection(), DW_SECT_INFO,
- true);
+ parseDWOUnits(LazyParse);
if (const auto &CUI = getCUIndex()) {
if (const auto *R = CUI.getFromHash(Hash))
- return dyn_cast_or_null<DWARFCompileUnit>(DWOCUs.getUnitForIndexEntry(*R));
+ return dyn_cast_or_null<DWARFCompileUnit>(
+ DWOUnits.getUnitForIndexEntry(*R));
return nullptr;
}
@@ -612,8 +611,8 @@
}
DWARFDie DWARFContext::getDIEForOffset(uint32_t Offset) {
- parseCompileUnits();
- if (auto *CU = CUs.getUnitForOffset(Offset))
+ parseNormalUnits();
+ if (auto *CU = NormalUnits.getUnitForOffset(Offset))
return CU->getDIEForOffset(Offset);
return DWARFDie();
}
@@ -842,37 +841,31 @@
RecoverableErrorCallback);
}
-void DWARFContext::parseCompileUnits() {
- if (!CUs.empty())
+void DWARFContext::parseNormalUnits() {
+ if (!NormalUnits.empty())
return;
- CUs.addUnitsForSection(*this, DObj->getInfoSection(), DW_SECT_INFO);
-}
-
-void DWARFContext::parseTypeUnits() {
- if (!TUs.empty())
- return;
+ NormalUnits.addUnitsForSection(*this, DObj->getInfoSection(), DW_SECT_INFO);
+ NormalUnits.finishedInfoUnits();
DObj->forEachTypesSections([&](const DWARFSection &S) {
- TUs.addUnitsForSection(*this, S, DW_SECT_TYPES);
+ NormalUnits.addUnitsForSection(*this, S, DW_SECT_TYPES);
});
}
-void DWARFContext::parseDWOCompileUnits() {
- if (!DWOCUs.empty())
+void DWARFContext::parseDWOUnits(bool Lazy) {
+ if (!DWOUnits.empty())
return;
- DWOCUs.addUnitsForDWOSection(*this, DObj->getInfoDWOSection(), DW_SECT_INFO);
-}
-
-void DWARFContext::parseDWOTypeUnits() {
- if (!DWOTUs.empty())
- return;
+ DWOUnits.addUnitsForDWOSection(*this, DObj->getInfoDWOSection(), DW_SECT_INFO,
+ Lazy);
+ DWOUnits.finishedInfoUnits();
DObj->forEachTypesDWOSections([&](const DWARFSection &S) {
- DWOTUs.addUnitsForDWOSection(*this, S, DW_SECT_TYPES);
+ DWOUnits.addUnitsForDWOSection(*this, S, DW_SECT_TYPES, Lazy);
});
}
DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
- parseCompileUnits();
- return dyn_cast_or_null<DWARFCompileUnit>(CUs.getUnitForOffset(Offset));
+ parseNormalUnits();
+ return dyn_cast_or_null<DWARFCompileUnit>(
+ NormalUnits.getUnitForOffset(Offset));
}
DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 671fdeb..408eeb4 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -62,16 +62,16 @@
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, &Obj, &Section, &SOS, &LS](
- uint32_t Offset,
+ uint32_t Offset, DWARFSectionKind SectionKind,
const DWARFSection *CurSection) -> std::unique_ptr<DWARFUnit> {
const DWARFSection &InfoSection = CurSection ? *CurSection : Section;
DWARFDataExtractor Data(Obj, InfoSection, LE, 0);
if (!Data.isValidOffset(Offset))
return nullptr;
+ const DWARFUnitIndex *Index = nullptr;
+ if (IsDWO)
+ Index = &getDWARFUnitIndex(Context, SectionKind);
DWARFUnitHeader Header;
if (!Header.extract(Context, Data, &Offset, SectionKind, Index))
return nullptr;
@@ -89,14 +89,21 @@
}
if (Lazy)
return;
+ // Find a reasonable insertion point within the vector. We skip over
+ // (a) units from a different section, (b) units from the same section
+ // but with lower offset-within-section. This keeps units in order
+ // within a section, although not necessarily within the object file,
+ // even if we do lazy parsing.
auto I = this->begin();
uint32_t Offset = 0;
while (Data.isValidOffset(Offset)) {
- if (I != this->end() && (*I)->getOffset() == Offset) {
+ if (I != this->end() &&
+ (&(*I)->getInfoSection() != &Section || (*I)->getOffset() == Offset)) {
++I;
continue;
}
- auto U = Parser(Offset, &Section);
+ auto U = Parser(Offset, SectionKind, &Section);
+ // If parsing failed, we're done with this section.
if (!U)
break;
Offset = U->getNextUnitOffset();
@@ -134,7 +141,7 @@
if (!Parser)
return nullptr;
- auto U = Parser(Offset, nullptr);
+ auto U = Parser(Offset, DW_SECT_INFO, nullptr);
if (!U)
U = nullptr;