Skip to content

Commit

Permalink
[DebugInfo/DWARF] [1/4] De-templatize DWARFUnitSection. NFC
Browse files Browse the repository at this point in the history
This is patch 1 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 1 replaces the templated DWARFUnitSection with a non-templated
version. That is, instead of being a SmallVector of pointers to a
specific unit kind, it is not a SmallVector of pointers to the base
class for both type and compile units.  Virtual methods are magic.

Differential Revision: https://reviews.llvm.org/D49741

llvm-svn: 338628
  • Loading branch information
pogo59 committed Aug 1, 2018
1 parent 624169f commit 143eaea
Show file tree
Hide file tree
Showing 10 changed files with 181 additions and 168 deletions.
12 changes: 6 additions & 6 deletions llvm/include/llvm/DebugInfo/DWARF/DWARFCompileUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,16 @@ class DWARFCompileUnit : public DWARFUnit {
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
StringRef SS, const DWARFSection &SOS,
const DWARFSection *AOS, const DWARFSection &LS, bool LE,
bool IsDWO, const DWARFUnitSectionBase &UnitSection)
bool IsDWO, const DWARFUnitSection &UnitSection)
: DWARFUnit(Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
UnitSection) {}

// VTable anchor.
/// VTable anchor.
~DWARFCompileUnit() override;

void dump(raw_ostream &OS, DIDumpOptions DumpOpts);

static const DWARFSectionKind Section = DW_SECT_INFO;
/// Dump this compile unit to \p OS.
void dump(raw_ostream &OS, DIDumpOptions DumpOpts) override;
/// Enable LLVM-style RTTI.
static bool classof(const DWARFUnit *U) { return !U->isTypeUnit(); }
};

} // end namespace llvm
Expand Down
20 changes: 10 additions & 10 deletions llvm/include/llvm/DebugInfo/DWARF/DWARFContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ enum class ErrorPolicy { Halt, Continue };
/// This data structure is the top level entity that deals with dwarf debug
/// information parsing. The actual data is supplied through DWARFObj.
class DWARFContext : public DIContext {
DWARFUnitSection<DWARFCompileUnit> CUs;
std::deque<DWARFUnitSection<DWARFTypeUnit>> TUs;
DWARFUnitSection CUs;
std::deque<DWARFUnitSection> TUs;
std::unique_ptr<DWARFUnitIndex> CUIndex;
std::unique_ptr<DWARFGdbIndex> GdbIndex;
std::unique_ptr<DWARFUnitIndex> TUIndex;
Expand All @@ -75,8 +75,8 @@ class DWARFContext : public DIContext {
std::unique_ptr<AppleAcceleratorTable> AppleNamespaces;
std::unique_ptr<AppleAcceleratorTable> AppleObjC;

DWARFUnitSection<DWARFCompileUnit> DWOCUs;
std::deque<DWARFUnitSection<DWARFTypeUnit>> DWOTUs;
DWARFUnitSection DWOCUs;
std::deque<DWARFUnitSection> DWOTUs;
std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
std::unique_ptr<DWARFDebugLocDWO> LocDWO;

Expand Down Expand Up @@ -139,8 +139,8 @@ class DWARFContext : public DIContext {

bool verify(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override;

using cu_iterator_range = DWARFUnitSection<DWARFCompileUnit>::iterator_range;
using tu_iterator_range = DWARFUnitSection<DWARFTypeUnit>::iterator_range;
using cu_iterator_range = DWARFUnitSection::iterator_range;
using tu_iterator_range = DWARFUnitSection::iterator_range;
using tu_section_iterator_range = iterator_range<decltype(TUs)::iterator>;

/// Get compile units in this context.
Expand Down Expand Up @@ -191,14 +191,14 @@ class DWARFContext : public DIContext {
return DWOTUs.size();
}

/// Get the compile unit at the specified index for this compile unit.
DWARFCompileUnit *getCompileUnitAtIndex(unsigned index) {
/// Get the unit at the specified index.
DWARFUnit *getUnitAtIndex(unsigned index) {
parseCompileUnits();
return CUs[index].get();
}

/// Get the compile unit at the specified index for the DWO compile units.
DWARFCompileUnit *getDWOCompileUnitAtIndex(unsigned index) {
/// Get the unit at the specified index for the DWO units.
DWARFUnit *getDWOUnitAtIndex(unsigned index) {
parseDWOCompileUnits();
return DWOCUs[index].get();
}
Expand Down
5 changes: 2 additions & 3 deletions llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,8 @@ class DWARFDebugLine {
/// Helper to allow for parsing of an entire .debug_line section in sequence.
class SectionParser {
public:
using cu_range = DWARFUnitSection<DWARFCompileUnit>::iterator_range;
using tu_range =
iterator_range<std::deque<DWARFUnitSection<DWARFTypeUnit>>::iterator>;
using cu_range = DWARFUnitSection::iterator_range;
using tu_range = iterator_range<std::deque<DWARFUnitSection>::iterator>;
using LineToUnitMap = std::map<uint64_t, DWARFUnit *>;

SectionParser(DWARFDataExtractor &Data, const DWARFContext &C, cu_range CUs,
Expand Down
7 changes: 4 additions & 3 deletions llvm/include/llvm/DebugInfo/DWARF/DWARFTypeUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,16 @@ class DWARFTypeUnit : public DWARFUnit {
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS,
const DWARFSection &LS, bool LE, bool IsDWO,
const DWARFUnitSectionBase &UnitSection)
const DWARFUnitSection &UnitSection)
: DWARFUnit(Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
UnitSection) {}

uint64_t getTypeHash() const { return getHeader().getTypeHash(); }
uint32_t getTypeOffset() const { return getHeader().getTypeOffset(); }

void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {});
static const DWARFSectionKind Section = DW_SECT_TYPES;
void dump(raw_ostream &OS, DIDumpOptions DumpOpts = {}) override;
// Enable LLVM-style RTTI.
static bool classof(const DWARFUnit *U) { return U->isTypeUnit(); }
};

} // end namespace llvm
Expand Down
124 changes: 16 additions & 108 deletions llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,125 +101,31 @@ class DWARFUnitHeader {
uint32_t getNextUnitOffset() const { return Offset + Length + 4; }
};

/// Base class for all DWARFUnitSection classes. This provides the
/// functionality common to all unit types.
class DWARFUnitSectionBase {
public:
/// Returns the Unit that contains the given section offset in the
/// same section this Unit originated from.
virtual DWARFUnit *getUnitForOffset(uint32_t Offset) const = 0;
virtual DWARFUnit *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) = 0;

void parse(DWARFContext &C, const DWARFSection &Section);
void parseDWO(DWARFContext &C, const DWARFSection &DWOSection,
bool Lazy = false);

protected:
~DWARFUnitSectionBase() = default;

virtual 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 isLittleEndian, bool isDWO, bool Lazy) = 0;
};

const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,
DWARFSectionKind Kind);

/// Concrete instance of DWARFUnitSection, specialized for one Unit type.
template<typename UnitType>
class DWARFUnitSection final : public SmallVector<std::unique_ptr<UnitType>, 1>,
public DWARFUnitSectionBase {
/// Describes one section's Units.
class DWARFUnitSection final : public SmallVector<std::unique_ptr<DWARFUnit>, 1> {
bool Parsed = false;
std::function<std::unique_ptr<UnitType>(uint32_t)> Parser;
std::function<std::unique_ptr<DWARFUnit>(uint32_t)> Parser;

public:
using UnitVector = SmallVectorImpl<std::unique_ptr<UnitType>>;
using UnitVector = SmallVectorImpl<std::unique_ptr<DWARFUnit>>;
using iterator = typename UnitVector::iterator;
using iterator_range = llvm::iterator_range<typename UnitVector::iterator>;

UnitType *getUnitForOffset(uint32_t Offset) const override {
auto *CU = std::upper_bound(
this->begin(), this->end(), Offset,
[](uint32_t LHS, const std::unique_ptr<UnitType> &RHS) {
return LHS < RHS->getNextUnitOffset();
});
if (CU != this->end() && (*CU)->getOffset() <= Offset)
return CU->get();
return nullptr;
}
UnitType *getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) override {
const auto *CUOff = E.getOffset(DW_SECT_INFO);
if (!CUOff)
return nullptr;

auto Offset = CUOff->Offset;

auto *CU = std::upper_bound(
this->begin(), this->end(), CUOff->Offset,
[](uint32_t LHS, const std::unique_ptr<UnitType> &RHS) {
return LHS < RHS->getNextUnitOffset();
});
if (CU != this->end() && (*CU)->getOffset() <= Offset)
return CU->get();

if (!Parser)
return nullptr;

auto U = Parser(Offset);
if (!U)
U = nullptr;

auto *NewCU = U.get();
this->insert(CU, std::move(U));
return NewCU;
}

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);
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) override {
if (Parsed)
return;
DWARFDataExtractor Data(Obj, Section, LE, 0);
if (!Parser) {
const DWARFUnitIndex *Index = nullptr;
if (IsDWO)
Index = &getDWARFUnitIndex(Context, UnitType::Section);
Parser = [=, &Context, &Section, &SOS,
&LS](uint32_t Offset) -> std::unique_ptr<UnitType> {
if (!Data.isValidOffset(Offset))
return nullptr;
DWARFUnitHeader Header;
if (!Header.extract(Context, Data, &Offset, UnitType::Section, Index))
return nullptr;
auto U = llvm::make_unique<UnitType>(
Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
*this);
return U;
};
}
if (Lazy)
return;
auto I = this->begin();
uint32_t Offset = 0;
while (Data.isValidOffset(Offset)) {
if (I != this->end() && (*I)->getOffset() == Offset) {
++I;
continue;
}
auto U = Parser(Offset);
if (!U)
break;
Offset = U->getNextUnitOffset();
I = std::next(this->insert(I, std::move(U)));
}
Parsed = true;
}
bool IsDWO, bool Lazy, DWARFSectionKind SectionKind);
};

/// Represents base address of the CU.
Expand Down Expand Up @@ -268,7 +174,7 @@ class DWARFUnit {
uint32_t AddrOffsetSectionBase = 0;
bool isLittleEndian;
bool isDWO;
const DWARFUnitSectionBase &UnitSection;
const DWARFUnitSection &UnitSection;

/// Start, length, and DWARF format of the unit's contribution to the string
/// offsets table (DWARF v5).
Expand Down Expand Up @@ -325,7 +231,7 @@ class DWARFUnit {
const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS,
const DWARFSection &SOS, const DWARFSection *AOS,
const DWARFSection &LS, bool LE, bool IsDWO,
const DWARFUnitSectionBase &UnitSection);
const DWARFUnitSection &UnitSection);

virtual ~DWARFUnit();

Expand All @@ -342,6 +248,7 @@ class DWARFUnit {
}
uint32_t getLength() const { return Header.getLength(); }
uint8_t getUnitType() const { return Header.getUnitType(); }
bool isTypeUnit() const { return Header.isTypeUnit(); }
uint32_t getNextUnitOffset() const { return Header.getNextUnitOffset(); }
const DWARFSection &getLineSection() const { return LineSection; }
StringRef getStringSection() const { return StringSection; }
Expand Down Expand Up @@ -481,7 +388,7 @@ class DWARFUnit {
SmallVectorImpl<DWARFDie> &InlinedChain);

/// getUnitSection - Return the DWARFUnitSection containing this unit.
const DWARFUnitSectionBase &getUnitSection() const { return UnitSection; }
const DWARFUnitSection &getUnitSection() const { return UnitSection; }

/// Returns the number of DIEs in the unit. Parses the unit
/// if necessary.
Expand Down Expand Up @@ -541,6 +448,7 @@ class DWARFUnit {
return die_iterator_range(DieArray.begin(), DieArray.end());
}

virtual void dump(raw_ostream &OS, DIDumpOptions DumpOpts) = 0;
private:
/// Size in bytes of the .debug_info data associated with this compile unit.
size_t getDebugInfoSize() const {
Expand Down
22 changes: 11 additions & 11 deletions llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -584,11 +584,11 @@ void DWARFContext::dump(
}

DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
DWOCUs.parseDWO(*this, DObj->getInfoDWOSection(), true);
DWOCUs.parseDWO(*this, DObj->getInfoDWOSection(), DW_SECT_INFO, true);

if (const auto &CUI = getCUIndex()) {
if (const auto *R = CUI.getFromHash(Hash))
return DWOCUs.getUnitForIndexEntry(*R);
return dyn_cast_or_null<DWARFCompileUnit>(DWOCUs.getUnitForIndexEntry(*R));
return nullptr;
}

Expand All @@ -607,7 +607,7 @@ DWARFCompileUnit *DWARFContext::getDWOCompileUnitForHash(uint64_t Hash) {
continue;
}
if (DWOCU->getDWOId() == Hash)
return DWOCU.get();
return dyn_cast<DWARFCompileUnit>(DWOCU.get());
}
return nullptr;
}
Expand Down Expand Up @@ -690,10 +690,10 @@ const DWARFDebugLoc *DWARFContext::getDebugLoc() {
return Loc.get();

Loc.reset(new DWARFDebugLoc);
// Assume all compile units have the same address byte size.
// Assume all units have the same address byte size.
if (getNumCompileUnits()) {
DWARFDataExtractor LocData(*DObj, DObj->getLocSection(), isLittleEndian(),
getCompileUnitAtIndex(0)->getAddressByteSize());
getUnitAtIndex(0)->getAddressByteSize());
Loc->parse(LocData);
}
return Loc.get();
Expand All @@ -707,7 +707,7 @@ const DWARFDebugLocDWO *DWARFContext::getDebugLocDWO() {
// Assume all compile units have the same address byte size.
if (getNumCompileUnits()) {
DataExtractor LocData(DObj->getLocDWOSection().Data, isLittleEndian(),
getCompileUnitAtIndex(0)->getAddressByteSize());
getUnitAtIndex(0)->getAddressByteSize());
LocDWO->parse(LocData);
}
return LocDWO.get();
Expand Down Expand Up @@ -844,34 +844,34 @@ Expected<const DWARFDebugLine::LineTable *> DWARFContext::getLineTableForUnit(
}

void DWARFContext::parseCompileUnits() {
CUs.parse(*this, DObj->getInfoSection());
CUs.parse(*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);
TUs.back().parse(*this, S, DW_SECT_TYPES);
});
}

void DWARFContext::parseDWOCompileUnits() {
DWOCUs.parseDWO(*this, DObj->getInfoDWOSection());
DWOCUs.parseDWO(*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);
DWOTUs.back().parseDWO(*this, S, DW_SECT_TYPES);
});
}

DWARFCompileUnit *DWARFContext::getCompileUnitForOffset(uint32_t Offset) {
parseCompileUnits();
return CUs.getUnitForOffset(Offset);
return dyn_cast_or_null<DWARFCompileUnit>(CUs.getUnitForOffset(Offset));
}

DWARFCompileUnit *DWARFContext::getCompileUnitForAddress(uint64_t Address) {
Expand Down

0 comments on commit 143eaea

Please sign in to comment.