Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

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