File indexing completed on 2026-05-10 08:43:41
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_DEBUGINFO_DWARF_DWARFACCELERATORTABLE_H
0010 #define LLVM_DEBUGINFO_DWARF_DWARFACCELERATORTABLE_H
0011
0012 #include "llvm/ADT/DenseSet.h"
0013 #include "llvm/ADT/SmallString.h"
0014 #include "llvm/ADT/SmallVector.h"
0015 #include "llvm/BinaryFormat/Dwarf.h"
0016 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
0017 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
0018 #include <cstdint>
0019 #include <utility>
0020
0021 namespace llvm {
0022
0023 class raw_ostream;
0024 class ScopedPrinter;
0025
0026
0027
0028
0029
0030
0031
0032 class DWARFAcceleratorTable {
0033 protected:
0034 DWARFDataExtractor AccelSection;
0035 DataExtractor StringSection;
0036
0037 public:
0038
0039 class Entry {
0040 protected:
0041 SmallVector<DWARFFormValue, 3> Values;
0042
0043 Entry() = default;
0044
0045
0046 Entry(const Entry &) = default;
0047 Entry(Entry &&) = default;
0048 Entry &operator=(const Entry &) = default;
0049 Entry &operator=(Entry &&) = default;
0050 ~Entry() = default;
0051
0052
0053 public:
0054
0055
0056
0057 virtual std::optional<uint64_t> getCUOffset() const = 0;
0058
0059
0060
0061
0062 virtual std::optional<uint64_t> getLocalTUOffset() const {
0063
0064 return std::nullopt;
0065 }
0066
0067
0068
0069
0070 virtual std::optional<uint64_t> getForeignTUTypeSignature() const {
0071
0072 return std::nullopt;
0073 }
0074
0075
0076
0077
0078 virtual std::optional<dwarf::Tag> getTag() const = 0;
0079
0080
0081
0082
0083 ArrayRef<DWARFFormValue> getValues() const { return Values; }
0084 };
0085
0086 DWARFAcceleratorTable(const DWARFDataExtractor &AccelSection,
0087 DataExtractor StringSection)
0088 : AccelSection(AccelSection), StringSection(StringSection) {}
0089 virtual ~DWARFAcceleratorTable();
0090
0091 virtual Error extract() = 0;
0092 virtual void dump(raw_ostream &OS) const = 0;
0093
0094 DWARFAcceleratorTable(const DWARFAcceleratorTable &) = delete;
0095 void operator=(const DWARFAcceleratorTable &) = delete;
0096 };
0097
0098
0099
0100 class AppleAcceleratorTable : public DWARFAcceleratorTable {
0101 struct Header {
0102 uint32_t Magic;
0103 uint16_t Version;
0104 uint16_t HashFunction;
0105 uint32_t BucketCount;
0106 uint32_t HashCount;
0107 uint32_t HeaderDataLength;
0108
0109 void dump(ScopedPrinter &W) const;
0110 };
0111
0112 struct HeaderData {
0113 using AtomType = uint16_t;
0114 using Form = dwarf::Form;
0115
0116 uint64_t DIEOffsetBase;
0117 SmallVector<std::pair<AtomType, Form>, 3> Atoms;
0118
0119 std::optional<uint64_t>
0120 extractOffset(std::optional<DWARFFormValue> Value) const;
0121 };
0122
0123 Header Hdr;
0124 HeaderData HdrData;
0125 dwarf::FormParams FormParams;
0126 uint32_t HashDataEntryLength;
0127 bool IsValid = false;
0128
0129
0130
0131 bool dumpName(ScopedPrinter &W, SmallVectorImpl<DWARFFormValue> &AtomForms,
0132 uint64_t *DataOffset) const;
0133
0134
0135
0136 std::optional<uint32_t> readU32FromAccel(uint64_t &Offset,
0137 bool UseRelocation = false) const;
0138
0139
0140 std::optional<StringRef>
0141 readStringFromStrSection(uint64_t StringSectionOffset) const;
0142
0143
0144 uint64_t getBucketBase() const { return sizeof(Hdr) + Hdr.HeaderDataLength; }
0145
0146
0147 uint64_t getIthBucketBase(uint32_t I) const {
0148 return getBucketBase() + I * 4;
0149 }
0150
0151
0152 uint64_t getHashBase() const { return getBucketBase() + getNumBuckets() * 4; }
0153
0154
0155 uint64_t getIthHashBase(uint32_t I) const { return getHashBase() + I * 4; }
0156
0157
0158 uint64_t getOffsetBase() const { return getHashBase() + getNumHashes() * 4; }
0159
0160
0161 uint64_t getEntriesBase() const {
0162 return getOffsetBase() + getNumHashes() * 4;
0163 }
0164
0165
0166 uint64_t getIthOffsetBase(uint32_t I) const {
0167 return getOffsetBase() + I * 4;
0168 }
0169
0170
0171 uint32_t hashToBucketIdx(uint32_t Hash) const {
0172 return Hash % getNumBuckets();
0173 }
0174
0175
0176
0177 bool wouldHashBeInBucket(uint32_t Hash, uint32_t BucketIdx) const {
0178 return hashToBucketIdx(Hash) == BucketIdx;
0179 }
0180
0181
0182
0183 std::optional<uint32_t> readIthBucket(uint32_t I) const {
0184 uint64_t Offset = getIthBucketBase(I);
0185 return readU32FromAccel(Offset);
0186 }
0187
0188
0189 std::optional<uint32_t> readIthHash(uint32_t I) const {
0190 uint64_t Offset = getIthHashBase(I);
0191 return readU32FromAccel(Offset);
0192 }
0193
0194
0195 std::optional<uint32_t> readIthOffset(uint32_t I) const {
0196 uint64_t Offset = getIthOffsetBase(I);
0197 return readU32FromAccel(Offset);
0198 }
0199
0200
0201
0202 std::optional<uint32_t> readStringOffsetAt(uint64_t &Offset) const {
0203 return readU32FromAccel(Offset, true);
0204 }
0205
0206
0207
0208 std::optional<uint32_t> idxOfHashInBucket(uint32_t HashToFind,
0209 uint32_t BucketIdx) const;
0210
0211 public:
0212
0213 class Entry final : public DWARFAcceleratorTable::Entry {
0214 const AppleAcceleratorTable &Table;
0215
0216 Entry(const AppleAcceleratorTable &Table);
0217 void extract(uint64_t *Offset);
0218
0219 public:
0220 std::optional<uint64_t> getCUOffset() const override;
0221
0222
0223
0224
0225
0226 std::optional<uint64_t> getDIESectionOffset() const;
0227
0228 std::optional<dwarf::Tag> getTag() const override;
0229
0230
0231
0232 std::optional<DWARFFormValue> lookup(HeaderData::AtomType Atom) const;
0233
0234 friend class AppleAcceleratorTable;
0235 friend class ValueIterator;
0236 };
0237
0238
0239 class SameNameIterator
0240 : public iterator_facade_base<SameNameIterator, std::forward_iterator_tag,
0241 Entry> {
0242 Entry Current;
0243 uint64_t Offset = 0;
0244
0245 public:
0246
0247 SameNameIterator(const AppleAcceleratorTable &AccelTable,
0248 uint64_t DataOffset);
0249
0250 const Entry &operator*() {
0251 uint64_t OffsetCopy = Offset;
0252 Current.extract(&OffsetCopy);
0253 return Current;
0254 }
0255 SameNameIterator &operator++() {
0256 Offset += Current.Table.getHashDataEntryLength();
0257 return *this;
0258 }
0259 friend bool operator==(const SameNameIterator &A,
0260 const SameNameIterator &B) {
0261 return A.Offset == B.Offset;
0262 }
0263 };
0264
0265 struct EntryWithName {
0266 EntryWithName(const AppleAcceleratorTable &Table)
0267 : BaseEntry(Table), StrOffset(0) {}
0268
0269 std::optional<StringRef> readName() const {
0270 return BaseEntry.Table.readStringFromStrSection(StrOffset);
0271 }
0272
0273 Entry BaseEntry;
0274 uint32_t StrOffset;
0275 };
0276
0277
0278 class Iterator
0279 : public iterator_facade_base<Iterator, std::forward_iterator_tag,
0280 EntryWithName> {
0281 constexpr static auto EndMarker = std::numeric_limits<uint64_t>::max();
0282
0283 EntryWithName Current;
0284 uint64_t Offset = EndMarker;
0285 uint32_t NumEntriesToCome = 0;
0286
0287 void setToEnd() { Offset = EndMarker; }
0288 bool isEnd() const { return Offset == EndMarker; }
0289 const AppleAcceleratorTable &getTable() const {
0290 return Current.BaseEntry.Table;
0291 }
0292
0293
0294
0295 void prepareNextEntryOrEnd();
0296
0297
0298
0299
0300
0301 void prepareNextStringOrEnd();
0302
0303 public:
0304 Iterator(const AppleAcceleratorTable &Table, bool SetEnd = false);
0305
0306 Iterator &operator++() {
0307 prepareNextEntryOrEnd();
0308 return *this;
0309 }
0310 bool operator==(const Iterator &It) const { return Offset == It.Offset; }
0311 const EntryWithName &operator*() const {
0312 assert(!isEnd() && "dereferencing end iterator");
0313 return Current;
0314 }
0315 };
0316
0317 AppleAcceleratorTable(const DWARFDataExtractor &AccelSection,
0318 DataExtractor StringSection)
0319 : DWARFAcceleratorTable(AccelSection, StringSection) {}
0320
0321 Error extract() override;
0322 uint32_t getNumBuckets() const;
0323 uint32_t getNumHashes() const;
0324 uint32_t getSizeHdr() const;
0325 uint32_t getHeaderDataLength() const;
0326
0327
0328 uint32_t getHashDataEntryLength() const { return HashDataEntryLength; }
0329
0330
0331
0332 ArrayRef<std::pair<HeaderData::AtomType, HeaderData::Form>> getAtomsDesc();
0333
0334
0335
0336 bool containsAtomType(HeaderData::AtomType AtomTy) const {
0337 return is_contained(make_first_range(HdrData.Atoms), AtomTy);
0338 }
0339
0340 bool validateForms();
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350 std::pair<uint64_t, dwarf::Tag> readAtoms(uint64_t *HashDataOffset);
0351 void dump(raw_ostream &OS) const override;
0352
0353
0354 iterator_range<SameNameIterator> equal_range(StringRef Key) const;
0355
0356
0357 auto entries() const {
0358 return make_range(Iterator(*this), Iterator(*this, true));
0359 }
0360 };
0361
0362
0363
0364
0365
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383 class DWARFDebugNames : public DWARFAcceleratorTable {
0384 public:
0385 class NameIndex;
0386 class NameIterator;
0387 class ValueIterator;
0388
0389
0390 struct Header {
0391 uint64_t UnitLength;
0392 dwarf::DwarfFormat Format;
0393 uint16_t Version;
0394 uint32_t CompUnitCount;
0395 uint32_t LocalTypeUnitCount;
0396 uint32_t ForeignTypeUnitCount;
0397 uint32_t BucketCount;
0398 uint32_t NameCount;
0399 uint32_t AbbrevTableSize;
0400 uint32_t AugmentationStringSize;
0401 SmallString<8> AugmentationString;
0402
0403 Error extract(const DWARFDataExtractor &AS, uint64_t *Offset);
0404 void dump(ScopedPrinter &W) const;
0405 };
0406
0407
0408 struct AttributeEncoding {
0409 dwarf::Index Index;
0410 dwarf::Form Form;
0411
0412 constexpr AttributeEncoding(dwarf::Index Index, dwarf::Form Form)
0413 : Index(Index), Form(Form) {}
0414
0415 friend bool operator==(const AttributeEncoding &LHS,
0416 const AttributeEncoding &RHS) {
0417 return LHS.Index == RHS.Index && LHS.Form == RHS.Form;
0418 }
0419 };
0420
0421
0422 struct Abbrev {
0423 uint64_t AbbrevOffset;
0424 uint32_t Code;
0425 dwarf::Tag Tag;
0426 std::vector<AttributeEncoding> Attributes;
0427
0428 Abbrev(uint32_t Code, dwarf::Tag Tag, uint64_t AbbrevOffset,
0429 std::vector<AttributeEncoding> Attributes)
0430 : AbbrevOffset(AbbrevOffset), Code(Code), Tag(Tag),
0431 Attributes(std::move(Attributes)) {}
0432
0433 void dump(ScopedPrinter &W) const;
0434 };
0435
0436
0437 class Entry final : public DWARFAcceleratorTable::Entry {
0438 const NameIndex *NameIdx;
0439 const Abbrev *Abbr;
0440
0441 Entry(const NameIndex &NameIdx, const Abbrev &Abbr);
0442
0443 public:
0444 const NameIndex *getNameIndex() const { return NameIdx; }
0445 std::optional<uint64_t> getCUOffset() const override;
0446 std::optional<uint64_t> getLocalTUOffset() const override;
0447 std::optional<uint64_t> getForeignTUTypeSignature() const override;
0448 std::optional<dwarf::Tag> getTag() const override { return tag(); }
0449
0450
0451
0452
0453 std::optional<uint64_t> getRelatedCUOffset() const;
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464 std::optional<uint64_t> getCUIndex() const;
0465
0466
0467
0468
0469 std::optional<uint64_t> getRelatedCUIndex() const;
0470
0471
0472
0473
0474
0475
0476
0477 std::optional<uint64_t> getTUIndex() const;
0478
0479
0480
0481 dwarf::Tag tag() const { return Abbr->Tag; }
0482
0483
0484 std::optional<uint64_t> getDIEUnitOffset() const;
0485
0486
0487
0488 bool hasParentInformation() const;
0489
0490
0491
0492
0493
0494 Expected<std::optional<DWARFDebugNames::Entry>> getParentDIEEntry() const;
0495
0496
0497
0498 const Abbrev &getAbbrev() const { return *Abbr; }
0499
0500
0501
0502 std::optional<DWARFFormValue> lookup(dwarf::Index Index) const;
0503
0504 void dump(ScopedPrinter &W) const;
0505 void dumpParentIdx(ScopedPrinter &W, const DWARFFormValue &FormValue) const;
0506
0507 friend class NameIndex;
0508 friend class ValueIterator;
0509 };
0510
0511
0512
0513 class SentinelError : public ErrorInfo<SentinelError> {
0514 public:
0515 static char ID;
0516
0517 void log(raw_ostream &OS) const override { OS << "Sentinel"; }
0518 std::error_code convertToErrorCode() const override;
0519 };
0520
0521 private:
0522
0523 struct AbbrevMapInfo {
0524 static Abbrev getEmptyKey();
0525 static Abbrev getTombstoneKey();
0526 static unsigned getHashValue(uint32_t Code) {
0527 return DenseMapInfo<uint32_t>::getHashValue(Code);
0528 }
0529 static unsigned getHashValue(const Abbrev &Abbr) {
0530 return getHashValue(Abbr.Code);
0531 }
0532 static bool isEqual(uint32_t LHS, const Abbrev &RHS) {
0533 return LHS == RHS.Code;
0534 }
0535 static bool isEqual(const Abbrev &LHS, const Abbrev &RHS) {
0536 return LHS.Code == RHS.Code;
0537 }
0538 };
0539
0540 public:
0541
0542
0543 class NameTableEntry {
0544 DataExtractor StrData;
0545
0546 uint32_t Index;
0547 uint64_t StringOffset;
0548 uint64_t EntryOffset;
0549
0550 public:
0551 NameTableEntry(const DataExtractor &StrData, uint32_t Index,
0552 uint64_t StringOffset, uint64_t EntryOffset)
0553 : StrData(StrData), Index(Index), StringOffset(StringOffset),
0554 EntryOffset(EntryOffset) {}
0555
0556
0557 uint32_t getIndex() const { return Index; }
0558
0559
0560 uint64_t getStringOffset() const { return StringOffset; }
0561
0562
0563
0564 const char *getString() const {
0565 uint64_t Off = StringOffset;
0566 return StrData.getCStr(&Off);
0567 }
0568
0569
0570
0571
0572 bool sameNameAs(StringRef Target) const {
0573
0574
0575
0576 StringRef Data = StrData.getData().substr(StringOffset);
0577 size_t TargetSize = Target.size();
0578 return Data.size() > TargetSize && !Data[TargetSize] &&
0579 strncmp(Data.data(), Target.data(), TargetSize) == 0;
0580 }
0581
0582
0583 uint64_t getEntryOffset() const { return EntryOffset; }
0584 };
0585
0586
0587
0588 struct DWARFDebugNamesOffsets {
0589 uint64_t CUsBase;
0590 uint64_t BucketsBase;
0591 uint64_t HashesBase;
0592 uint64_t StringOffsetsBase;
0593 uint64_t EntryOffsetsBase;
0594 uint64_t EntriesBase;
0595 };
0596
0597
0598
0599 class NameIndex {
0600 DenseSet<Abbrev, AbbrevMapInfo> Abbrevs;
0601 struct Header Hdr;
0602 const DWARFDebugNames &Section;
0603
0604
0605
0606 uint64_t Base;
0607 DWARFDebugNamesOffsets Offsets;
0608
0609 void dumpCUs(ScopedPrinter &W) const;
0610 void dumpLocalTUs(ScopedPrinter &W) const;
0611 void dumpForeignTUs(ScopedPrinter &W) const;
0612 void dumpAbbreviations(ScopedPrinter &W) const;
0613 bool dumpEntry(ScopedPrinter &W, uint64_t *Offset) const;
0614 void dumpName(ScopedPrinter &W, const NameTableEntry &NTE,
0615 std::optional<uint32_t> Hash) const;
0616 void dumpBucket(ScopedPrinter &W, uint32_t Bucket) const;
0617
0618 Expected<AttributeEncoding> extractAttributeEncoding(uint64_t *Offset);
0619
0620 Expected<std::vector<AttributeEncoding>>
0621 extractAttributeEncodings(uint64_t *Offset);
0622
0623 Expected<Abbrev> extractAbbrev(uint64_t *Offset);
0624
0625 public:
0626 NameIndex(const DWARFDebugNames &Section, uint64_t Base)
0627 : Section(Section), Base(Base) {}
0628
0629
0630 Header getHeader() const { return Hdr; }
0631
0632
0633 DWARFDebugNamesOffsets getOffsets() const { return Offsets; }
0634
0635
0636 uint64_t getCUOffset(uint32_t CU) const;
0637 uint32_t getCUCount() const { return Hdr.CompUnitCount; }
0638
0639
0640 uint64_t getLocalTUOffset(uint32_t TU) const;
0641 uint32_t getLocalTUCount() const { return Hdr.LocalTypeUnitCount; }
0642
0643
0644 uint64_t getForeignTUSignature(uint32_t TU) const;
0645 uint32_t getForeignTUCount() const { return Hdr.ForeignTypeUnitCount; }
0646
0647
0648
0649
0650 uint32_t getBucketArrayEntry(uint32_t Bucket) const;
0651 uint32_t getBucketCount() const { return Hdr.BucketCount; }
0652
0653
0654
0655 uint32_t getHashArrayEntry(uint32_t Index) const;
0656
0657
0658
0659
0660
0661 NameTableEntry getNameTableEntry(uint32_t Index) const;
0662
0663 uint32_t getNameCount() const { return Hdr.NameCount; }
0664
0665 const DenseSet<Abbrev, AbbrevMapInfo> &getAbbrevs() const {
0666 return Abbrevs;
0667 }
0668
0669 Expected<Entry> getEntry(uint64_t *Offset) const;
0670
0671
0672
0673 Expected<Entry> getEntryAtRelativeOffset(uint64_t Offset) const {
0674 auto OffsetFromSection = Offset + this->Offsets.EntriesBase;
0675 return getEntry(&OffsetFromSection);
0676 }
0677
0678
0679 iterator_range<ValueIterator> equal_range(StringRef Key) const;
0680
0681 NameIterator begin() const { return NameIterator(this, 1); }
0682 NameIterator end() const { return NameIterator(this, getNameCount() + 1); }
0683
0684 Error extract();
0685 uint64_t getUnitOffset() const { return Base; }
0686 uint64_t getNextUnitOffset() const {
0687 return Base + dwarf::getUnitLengthFieldByteSize(Hdr.Format) +
0688 Hdr.UnitLength;
0689 }
0690 void dump(ScopedPrinter &W) const;
0691
0692 friend class DWARFDebugNames;
0693 };
0694
0695 class ValueIterator {
0696 public:
0697 using iterator_category = std::input_iterator_tag;
0698 using value_type = Entry;
0699 using difference_type = std::ptrdiff_t;
0700 using pointer = value_type *;
0701 using reference = value_type &;
0702
0703 private:
0704
0705
0706
0707 const NameIndex *CurrentIndex = nullptr;
0708
0709
0710
0711 bool IsLocal;
0712
0713 std::optional<Entry> CurrentEntry;
0714 uint64_t DataOffset = 0;
0715 std::string Key;
0716 std::optional<uint32_t> Hash;
0717
0718 bool getEntryAtCurrentOffset();
0719 std::optional<uint64_t> findEntryOffsetInCurrentIndex();
0720 bool findInCurrentIndex();
0721 void searchFromStartOfCurrentIndex();
0722 void next();
0723
0724
0725 void setEnd() { *this = ValueIterator(); }
0726
0727 public:
0728
0729
0730
0731 ValueIterator(const DWARFDebugNames &AccelTable, StringRef Key);
0732
0733
0734
0735 ValueIterator(const NameIndex &NI, StringRef Key);
0736
0737
0738 ValueIterator() = default;
0739
0740 const Entry &operator*() const { return *CurrentEntry; }
0741 ValueIterator &operator++() {
0742 next();
0743 return *this;
0744 }
0745 ValueIterator operator++(int) {
0746 ValueIterator I = *this;
0747 next();
0748 return I;
0749 }
0750
0751 friend bool operator==(const ValueIterator &A, const ValueIterator &B) {
0752 return A.CurrentIndex == B.CurrentIndex && A.DataOffset == B.DataOffset;
0753 }
0754 friend bool operator!=(const ValueIterator &A, const ValueIterator &B) {
0755 return !(A == B);
0756 }
0757 };
0758
0759 class NameIterator {
0760
0761
0762 const NameIndex *CurrentIndex;
0763
0764
0765 uint32_t CurrentName;
0766
0767 void next() {
0768 assert(CurrentName <= CurrentIndex->getNameCount());
0769 ++CurrentName;
0770 }
0771
0772 public:
0773 using iterator_category = std::input_iterator_tag;
0774 using value_type = NameTableEntry;
0775 using difference_type = uint32_t;
0776 using pointer = NameTableEntry *;
0777 using reference = NameTableEntry;
0778
0779
0780
0781 NameIterator(const NameIndex *CurrentIndex, uint32_t CurrentName)
0782 : CurrentIndex(CurrentIndex), CurrentName(CurrentName) {}
0783
0784 NameTableEntry operator*() const {
0785 return CurrentIndex->getNameTableEntry(CurrentName);
0786 }
0787 NameIterator &operator++() {
0788 next();
0789 return *this;
0790 }
0791 NameIterator operator++(int) {
0792 NameIterator I = *this;
0793 next();
0794 return I;
0795 }
0796
0797 friend bool operator==(const NameIterator &A, const NameIterator &B) {
0798 return A.CurrentIndex == B.CurrentIndex && A.CurrentName == B.CurrentName;
0799 }
0800 friend bool operator!=(const NameIterator &A, const NameIterator &B) {
0801 return !(A == B);
0802 }
0803 };
0804
0805 private:
0806 SmallVector<NameIndex, 0> NameIndices;
0807 DenseMap<uint64_t, const NameIndex *> UnitOffsetToNameIndex;
0808
0809 public:
0810 DWARFDebugNames(const DWARFDataExtractor &AccelSection,
0811 DataExtractor StringSection)
0812 : DWARFAcceleratorTable(AccelSection, StringSection) {}
0813
0814 Error extract() override;
0815 void dump(raw_ostream &OS) const override;
0816
0817
0818 iterator_range<ValueIterator> equal_range(StringRef Key) const;
0819
0820 using const_iterator = SmallVector<NameIndex, 0>::const_iterator;
0821 const_iterator begin() const { return NameIndices.begin(); }
0822 const_iterator end() const { return NameIndices.end(); }
0823
0824
0825
0826 const NameIndex *getCUOrTUNameIndex(uint64_t UnitOffset);
0827 };
0828
0829
0830
0831 namespace dwarf {
0832 DWARFDebugNames::DWARFDebugNamesOffsets
0833 findDebugNamesOffsets(uint64_t EndOfHeaderOffset,
0834 const DWARFDebugNames::Header &Hdr);
0835 }
0836
0837
0838
0839
0840
0841 std::optional<StringRef> StripTemplateParameters(StringRef Name);
0842
0843 struct ObjCSelectorNames {
0844
0845 StringRef Selector;
0846
0847 StringRef ClassName;
0848
0849 std::optional<StringRef> ClassNameNoCategory;
0850
0851 std::optional<std::string> MethodNameNoCategory;
0852 };
0853
0854
0855
0856
0857 std::optional<ObjCSelectorNames> getObjCNamesIfSelector(StringRef Name);
0858
0859 }
0860
0861 #endif