File indexing completed on 2026-05-10 08:43:41
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_DEBUGINFO_DWARF_DWARFDIE_H
0010 #define LLVM_DEBUGINFO_DWARF_DWARFDIE_H
0011
0012 #include "llvm/ADT/ArrayRef.h"
0013 #include "llvm/ADT/iterator.h"
0014 #include "llvm/ADT/iterator_range.h"
0015 #include "llvm/BinaryFormat/Dwarf.h"
0016 #include "llvm/DebugInfo/DIContext.h"
0017 #include "llvm/DebugInfo/DWARF/DWARFAddressRange.h"
0018 #include "llvm/DebugInfo/DWARF/DWARFAttribute.h"
0019 #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h"
0020 #include "llvm/DebugInfo/DWARF/DWARFLocationExpression.h"
0021 #include <cassert>
0022 #include <cstdint>
0023 #include <iterator>
0024
0025 namespace llvm {
0026
0027 class DWARFUnit;
0028 class raw_ostream;
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 class DWARFDie {
0043 DWARFUnit *U = nullptr;
0044 const DWARFDebugInfoEntry *Die = nullptr;
0045
0046 public:
0047 using DWARFFormValue = llvm::DWARFFormValue;
0048 DWARFDie() = default;
0049 DWARFDie(DWARFUnit *Unit, const DWARFDebugInfoEntry *D) : U(Unit), Die(D) {}
0050
0051 bool isValid() const { return U && Die; }
0052 explicit operator bool() const { return isValid(); }
0053 const DWARFDebugInfoEntry *getDebugInfoEntry() const { return Die; }
0054 DWARFUnit *getDwarfUnit() const { return U; }
0055
0056
0057
0058
0059 const DWARFAbbreviationDeclaration *getAbbreviationDeclarationPtr() const {
0060 assert(isValid() && "must check validity prior to calling");
0061 return Die->getAbbreviationDeclarationPtr();
0062 }
0063
0064
0065
0066
0067 uint64_t getOffset() const {
0068 assert(isValid() && "must check validity prior to calling");
0069 return Die->getOffset();
0070 }
0071
0072 dwarf::Tag getTag() const {
0073 auto AbbrevDecl = getAbbreviationDeclarationPtr();
0074 if (AbbrevDecl)
0075 return AbbrevDecl->getTag();
0076 return dwarf::DW_TAG_null;
0077 }
0078
0079 bool hasChildren() const {
0080 assert(isValid() && "must check validity prior to calling");
0081 return Die->hasChildren();
0082 }
0083
0084
0085 bool isNULL() const { return getAbbreviationDeclarationPtr() == nullptr; }
0086
0087
0088 bool isSubprogramDIE() const;
0089
0090
0091 bool isSubroutineDIE() const;
0092
0093
0094
0095
0096
0097 DWARFDie getParent() const;
0098
0099
0100
0101
0102
0103 DWARFDie getSibling() const;
0104
0105
0106
0107
0108
0109 DWARFDie getPreviousSibling() const;
0110
0111
0112
0113
0114
0115 DWARFDie getFirstChild() const;
0116
0117
0118
0119
0120
0121 DWARFDie getLastChild() const;
0122
0123
0124
0125
0126
0127 void dump(raw_ostream &OS, unsigned indent = 0,
0128 DIDumpOptions DumpOpts = DIDumpOptions()) const;
0129
0130
0131 LLVM_DUMP_METHOD void dump() const;
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 std::optional<DWARFFormValue> find(dwarf::Attribute Attr) const;
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155 std::optional<DWARFFormValue> find(ArrayRef<dwarf::Attribute> Attrs) const;
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166 std::optional<DWARFFormValue>
0167 findRecursively(ArrayRef<dwarf::Attribute> Attrs) const;
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182 DWARFDie getAttributeValueAsReferencedDie(dwarf::Attribute Attr) const;
0183 DWARFDie getAttributeValueAsReferencedDie(const DWARFFormValue &V) const;
0184
0185 DWARFDie resolveTypeUnitReference() const;
0186
0187 DWARFDie resolveReferencedType(dwarf::Attribute Attr) const;
0188 DWARFDie resolveReferencedType(const DWARFFormValue &V) const;
0189
0190
0191
0192
0193
0194
0195 std::optional<uint64_t> getRangesBaseAttribute() const;
0196 std::optional<uint64_t> getLocBaseAttribute() const;
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208 std::optional<uint64_t> getHighPC(uint64_t LowPC) const;
0209
0210
0211
0212 bool getLowAndHighPC(uint64_t &LowPC, uint64_t &HighPC,
0213 uint64_t &SectionIndex) const;
0214
0215
0216
0217
0218
0219
0220
0221
0222
0223
0224
0225 Expected<DWARFAddressRangesVector> getAddressRanges() const;
0226
0227 bool addressRangeContainsAddress(const uint64_t Address) const;
0228
0229 std::optional<uint64_t> getLanguage() const;
0230
0231 Expected<DWARFLocationExpressionsVector>
0232 getLocations(dwarf::Attribute Attr) const;
0233
0234
0235
0236
0237
0238 const char *getSubroutineName(DINameKind Kind) const;
0239
0240
0241
0242
0243
0244 const char *getName(DINameKind Kind) const;
0245 void getFullName(raw_string_ostream &,
0246 std::string *OriginalFullName = nullptr) const;
0247
0248
0249
0250
0251 const char *getShortName() const;
0252
0253
0254
0255
0256 const char *getLinkageName() const;
0257
0258
0259
0260
0261
0262 uint64_t getDeclLine() const;
0263 std::string getDeclFile(DILineInfoSpecifier::FileLineInfoKind Kind) const;
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277 void getCallerFrame(uint32_t &CallFile, uint32_t &CallLine,
0278 uint32_t &CallColumn, uint32_t &CallDiscriminator) const;
0279
0280 class attribute_iterator;
0281
0282
0283
0284
0285 iterator_range<attribute_iterator> attributes() const;
0286
0287
0288
0289
0290
0291
0292 std::optional<uint64_t> getTypeSize(uint64_t PointerSize);
0293
0294 class iterator;
0295
0296 iterator begin() const;
0297 iterator end() const;
0298
0299 std::reverse_iterator<iterator> rbegin() const;
0300 std::reverse_iterator<iterator> rend() const;
0301
0302 iterator_range<iterator> children() const;
0303 };
0304
0305 class DWARFDie::attribute_iterator
0306 : public iterator_facade_base<attribute_iterator, std::forward_iterator_tag,
0307 const DWARFAttribute> {
0308
0309 DWARFDie Die;
0310
0311 DWARFAttribute AttrValue;
0312
0313 uint32_t Index;
0314
0315 friend bool operator==(const attribute_iterator &LHS,
0316 const attribute_iterator &RHS);
0317
0318
0319
0320
0321
0322
0323 void updateForIndex(const DWARFAbbreviationDeclaration &AbbrDecl, uint32_t I);
0324
0325 public:
0326 attribute_iterator() = delete;
0327 explicit attribute_iterator(DWARFDie D, bool End);
0328
0329 attribute_iterator &operator++();
0330 attribute_iterator &operator--();
0331 explicit operator bool() const { return AttrValue.isValid(); }
0332 const DWARFAttribute &operator*() const { return AttrValue; }
0333 };
0334
0335 inline bool operator==(const DWARFDie::attribute_iterator &LHS,
0336 const DWARFDie::attribute_iterator &RHS) {
0337 return LHS.Index == RHS.Index;
0338 }
0339
0340 inline bool operator!=(const DWARFDie::attribute_iterator &LHS,
0341 const DWARFDie::attribute_iterator &RHS) {
0342 return !(LHS == RHS);
0343 }
0344
0345 inline bool operator==(const DWARFDie &LHS, const DWARFDie &RHS) {
0346 return LHS.getDebugInfoEntry() == RHS.getDebugInfoEntry() &&
0347 LHS.getDwarfUnit() == RHS.getDwarfUnit();
0348 }
0349
0350 inline bool operator!=(const DWARFDie &LHS, const DWARFDie &RHS) {
0351 return !(LHS == RHS);
0352 }
0353
0354 inline bool operator<(const DWARFDie &LHS, const DWARFDie &RHS) {
0355 return LHS.getOffset() < RHS.getOffset();
0356 }
0357
0358 class DWARFDie::iterator
0359 : public iterator_facade_base<iterator, std::bidirectional_iterator_tag,
0360 const DWARFDie> {
0361 DWARFDie Die;
0362
0363 friend std::reverse_iterator<llvm::DWARFDie::iterator>;
0364 friend bool operator==(const DWARFDie::iterator &LHS,
0365 const DWARFDie::iterator &RHS);
0366
0367 public:
0368 iterator() = default;
0369
0370 explicit iterator(DWARFDie D) : Die(D) {}
0371
0372 iterator &operator++() {
0373 Die = Die.getSibling();
0374 return *this;
0375 }
0376
0377 iterator &operator--() {
0378 Die = Die.getPreviousSibling();
0379 return *this;
0380 }
0381
0382 const DWARFDie &operator*() const { return Die; }
0383 };
0384
0385 inline bool operator==(const DWARFDie::iterator &LHS,
0386 const DWARFDie::iterator &RHS) {
0387 return LHS.Die == RHS.Die;
0388 }
0389
0390
0391
0392 inline DWARFDie::iterator DWARFDie::begin() const {
0393 return iterator(getFirstChild());
0394 }
0395
0396 inline DWARFDie::iterator DWARFDie::end() const {
0397 return iterator(getLastChild());
0398 }
0399
0400 inline iterator_range<DWARFDie::iterator> DWARFDie::children() const {
0401 return make_range(begin(), end());
0402 }
0403
0404 }
0405
0406 namespace std {
0407
0408 template <>
0409 class reverse_iterator<llvm::DWARFDie::iterator>
0410 : public llvm::iterator_facade_base<
0411 reverse_iterator<llvm::DWARFDie::iterator>,
0412 bidirectional_iterator_tag, const llvm::DWARFDie> {
0413
0414 private:
0415 llvm::DWARFDie Die;
0416 bool AtEnd;
0417
0418 public:
0419 reverse_iterator(llvm::DWARFDie::iterator It)
0420 : Die(It.Die), AtEnd(!It.Die.getPreviousSibling()) {
0421 if (!AtEnd)
0422 Die = Die.getPreviousSibling();
0423 }
0424
0425 llvm::DWARFDie::iterator base() const {
0426 return llvm::DWARFDie::iterator(AtEnd ? Die : Die.getSibling());
0427 }
0428
0429 reverse_iterator<llvm::DWARFDie::iterator> &operator++() {
0430 assert(!AtEnd && "Incrementing rend");
0431 llvm::DWARFDie D = Die.getPreviousSibling();
0432 if (D)
0433 Die = D;
0434 else
0435 AtEnd = true;
0436 return *this;
0437 }
0438
0439 reverse_iterator<llvm::DWARFDie::iterator> &operator--() {
0440 if (AtEnd) {
0441 AtEnd = false;
0442 return *this;
0443 }
0444 Die = Die.getSibling();
0445 assert(!Die.isNULL() && "Decrementing rbegin");
0446 return *this;
0447 }
0448
0449 const llvm::DWARFDie &operator*() const {
0450 assert(Die.isValid());
0451 return Die;
0452 }
0453
0454
0455
0456
0457 bool equals(const reverse_iterator<llvm::DWARFDie::iterator> &RHS) const {
0458 return Die == RHS.Die && AtEnd == RHS.AtEnd;
0459 }
0460 };
0461
0462 }
0463
0464 namespace llvm {
0465
0466 inline bool operator==(const std::reverse_iterator<DWARFDie::iterator> &LHS,
0467 const std::reverse_iterator<DWARFDie::iterator> &RHS) {
0468 return LHS.equals(RHS);
0469 }
0470
0471 inline bool operator!=(const std::reverse_iterator<DWARFDie::iterator> &LHS,
0472 const std::reverse_iterator<DWARFDie::iterator> &RHS) {
0473 return !(LHS == RHS);
0474 }
0475
0476 inline std::reverse_iterator<DWARFDie::iterator> DWARFDie::rbegin() const {
0477 return std::make_reverse_iterator(end());
0478 }
0479
0480 inline std::reverse_iterator<DWARFDie::iterator> DWARFDie::rend() const {
0481 return std::make_reverse_iterator(begin());
0482 }
0483
0484 void dumpTypeQualifiedName(const DWARFDie &DIE, raw_ostream &OS);
0485 void dumpTypeUnqualifiedName(const DWARFDie &DIE, raw_ostream &OS,
0486 std::string *OriginalFullName = nullptr);
0487
0488 }
0489
0490 #endif