diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h @@ -189,12 +189,10 @@ public: /// Apple-specific implementation of an Accelerator Entry. class Entry final : public DWARFAcceleratorTable::Entry { - const HeaderData *HdrData = nullptr; + const AppleAcceleratorTable &Table; - Entry(const HeaderData &Data); - Entry() = default; - - void extract(const AppleAcceleratorTable &AccelTable, uint64_t *Offset); + Entry(const AppleAcceleratorTable &Table); + void extract(uint64_t *Offset); public: std::optional getCUOffset() const override; @@ -215,37 +213,25 @@ friend class ValueIterator; }; + /// An iterator for Entries all having the same string as key. class ValueIterator { - const AppleAcceleratorTable *AccelTable = nullptr; - Entry Current; ///< The current entry. - uint64_t DataOffset = 0; ///< Offset into the section. - unsigned Data = 0; ///< Current data entry. - unsigned NumData = 0; ///< Number of data entries. + Entry Current; + uint64_t Offset = 0; - /// Advance the iterator. - void Next(); + void Next() { Offset += Current.Table.getHashDataEntryLength(); } public: - using iterator_category = std::input_iterator_tag; - using value_type = Entry; - using difference_type = std::ptrdiff_t; - using pointer = value_type *; - using reference = value_type &; - /// Construct a new iterator for the entries at \p DataOffset. ValueIterator(const AppleAcceleratorTable &AccelTable, uint64_t DataOffset); - /// End marker. - ValueIterator() = default; - const Entry &operator*() const { return Current; } - ValueIterator &operator++() { Next(); return *this; } - ValueIterator operator++(int) { - ValueIterator I = *this; - Next(); - return I; + const Entry &operator*() { + uint64_t OffsetCopy = Offset; + Current.extract(&OffsetCopy); + return Current; } + ValueIterator &operator++() { Next(); return *this; } friend bool operator==(const ValueIterator &A, const ValueIterator &B) { - return A.NumData == B.NumData && A.DataOffset == B.DataOffset; + return A.Offset == B.Offset; } friend bool operator!=(const ValueIterator &A, const ValueIterator &B) { return !(A == B); diff --git a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp --- a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp @@ -267,26 +267,21 @@ } } -AppleAcceleratorTable::Entry::Entry( - const AppleAcceleratorTable::HeaderData &HdrData) - : HdrData(&HdrData) { - Values.reserve(HdrData.Atoms.size()); - for (const auto &Atom : HdrData.Atoms) +AppleAcceleratorTable::Entry::Entry(const AppleAcceleratorTable &Table) + : Table(Table) { + Values.reserve(Table.HdrData.Atoms.size()); + for (const auto &Atom : Table.HdrData.Atoms) Values.push_back(DWARFFormValue(Atom.second)); } -void AppleAcceleratorTable::Entry::extract( - const AppleAcceleratorTable &AccelTable, uint64_t *Offset) { +void AppleAcceleratorTable::Entry::extract(uint64_t *Offset) { for (auto &FormValue : Values) - FormValue.extractValue(AccelTable.AccelSection, Offset, - AccelTable.FormParams); + FormValue.extractValue(Table.AccelSection, Offset, Table.FormParams); } std::optional AppleAcceleratorTable::Entry::lookup(HeaderData::AtomType AtomToFind) const { - assert(HdrData && "Dereferencing end iterator?"); - assert(HdrData->Atoms.size() == Values.size()); - for (auto [Atom, FormValue] : zip_equal(HdrData->Atoms, Values)) + for (auto [Atom, FormValue] : zip_equal(Table.HdrData.Atoms, Values)) if (Atom.first == AtomToFind) return FormValue; return std::nullopt; @@ -294,11 +289,11 @@ std::optional AppleAcceleratorTable::Entry::getDIESectionOffset() const { - return HdrData->extractOffset(lookup(dwarf::DW_ATOM_die_offset)); + return Table.HdrData.extractOffset(lookup(dwarf::DW_ATOM_die_offset)); } std::optional AppleAcceleratorTable::Entry::getCUOffset() const { - return HdrData->extractOffset(lookup(dwarf::DW_ATOM_cu_offset)); + return Table.HdrData.extractOffset(lookup(dwarf::DW_ATOM_cu_offset)); } std::optional AppleAcceleratorTable::Entry::getTag() const { @@ -311,32 +306,14 @@ } AppleAcceleratorTable::ValueIterator::ValueIterator( - const AppleAcceleratorTable &AccelTable, uint64_t Offset) - : AccelTable(&AccelTable), Current(AccelTable.HdrData), DataOffset(Offset) { - if (!AccelTable.AccelSection.isValidOffsetForDataOfSize(DataOffset, 4)) - return; - - // Read the first entry. - NumData = AccelTable.AccelSection.getU32(&DataOffset); - Next(); -} - -void AppleAcceleratorTable::ValueIterator::Next() { - assert(NumData > 0 && "attempted to increment iterator past the end"); - auto &AccelSection = AccelTable->AccelSection; - if (Data >= NumData || - !AccelSection.isValidOffsetForDataOfSize(DataOffset, 4)) { - NumData = 0; - DataOffset = 0; - return; - } - Current.extract(*AccelTable, &DataOffset); - ++Data; + const AppleAcceleratorTable &AccelTable, uint64_t DataOffset) + : Current(AccelTable), Offset(DataOffset) { } iterator_range AppleAcceleratorTable::equal_range(StringRef Key) const { - const auto EmptyRange = make_range(ValueIterator(), ValueIterator()); + const auto EmptyRange = + make_range(ValueIterator(*this, 0), ValueIterator(*this, 0)); if (!IsValid) return EmptyRange; @@ -362,10 +339,13 @@ return EmptyRange; std::optional MaybeStr = readStringFromStrSection(*StrOffset); - if (!MaybeStr) + std::optional NumEntries = this->readU32FromAccel(DataOffset); + if (!MaybeStr || !NumEntries) return EmptyRange; - if (Key == *MaybeStr) - return make_range({*this, DataOffset}, ValueIterator()); + if (Key == *MaybeStr) { + uint64_t EndOffset = DataOffset + *NumEntries * getHashDataEntryLength(); + return make_range({*this, DataOffset}, ValueIterator{*this, EndOffset}); + } // FIXME: this shouldn't return, we haven't checked all the colliding strings // in the bucket!