DWARFAcceleratorTable.h 21 KB

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