DWARFAcceleratorTable.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- DWARFAcceleratorTable.h ----------------------------------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #ifndef LLVM_DEBUGINFO_DWARF_DWARFACCELERATORTABLE_H
  14. #define LLVM_DEBUGINFO_DWARF_DWARFACCELERATORTABLE_H
  15. #include "llvm/ADT/DenseSet.h"
  16. #include "llvm/ADT/SmallVector.h"
  17. #include "llvm/BinaryFormat/Dwarf.h"
  18. #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
  19. #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
  20. #include <cstdint>
  21. #include <utility>
  22. namespace llvm {
  23. class raw_ostream;
  24. class ScopedPrinter;
  25. /// The accelerator tables are designed to allow efficient random access
  26. /// (using a symbol name as a key) into debug info by providing an index of the
  27. /// debug info DIEs. This class implements the common functionality of Apple and
  28. /// DWARF 5 accelerator tables.
  29. /// TODO: Generalize the rest of the AppleAcceleratorTable interface and move it
  30. /// to this class.
  31. class DWARFAcceleratorTable {
  32. protected:
  33. DWARFDataExtractor AccelSection;
  34. DataExtractor StringSection;
  35. public:
  36. /// An abstract class representing a single entry in the accelerator tables.
  37. class Entry {
  38. protected:
  39. SmallVector<DWARFFormValue, 3> Values;
  40. Entry() = default;
  41. // Make these protected so only (final) subclasses can be copied around.
  42. Entry(const Entry &) = default;
  43. Entry(Entry &&) = default;
  44. Entry &operator=(const Entry &) = default;
  45. Entry &operator=(Entry &&) = default;
  46. ~Entry() = default;
  47. public:
  48. /// Returns the Offset of the Compilation Unit associated with this
  49. /// Accelerator Entry or std::nullopt if the Compilation Unit offset is not
  50. /// recorded in this Accelerator Entry.
  51. virtual std::optional<uint64_t> getCUOffset() const = 0;
  52. /// Returns the Tag of the Debug Info Entry associated with this
  53. /// Accelerator Entry or std::nullopt if the Tag is not recorded in this
  54. /// Accelerator Entry.
  55. virtual std::optional<dwarf::Tag> getTag() const = 0;
  56. /// Returns the raw values of fields in the Accelerator Entry. In general,
  57. /// these can only be interpreted with the help of the metadata in the
  58. /// owning Accelerator Table.
  59. ArrayRef<DWARFFormValue> getValues() const { return Values; }
  60. };
  61. DWARFAcceleratorTable(const DWARFDataExtractor &AccelSection,
  62. DataExtractor StringSection)
  63. : AccelSection(AccelSection), StringSection(StringSection) {}
  64. virtual ~DWARFAcceleratorTable();
  65. virtual Error extract() = 0;
  66. virtual void dump(raw_ostream &OS) const = 0;
  67. DWARFAcceleratorTable(const DWARFAcceleratorTable &) = delete;
  68. void operator=(const DWARFAcceleratorTable &) = delete;
  69. };
  70. /// This implements the Apple accelerator table format, a precursor of the
  71. /// DWARF 5 accelerator table format.
  72. class AppleAcceleratorTable : public DWARFAcceleratorTable {
  73. struct Header {
  74. uint32_t Magic;
  75. uint16_t Version;
  76. uint16_t HashFunction;
  77. uint32_t BucketCount;
  78. uint32_t HashCount;
  79. uint32_t HeaderDataLength;
  80. void dump(ScopedPrinter &W) const;
  81. };
  82. struct HeaderData {
  83. using AtomType = uint16_t;
  84. using Form = dwarf::Form;
  85. uint64_t DIEOffsetBase;
  86. SmallVector<std::pair<AtomType, Form>, 3> Atoms;
  87. std::optional<uint64_t>
  88. extractOffset(std::optional<DWARFFormValue> Value) const;
  89. };
  90. struct Header Hdr;
  91. struct HeaderData HdrData;
  92. bool IsValid = false;
  93. /// Returns true if we should continue scanning for entries or false if we've
  94. /// reached the last (sentinel) entry of encountered a parsing error.
  95. bool dumpName(ScopedPrinter &W, SmallVectorImpl<DWARFFormValue> &AtomForms,
  96. uint64_t *DataOffset) const;
  97. public:
  98. /// Apple-specific implementation of an Accelerator Entry.
  99. class Entry final : public DWARFAcceleratorTable::Entry {
  100. const HeaderData *HdrData = nullptr;
  101. Entry(const HeaderData &Data);
  102. Entry() = default;
  103. void extract(const AppleAcceleratorTable &AccelTable, uint64_t *Offset);
  104. public:
  105. std::optional<uint64_t> getCUOffset() const override;
  106. /// Returns the Section Offset of the Debug Info Entry associated with this
  107. /// Accelerator Entry or std::nullopt if the DIE offset is not recorded in
  108. /// this Accelerator Entry. The returned offset is relative to the start of
  109. /// the Section containing the DIE.
  110. std::optional<uint64_t> getDIESectionOffset() const;
  111. std::optional<dwarf::Tag> getTag() const override;
  112. /// Returns the value of the Atom in this Accelerator Entry, if the Entry
  113. /// contains such Atom.
  114. std::optional<DWARFFormValue> lookup(HeaderData::AtomType Atom) const;
  115. friend class AppleAcceleratorTable;
  116. friend class ValueIterator;
  117. };
  118. class ValueIterator {
  119. const AppleAcceleratorTable *AccelTable = nullptr;
  120. Entry Current; ///< The current entry.
  121. uint64_t DataOffset = 0; ///< Offset into the section.
  122. unsigned Data = 0; ///< Current data entry.
  123. unsigned NumData = 0; ///< Number of data entries.
  124. /// Advance the iterator.
  125. void Next();
  126. public:
  127. using iterator_category = std::input_iterator_tag;
  128. using value_type = Entry;
  129. using difference_type = std::ptrdiff_t;
  130. using pointer = value_type *;
  131. using reference = value_type &;
  132. /// Construct a new iterator for the entries at \p DataOffset.
  133. ValueIterator(const AppleAcceleratorTable &AccelTable, uint64_t DataOffset);
  134. /// End marker.
  135. ValueIterator() = default;
  136. const Entry &operator*() const { return Current; }
  137. ValueIterator &operator++() { Next(); return *this; }
  138. ValueIterator operator++(int) {
  139. ValueIterator I = *this;
  140. Next();
  141. return I;
  142. }
  143. friend bool operator==(const ValueIterator &A, const ValueIterator &B) {
  144. return A.NumData == B.NumData && A.DataOffset == B.DataOffset;
  145. }
  146. friend bool operator!=(const ValueIterator &A, const ValueIterator &B) {
  147. return !(A == B);
  148. }
  149. };
  150. AppleAcceleratorTable(const DWARFDataExtractor &AccelSection,
  151. DataExtractor StringSection)
  152. : DWARFAcceleratorTable(AccelSection, StringSection) {}
  153. Error extract() override;
  154. uint32_t getNumBuckets();
  155. uint32_t getNumHashes();
  156. uint32_t getSizeHdr();
  157. uint32_t getHeaderDataLength();
  158. /// Return the Atom description, which can be used to interpret the raw values
  159. /// of the Accelerator Entries in this table.
  160. ArrayRef<std::pair<HeaderData::AtomType, HeaderData::Form>> getAtomsDesc();
  161. bool validateForms();
  162. /// Return information related to the DWARF DIE we're looking for when
  163. /// performing a lookup by name.
  164. ///
  165. /// \param HashDataOffset an offset into the hash data table
  166. /// \returns <DieOffset, DieTag>
  167. /// DieOffset is the offset into the .debug_info section for the DIE
  168. /// related to the input hash data offset.
  169. /// DieTag is the tag of the DIE
  170. std::pair<uint64_t, dwarf::Tag> readAtoms(uint64_t *HashDataOffset);
  171. void dump(raw_ostream &OS) const override;
  172. /// Look up all entries in the accelerator table matching \c Key.
  173. iterator_range<ValueIterator> equal_range(StringRef Key) const;
  174. };
  175. /// .debug_names section consists of one or more units. Each unit starts with a
  176. /// header, which is followed by a list of compilation units, local and foreign
  177. /// type units.
  178. ///
  179. /// These may be followed by an (optional) hash lookup table, which consists of
  180. /// an array of buckets and hashes similar to the apple tables above. The only
  181. /// difference is that the hashes array is 1-based, and consequently an empty
  182. /// bucket is denoted by 0 and not UINT32_MAX.
  183. ///
  184. /// Next is the name table, which consists of an array of names and array of
  185. /// entry offsets. This is different from the apple tables, which store names
  186. /// next to the actual entries.
  187. ///
  188. /// The structure of the entries is described by an abbreviations table, which
  189. /// comes after the name table. Unlike the apple tables, which have a uniform
  190. /// entry structure described in the header, each .debug_names entry may have
  191. /// different index attributes (DW_IDX_???) attached to it.
  192. ///
  193. /// The last segment consists of a list of entries, which is a 0-terminated list
  194. /// referenced by the name table and interpreted with the help of the
  195. /// abbreviation table.
  196. class DWARFDebugNames : public DWARFAcceleratorTable {
  197. public:
  198. class NameIndex;
  199. class NameIterator;
  200. class ValueIterator;
  201. /// DWARF v5 Name Index header.
  202. struct Header {
  203. uint64_t UnitLength;
  204. dwarf::DwarfFormat Format;
  205. uint16_t Version;
  206. uint32_t CompUnitCount;
  207. uint32_t LocalTypeUnitCount;
  208. uint32_t ForeignTypeUnitCount;
  209. uint32_t BucketCount;
  210. uint32_t NameCount;
  211. uint32_t AbbrevTableSize;
  212. uint32_t AugmentationStringSize;
  213. SmallString<8> AugmentationString;
  214. Error extract(const DWARFDataExtractor &AS, uint64_t *Offset);
  215. void dump(ScopedPrinter &W) const;
  216. };
  217. /// Index attribute and its encoding.
  218. struct AttributeEncoding {
  219. dwarf::Index Index;
  220. dwarf::Form Form;
  221. constexpr AttributeEncoding(dwarf::Index Index, dwarf::Form Form)
  222. : Index(Index), Form(Form) {}
  223. friend bool operator==(const AttributeEncoding &LHS,
  224. const AttributeEncoding &RHS) {
  225. return LHS.Index == RHS.Index && LHS.Form == RHS.Form;
  226. }
  227. };
  228. /// Abbreviation describing the encoding of Name Index entries.
  229. struct Abbrev {
  230. uint32_t Code; ///< Abbreviation code
  231. dwarf::Tag Tag; ///< Dwarf Tag of the described entity.
  232. std::vector<AttributeEncoding> Attributes; ///< List of index attributes.
  233. Abbrev(uint32_t Code, dwarf::Tag Tag,
  234. std::vector<AttributeEncoding> Attributes)
  235. : Code(Code), Tag(Tag), Attributes(std::move(Attributes)) {}
  236. void dump(ScopedPrinter &W) const;
  237. };
  238. /// DWARF v5-specific implementation of an Accelerator Entry.
  239. class Entry final : public DWARFAcceleratorTable::Entry {
  240. const NameIndex *NameIdx;
  241. const Abbrev *Abbr;
  242. Entry(const NameIndex &NameIdx, const Abbrev &Abbr);
  243. public:
  244. std::optional<uint64_t> getCUOffset() const override;
  245. std::optional<dwarf::Tag> getTag() const override { return tag(); }
  246. /// Returns the Index into the Compilation Unit list of the owning Name
  247. /// Index or std::nullopt if this Accelerator Entry does not have an
  248. /// associated Compilation Unit. It is up to the user to verify that the
  249. /// returned Index is valid in the owning NameIndex (or use getCUOffset(),
  250. /// which will handle that check itself). Note that entries in NameIndexes
  251. /// which index just a single Compilation Unit are implicitly associated
  252. /// with that unit, so this function will return 0 even without an explicit
  253. /// DW_IDX_compile_unit attribute.
  254. std::optional<uint64_t> getCUIndex() const;
  255. /// .debug_names-specific getter, which always succeeds (DWARF v5 index
  256. /// entries always have a tag).
  257. dwarf::Tag tag() const { return Abbr->Tag; }
  258. /// Returns the Offset of the DIE within the containing CU or TU.
  259. std::optional<uint64_t> getDIEUnitOffset() const;
  260. /// Return the Abbreviation that can be used to interpret the raw values of
  261. /// this Accelerator Entry.
  262. const Abbrev &getAbbrev() const { return *Abbr; }
  263. /// Returns the value of the Index Attribute in this Accelerator Entry, if
  264. /// the Entry contains such Attribute.
  265. std::optional<DWARFFormValue> lookup(dwarf::Index Index) const;
  266. void dump(ScopedPrinter &W) const;
  267. friend class NameIndex;
  268. friend class ValueIterator;
  269. };
  270. /// Error returned by NameIndex::getEntry to report it has reached the end of
  271. /// the entry list.
  272. class SentinelError : public ErrorInfo<SentinelError> {
  273. public:
  274. static char ID;
  275. void log(raw_ostream &OS) const override { OS << "Sentinel"; }
  276. std::error_code convertToErrorCode() const override;
  277. };
  278. private:
  279. /// DenseMapInfo for struct Abbrev.
  280. struct AbbrevMapInfo {
  281. static Abbrev getEmptyKey();
  282. static Abbrev getTombstoneKey();
  283. static unsigned getHashValue(uint32_t Code) {
  284. return DenseMapInfo<uint32_t>::getHashValue(Code);
  285. }
  286. static unsigned getHashValue(const Abbrev &Abbr) {
  287. return getHashValue(Abbr.Code);
  288. }
  289. static bool isEqual(uint32_t LHS, const Abbrev &RHS) {
  290. return LHS == RHS.Code;
  291. }
  292. static bool isEqual(const Abbrev &LHS, const Abbrev &RHS) {
  293. return LHS.Code == RHS.Code;
  294. }
  295. };
  296. public:
  297. /// A single entry in the Name Table (DWARF v5 sect. 6.1.1.4.6) of the Name
  298. /// Index.
  299. class NameTableEntry {
  300. DataExtractor StrData;
  301. uint32_t Index;
  302. uint64_t StringOffset;
  303. uint64_t EntryOffset;
  304. public:
  305. NameTableEntry(const DataExtractor &StrData, uint32_t Index,
  306. uint64_t StringOffset, uint64_t EntryOffset)
  307. : StrData(StrData), Index(Index), StringOffset(StringOffset),
  308. EntryOffset(EntryOffset) {}
  309. /// Return the index of this name in the parent Name Index.
  310. uint32_t getIndex() const { return Index; }
  311. /// Returns the offset of the name of the described entities.
  312. uint64_t getStringOffset() const { return StringOffset; }
  313. /// Return the string referenced by this name table entry or nullptr if the
  314. /// string offset is not valid.
  315. const char *getString() const {
  316. uint64_t Off = StringOffset;
  317. return StrData.getCStr(&Off);
  318. }
  319. /// Returns the offset of the first Entry in the list.
  320. uint64_t getEntryOffset() const { return EntryOffset; }
  321. };
  322. /// Represents a single accelerator table within the DWARF v5 .debug_names
  323. /// section.
  324. class NameIndex {
  325. DenseSet<Abbrev, AbbrevMapInfo> Abbrevs;
  326. struct Header Hdr;
  327. const DWARFDebugNames &Section;
  328. // Base of the whole unit and of various important tables, as offsets from
  329. // the start of the section.
  330. uint64_t Base;
  331. uint64_t CUsBase;
  332. uint64_t BucketsBase;
  333. uint64_t HashesBase;
  334. uint64_t StringOffsetsBase;
  335. uint64_t EntryOffsetsBase;
  336. uint64_t EntriesBase;
  337. void dumpCUs(ScopedPrinter &W) const;
  338. void dumpLocalTUs(ScopedPrinter &W) const;
  339. void dumpForeignTUs(ScopedPrinter &W) const;
  340. void dumpAbbreviations(ScopedPrinter &W) const;
  341. bool dumpEntry(ScopedPrinter &W, uint64_t *Offset) const;
  342. void dumpName(ScopedPrinter &W, const NameTableEntry &NTE,
  343. std::optional<uint32_t> Hash) const;
  344. void dumpBucket(ScopedPrinter &W, uint32_t Bucket) const;
  345. Expected<AttributeEncoding> extractAttributeEncoding(uint64_t *Offset);
  346. Expected<std::vector<AttributeEncoding>>
  347. extractAttributeEncodings(uint64_t *Offset);
  348. Expected<Abbrev> extractAbbrev(uint64_t *Offset);
  349. public:
  350. NameIndex(const DWARFDebugNames &Section, uint64_t Base)
  351. : Section(Section), Base(Base) {}
  352. /// Reads offset of compilation unit CU. CU is 0-based.
  353. uint64_t getCUOffset(uint32_t CU) const;
  354. uint32_t getCUCount() const { return Hdr.CompUnitCount; }
  355. /// Reads offset of local type unit TU, TU is 0-based.
  356. uint64_t getLocalTUOffset(uint32_t TU) const;
  357. uint32_t getLocalTUCount() const { return Hdr.LocalTypeUnitCount; }
  358. /// Reads signature of foreign type unit TU. TU is 0-based.
  359. uint64_t getForeignTUSignature(uint32_t TU) const;
  360. uint32_t getForeignTUCount() const { return Hdr.ForeignTypeUnitCount; }
  361. /// Reads an entry in the Bucket Array for the given Bucket. The returned
  362. /// value is a (1-based) index into the Names, StringOffsets and
  363. /// EntryOffsets arrays. The input Bucket index is 0-based.
  364. uint32_t getBucketArrayEntry(uint32_t Bucket) const;
  365. uint32_t getBucketCount() const { return Hdr.BucketCount; }
  366. /// Reads an entry in the Hash Array for the given Index. The input Index
  367. /// is 1-based.
  368. uint32_t getHashArrayEntry(uint32_t Index) const;
  369. /// Reads an entry in the Name Table for the given Index. The Name Table
  370. /// consists of two arrays -- String Offsets and Entry Offsets. The returned
  371. /// offsets are relative to the starts of respective sections. Input Index
  372. /// is 1-based.
  373. NameTableEntry getNameTableEntry(uint32_t Index) const;
  374. uint32_t getNameCount() const { return Hdr.NameCount; }
  375. const DenseSet<Abbrev, AbbrevMapInfo> &getAbbrevs() const {
  376. return Abbrevs;
  377. }
  378. Expected<Entry> getEntry(uint64_t *Offset) const;
  379. /// Look up all entries in this Name Index matching \c Key.
  380. iterator_range<ValueIterator> equal_range(StringRef Key) const;
  381. NameIterator begin() const { return NameIterator(this, 1); }
  382. NameIterator end() const { return NameIterator(this, getNameCount() + 1); }
  383. Error extract();
  384. uint64_t getUnitOffset() const { return Base; }
  385. uint64_t getNextUnitOffset() const {
  386. return Base + dwarf::getUnitLengthFieldByteSize(Hdr.Format) +
  387. Hdr.UnitLength;
  388. }
  389. void dump(ScopedPrinter &W) const;
  390. friend class DWARFDebugNames;
  391. };
  392. class ValueIterator {
  393. public:
  394. using iterator_category = std::input_iterator_tag;
  395. using value_type = Entry;
  396. using difference_type = std::ptrdiff_t;
  397. using pointer = value_type *;
  398. using reference = value_type &;
  399. private:
  400. /// The Name Index we are currently iterating through. The implementation
  401. /// relies on the fact that this can also be used as an iterator into the
  402. /// "NameIndices" vector in the Accelerator section.
  403. const NameIndex *CurrentIndex = nullptr;
  404. /// Whether this is a local iterator (searches in CurrentIndex only) or not
  405. /// (searches all name indices).
  406. bool IsLocal;
  407. std::optional<Entry> CurrentEntry;
  408. uint64_t DataOffset = 0; ///< Offset into the section.
  409. std::string Key; ///< The Key we are searching for.
  410. std::optional<uint32_t> Hash; ///< Hash of Key, if it has been computed.
  411. bool getEntryAtCurrentOffset();
  412. std::optional<uint64_t> findEntryOffsetInCurrentIndex();
  413. bool findInCurrentIndex();
  414. void searchFromStartOfCurrentIndex();
  415. void next();
  416. /// Set the iterator to the "end" state.
  417. void setEnd() { *this = ValueIterator(); }
  418. public:
  419. /// Create a "begin" iterator for looping over all entries in the
  420. /// accelerator table matching Key. The iterator will run through all Name
  421. /// Indexes in the section in sequence.
  422. ValueIterator(const DWARFDebugNames &AccelTable, StringRef Key);
  423. /// Create a "begin" iterator for looping over all entries in a specific
  424. /// Name Index. Other indices in the section will not be visited.
  425. ValueIterator(const NameIndex &NI, StringRef Key);
  426. /// End marker.
  427. ValueIterator() = default;
  428. const Entry &operator*() const { return *CurrentEntry; }
  429. ValueIterator &operator++() {
  430. next();
  431. return *this;
  432. }
  433. ValueIterator operator++(int) {
  434. ValueIterator I = *this;
  435. next();
  436. return I;
  437. }
  438. friend bool operator==(const ValueIterator &A, const ValueIterator &B) {
  439. return A.CurrentIndex == B.CurrentIndex && A.DataOffset == B.DataOffset;
  440. }
  441. friend bool operator!=(const ValueIterator &A, const ValueIterator &B) {
  442. return !(A == B);
  443. }
  444. };
  445. class NameIterator {
  446. /// The Name Index we are iterating through.
  447. const NameIndex *CurrentIndex;
  448. /// The current name in the Name Index.
  449. uint32_t CurrentName;
  450. void next() {
  451. assert(CurrentName <= CurrentIndex->getNameCount());
  452. ++CurrentName;
  453. }
  454. public:
  455. using iterator_category = std::input_iterator_tag;
  456. using value_type = NameTableEntry;
  457. using difference_type = uint32_t;
  458. using pointer = NameTableEntry *;
  459. using reference = NameTableEntry; // We return entries by value.
  460. /// Creates an iterator whose initial position is name CurrentName in
  461. /// CurrentIndex.
  462. NameIterator(const NameIndex *CurrentIndex, uint32_t CurrentName)
  463. : CurrentIndex(CurrentIndex), CurrentName(CurrentName) {}
  464. NameTableEntry operator*() const {
  465. return CurrentIndex->getNameTableEntry(CurrentName);
  466. }
  467. NameIterator &operator++() {
  468. next();
  469. return *this;
  470. }
  471. NameIterator operator++(int) {
  472. NameIterator I = *this;
  473. next();
  474. return I;
  475. }
  476. friend bool operator==(const NameIterator &A, const NameIterator &B) {
  477. return A.CurrentIndex == B.CurrentIndex && A.CurrentName == B.CurrentName;
  478. }
  479. friend bool operator!=(const NameIterator &A, const NameIterator &B) {
  480. return !(A == B);
  481. }
  482. };
  483. private:
  484. SmallVector<NameIndex, 0> NameIndices;
  485. DenseMap<uint64_t, const NameIndex *> CUToNameIndex;
  486. public:
  487. DWARFDebugNames(const DWARFDataExtractor &AccelSection,
  488. DataExtractor StringSection)
  489. : DWARFAcceleratorTable(AccelSection, StringSection) {}
  490. Error extract() override;
  491. void dump(raw_ostream &OS) const override;
  492. /// Look up all entries in the accelerator table matching \c Key.
  493. iterator_range<ValueIterator> equal_range(StringRef Key) const;
  494. using const_iterator = SmallVector<NameIndex, 0>::const_iterator;
  495. const_iterator begin() const { return NameIndices.begin(); }
  496. const_iterator end() const { return NameIndices.end(); }
  497. /// Return the Name Index covering the compile unit at CUOffset, or nullptr if
  498. /// there is no Name Index covering that unit.
  499. const NameIndex *getCUNameIndex(uint64_t CUOffset);
  500. };
  501. } // end namespace llvm
  502. #endif // LLVM_DEBUGINFO_DWARF_DWARFACCELERATORTABLE_H
  503. #ifdef __GNUC__
  504. #pragma GCC diagnostic pop
  505. #endif