Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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