File indexing completed on 2026-05-10 08:43:28
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_CODEGEN_DIE_H
0014 #define LLVM_CODEGEN_DIE_H
0015
0016 #include "llvm/ADT/FoldingSet.h"
0017 #include "llvm/ADT/PointerIntPair.h"
0018 #include "llvm/ADT/PointerUnion.h"
0019 #include "llvm/ADT/SmallVector.h"
0020 #include "llvm/ADT/StringRef.h"
0021 #include "llvm/ADT/iterator.h"
0022 #include "llvm/ADT/iterator_range.h"
0023 #include "llvm/BinaryFormat/Dwarf.h"
0024 #include "llvm/CodeGen/DwarfStringPoolEntry.h"
0025 #include "llvm/Support/AlignOf.h"
0026 #include "llvm/Support/Allocator.h"
0027 #include <cassert>
0028 #include <cstddef>
0029 #include <cstdint>
0030 #include <iterator>
0031 #include <new>
0032 #include <type_traits>
0033 #include <utility>
0034 #include <vector>
0035
0036 namespace llvm {
0037
0038 class AsmPrinter;
0039 class DIE;
0040 class DIEUnit;
0041 class DwarfCompileUnit;
0042 class MCExpr;
0043 class MCSection;
0044 class MCSymbol;
0045 class raw_ostream;
0046
0047
0048
0049 class DIEAbbrevData {
0050
0051 dwarf::Attribute Attribute;
0052
0053
0054 dwarf::Form Form;
0055
0056
0057 int64_t Value = 0;
0058
0059 public:
0060 DIEAbbrevData(dwarf::Attribute A, dwarf::Form F)
0061 : Attribute(A), Form(F) {}
0062 DIEAbbrevData(dwarf::Attribute A, int64_t V)
0063 : Attribute(A), Form(dwarf::DW_FORM_implicit_const), Value(V) {}
0064
0065
0066
0067 dwarf::Attribute getAttribute() const { return Attribute; }
0068 dwarf::Form getForm() const { return Form; }
0069 int64_t getValue() const { return Value; }
0070
0071
0072
0073 void Profile(FoldingSetNodeID &ID) const;
0074 };
0075
0076
0077
0078
0079 class DIEAbbrev : public FoldingSetNode {
0080
0081 unsigned Number = 0;
0082
0083
0084 dwarf::Tag Tag;
0085
0086
0087
0088
0089
0090 bool Children;
0091
0092
0093 SmallVector<DIEAbbrevData, 12> Data;
0094
0095 public:
0096 DIEAbbrev(dwarf::Tag T, bool C) : Tag(T), Children(C) {}
0097
0098
0099
0100 dwarf::Tag getTag() const { return Tag; }
0101 unsigned getNumber() const { return Number; }
0102 bool hasChildren() const { return Children; }
0103 const SmallVectorImpl<DIEAbbrevData> &getData() const { return Data; }
0104 void setChildrenFlag(bool hasChild) { Children = hasChild; }
0105 void setNumber(unsigned N) { Number = N; }
0106
0107
0108
0109 void AddAttribute(dwarf::Attribute Attribute, dwarf::Form Form) {
0110 Data.push_back(DIEAbbrevData(Attribute, Form));
0111 }
0112
0113
0114 void AddImplicitConstAttribute(dwarf::Attribute Attribute, int64_t Value) {
0115 Data.push_back(DIEAbbrevData(Attribute, Value));
0116 }
0117
0118
0119 void AddAttribute(const DIEAbbrevData &AbbrevData) {
0120 Data.push_back(AbbrevData);
0121 }
0122
0123
0124 void Profile(FoldingSetNodeID &ID) const;
0125
0126
0127 void Emit(const AsmPrinter *AP) const;
0128
0129 void print(raw_ostream &O) const;
0130 void dump() const;
0131 };
0132
0133
0134
0135
0136
0137
0138
0139
0140 class DIEAbbrevSet {
0141
0142
0143 BumpPtrAllocator &Alloc;
0144
0145 FoldingSet<DIEAbbrev> AbbreviationsSet;
0146
0147 std::vector<DIEAbbrev *> Abbreviations;
0148
0149 public:
0150 DIEAbbrevSet(BumpPtrAllocator &A) : Alloc(A) {}
0151 ~DIEAbbrevSet();
0152
0153
0154
0155
0156
0157
0158
0159 DIEAbbrev &uniqueAbbreviation(DIE &Die);
0160
0161
0162 void Emit(const AsmPrinter *AP, MCSection *Section) const;
0163 };
0164
0165
0166
0167
0168 class DIEInteger {
0169 uint64_t Integer;
0170
0171 public:
0172 explicit DIEInteger(uint64_t I) : Integer(I) {}
0173
0174
0175 static dwarf::Form BestForm(bool IsSigned, uint64_t Int) {
0176 if (IsSigned) {
0177 const int64_t SignedInt = Int;
0178 if ((char)Int == SignedInt)
0179 return dwarf::DW_FORM_data1;
0180 if ((short)Int == SignedInt)
0181 return dwarf::DW_FORM_data2;
0182 if ((int)Int == SignedInt)
0183 return dwarf::DW_FORM_data4;
0184 } else {
0185 if ((unsigned char)Int == Int)
0186 return dwarf::DW_FORM_data1;
0187 if ((unsigned short)Int == Int)
0188 return dwarf::DW_FORM_data2;
0189 if ((unsigned int)Int == Int)
0190 return dwarf::DW_FORM_data4;
0191 }
0192 return dwarf::DW_FORM_data8;
0193 }
0194
0195 uint64_t getValue() const { return Integer; }
0196 void setValue(uint64_t Val) { Integer = Val; }
0197
0198 void emitValue(const AsmPrinter *Asm, dwarf::Form Form) const;
0199 unsigned sizeOf(const dwarf::FormParams &FormParams, dwarf::Form Form) const;
0200
0201 void print(raw_ostream &O) const;
0202 };
0203
0204
0205
0206 class DIEExpr {
0207 const MCExpr *Expr;
0208
0209 public:
0210 explicit DIEExpr(const MCExpr *E) : Expr(E) {}
0211
0212
0213 const MCExpr *getValue() const { return Expr; }
0214
0215 void emitValue(const AsmPrinter *AP, dwarf::Form Form) const;
0216 unsigned sizeOf(const dwarf::FormParams &FormParams, dwarf::Form Form) const;
0217
0218 void print(raw_ostream &O) const;
0219 };
0220
0221
0222
0223 class DIELabel {
0224 const MCSymbol *Label;
0225
0226 public:
0227 explicit DIELabel(const MCSymbol *L) : Label(L) {}
0228
0229
0230 const MCSymbol *getValue() const { return Label; }
0231
0232 void emitValue(const AsmPrinter *AP, dwarf::Form Form) const;
0233 unsigned sizeOf(const dwarf::FormParams &FormParams, dwarf::Form Form) const;
0234
0235 void print(raw_ostream &O) const;
0236 };
0237
0238
0239
0240 class DIEBaseTypeRef {
0241 const DwarfCompileUnit *CU;
0242 const uint64_t Index;
0243 static constexpr unsigned ULEB128PadSize = 4;
0244
0245 public:
0246 explicit DIEBaseTypeRef(const DwarfCompileUnit *TheCU, uint64_t Idx)
0247 : CU(TheCU), Index(Idx) {}
0248
0249
0250 void emitValue(const AsmPrinter *AP, dwarf::Form Form) const;
0251
0252 unsigned sizeOf(const dwarf::FormParams &, dwarf::Form) const;
0253
0254 void print(raw_ostream &O) const;
0255 uint64_t getIndex() const { return Index; }
0256 };
0257
0258
0259
0260
0261 class DIEDelta {
0262 const MCSymbol *LabelHi;
0263 const MCSymbol *LabelLo;
0264
0265 public:
0266 DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo) : LabelHi(Hi), LabelLo(Lo) {}
0267
0268 void emitValue(const AsmPrinter *AP, dwarf::Form Form) const;
0269 unsigned sizeOf(const dwarf::FormParams &FormParams, dwarf::Form Form) const;
0270
0271 void print(raw_ostream &O) const;
0272 };
0273
0274
0275
0276
0277
0278 class DIEString {
0279 DwarfStringPoolEntryRef S;
0280
0281 public:
0282 DIEString(DwarfStringPoolEntryRef S) : S(S) {}
0283
0284
0285 StringRef getString() const { return S.getString(); }
0286
0287 void emitValue(const AsmPrinter *AP, dwarf::Form Form) const;
0288 unsigned sizeOf(const dwarf::FormParams &FormParams, dwarf::Form Form) const;
0289
0290 void print(raw_ostream &O) const;
0291 };
0292
0293
0294
0295
0296
0297 class DIEInlineString {
0298 StringRef S;
0299
0300 public:
0301 template <typename Allocator>
0302 explicit DIEInlineString(StringRef Str, Allocator &A) : S(Str.copy(A)) {}
0303
0304 ~DIEInlineString() = default;
0305
0306
0307 StringRef getString() const { return S; }
0308
0309 void emitValue(const AsmPrinter *AP, dwarf::Form Form) const;
0310 unsigned sizeOf(const dwarf::FormParams &, dwarf::Form) const;
0311
0312 void print(raw_ostream &O) const;
0313 };
0314
0315
0316
0317
0318
0319 class DIEEntry {
0320 DIE *Entry;
0321
0322 public:
0323 DIEEntry() = delete;
0324 explicit DIEEntry(DIE &E) : Entry(&E) {}
0325
0326 DIE &getEntry() const { return *Entry; }
0327
0328 void emitValue(const AsmPrinter *AP, dwarf::Form Form) const;
0329 unsigned sizeOf(const dwarf::FormParams &FormParams, dwarf::Form Form) const;
0330
0331 void print(raw_ostream &O) const;
0332 };
0333
0334
0335
0336
0337 class DIELocList {
0338
0339 size_t Index;
0340
0341 public:
0342 DIELocList(size_t I) : Index(I) {}
0343
0344
0345 size_t getValue() const { return Index; }
0346
0347 void emitValue(const AsmPrinter *AP, dwarf::Form Form) const;
0348 unsigned sizeOf(const dwarf::FormParams &FormParams, dwarf::Form Form) const;
0349
0350 void print(raw_ostream &O) const;
0351 };
0352
0353
0354
0355 class DIEAddrOffset {
0356 DIEInteger Addr;
0357 DIEDelta Offset;
0358
0359 public:
0360 explicit DIEAddrOffset(uint64_t Idx, const MCSymbol *Hi, const MCSymbol *Lo)
0361 : Addr(Idx), Offset(Hi, Lo) {}
0362
0363 void emitValue(const AsmPrinter *AP, dwarf::Form Form) const;
0364 unsigned sizeOf(const dwarf::FormParams &FormParams, dwarf::Form Form) const;
0365
0366 void print(raw_ostream &O) const;
0367 };
0368
0369
0370
0371
0372 class DIEBlock;
0373 class DIELoc;
0374 class DIEValue {
0375 public:
0376 enum Type {
0377 isNone,
0378 #define HANDLE_DIEVALUE(T) is##T,
0379 #include "llvm/CodeGen/DIEValue.def"
0380 };
0381
0382 private:
0383
0384 Type Ty = isNone;
0385 dwarf::Attribute Attribute = (dwarf::Attribute)0;
0386 dwarf::Form Form = (dwarf::Form)0;
0387
0388
0389
0390
0391
0392 using ValTy =
0393 AlignedCharArrayUnion<DIEInteger, DIEString, DIEExpr, DIELabel,
0394 DIEDelta *, DIEEntry, DIEBlock *, DIELoc *,
0395 DIELocList, DIEBaseTypeRef *, DIEAddrOffset *>;
0396
0397 static_assert(sizeof(ValTy) <= sizeof(uint64_t) ||
0398 sizeof(ValTy) <= sizeof(void *),
0399 "Expected all large types to be stored via pointer");
0400
0401
0402 ValTy Val;
0403
0404 template <class T> void construct(T V) {
0405 static_assert(std::is_standard_layout<T>::value ||
0406 std::is_pointer<T>::value,
0407 "Expected standard layout or pointer");
0408 new (reinterpret_cast<void *>(&Val)) T(V);
0409 }
0410
0411 template <class T> T *get() { return reinterpret_cast<T *>(&Val); }
0412 template <class T> const T *get() const {
0413 return reinterpret_cast<const T *>(&Val);
0414 }
0415 template <class T> void destruct() { get<T>()->~T(); }
0416
0417
0418
0419
0420
0421
0422 void destroyVal() {
0423 switch (Ty) {
0424 case isNone:
0425 return;
0426 #define HANDLE_DIEVALUE_SMALL(T) \
0427 case is##T: \
0428 destruct<DIE##T>(); \
0429 return;
0430 #define HANDLE_DIEVALUE_LARGE(T) \
0431 case is##T: \
0432 destruct<const DIE##T *>(); \
0433 return;
0434 #include "llvm/CodeGen/DIEValue.def"
0435 }
0436 }
0437
0438
0439
0440
0441
0442
0443 void copyVal(const DIEValue &X) {
0444 switch (Ty) {
0445 case isNone:
0446 return;
0447 #define HANDLE_DIEVALUE_SMALL(T) \
0448 case is##T: \
0449 construct<DIE##T>(*X.get<DIE##T>()); \
0450 return;
0451 #define HANDLE_DIEVALUE_LARGE(T) \
0452 case is##T: \
0453 construct<const DIE##T *>(*X.get<const DIE##T *>()); \
0454 return;
0455 #include "llvm/CodeGen/DIEValue.def"
0456 }
0457 }
0458
0459 public:
0460 DIEValue() = default;
0461
0462 DIEValue(const DIEValue &X) : Ty(X.Ty), Attribute(X.Attribute), Form(X.Form) {
0463 copyVal(X);
0464 }
0465
0466 DIEValue &operator=(const DIEValue &X) {
0467 if (this == &X)
0468 return *this;
0469 destroyVal();
0470 Ty = X.Ty;
0471 Attribute = X.Attribute;
0472 Form = X.Form;
0473 copyVal(X);
0474 return *this;
0475 }
0476
0477 ~DIEValue() { destroyVal(); }
0478
0479 #define HANDLE_DIEVALUE_SMALL(T) \
0480 DIEValue(dwarf::Attribute Attribute, dwarf::Form Form, const DIE##T &V) \
0481 : Ty(is##T), Attribute(Attribute), Form(Form) { \
0482 construct<DIE##T>(V); \
0483 }
0484 #define HANDLE_DIEVALUE_LARGE(T) \
0485 DIEValue(dwarf::Attribute Attribute, dwarf::Form Form, const DIE##T *V) \
0486 : Ty(is##T), Attribute(Attribute), Form(Form) { \
0487 assert(V && "Expected valid value"); \
0488 construct<const DIE##T *>(V); \
0489 }
0490 #include "llvm/CodeGen/DIEValue.def"
0491
0492
0493
0494 Type getType() const { return Ty; }
0495 dwarf::Attribute getAttribute() const { return Attribute; }
0496 dwarf::Form getForm() const { return Form; }
0497 explicit operator bool() const { return Ty; }
0498
0499
0500 #define HANDLE_DIEVALUE_SMALL(T) \
0501 const DIE##T &getDIE##T() const { \
0502 assert(getType() == is##T && "Expected " #T); \
0503 return *get<DIE##T>(); \
0504 }
0505 #define HANDLE_DIEVALUE_LARGE(T) \
0506 const DIE##T &getDIE##T() const { \
0507 assert(getType() == is##T && "Expected " #T); \
0508 return **get<const DIE##T *>(); \
0509 }
0510 #include "llvm/CodeGen/DIEValue.def"
0511
0512
0513 void emitValue(const AsmPrinter *AP) const;
0514
0515
0516 unsigned sizeOf(const dwarf::FormParams &FormParams) const;
0517
0518 void print(raw_ostream &O) const;
0519 void dump() const;
0520 };
0521
0522 struct IntrusiveBackListNode {
0523 PointerIntPair<IntrusiveBackListNode *, 1> Next;
0524
0525 IntrusiveBackListNode() : Next(this, true) {}
0526
0527 IntrusiveBackListNode *getNext() const {
0528 return Next.getInt() ? nullptr : Next.getPointer();
0529 }
0530 };
0531
0532 struct IntrusiveBackListBase {
0533 using Node = IntrusiveBackListNode;
0534
0535 Node *Last = nullptr;
0536
0537 bool empty() const { return !Last; }
0538
0539 void push_back(Node &N) {
0540 assert(N.Next.getPointer() == &N && "Expected unlinked node");
0541 assert(N.Next.getInt() == true && "Expected unlinked node");
0542
0543 if (Last) {
0544 N.Next = Last->Next;
0545 Last->Next.setPointerAndInt(&N, false);
0546 }
0547 Last = &N;
0548 }
0549
0550 void push_front(Node &N) {
0551 assert(N.Next.getPointer() == &N && "Expected unlinked node");
0552 assert(N.Next.getInt() == true && "Expected unlinked node");
0553
0554 if (Last) {
0555 N.Next.setPointerAndInt(Last->Next.getPointer(), false);
0556 Last->Next.setPointerAndInt(&N, true);
0557 } else {
0558 Last = &N;
0559 }
0560 }
0561 };
0562
0563 template <class T> class IntrusiveBackList : IntrusiveBackListBase {
0564 public:
0565 using IntrusiveBackListBase::empty;
0566
0567 void push_back(T &N) { IntrusiveBackListBase::push_back(N); }
0568 void push_front(T &N) { IntrusiveBackListBase::push_front(N); }
0569
0570 T &back() { return *static_cast<T *>(Last); }
0571 const T &back() const { return *static_cast<T *>(Last); }
0572 T &front() {
0573 return *static_cast<T *>(Last ? Last->Next.getPointer() : nullptr);
0574 }
0575 const T &front() const {
0576 return *static_cast<T *>(Last ? Last->Next.getPointer() : nullptr);
0577 }
0578
0579 void takeNodes(IntrusiveBackList<T> &Other) {
0580 if (Other.empty())
0581 return;
0582
0583 T *FirstNode = static_cast<T *>(Other.Last->Next.getPointer());
0584 T *IterNode = FirstNode;
0585 do {
0586
0587 T *TmpNode = IterNode;
0588 IterNode = static_cast<T *>(IterNode->Next.getPointer());
0589
0590
0591 TmpNode->Next.setPointerAndInt(TmpNode, true);
0592 push_back(*TmpNode);
0593 } while (IterNode != FirstNode);
0594
0595 Other.Last = nullptr;
0596 }
0597
0598 bool deleteNode(T &N) {
0599 if (Last == &N) {
0600 Last = Last->Next.getPointer();
0601 Last->Next.setInt(true);
0602 return true;
0603 }
0604
0605 Node *cur = Last;
0606 while (cur && cur->Next.getPointer()) {
0607 if (cur->Next.getPointer() == &N) {
0608 cur->Next.setPointer(cur->Next.getPointer()->Next.getPointer());
0609 return true;
0610 }
0611 cur = cur->Next.getPointer();
0612 }
0613
0614 return false;
0615 }
0616
0617 class const_iterator;
0618 class iterator
0619 : public iterator_facade_base<iterator, std::forward_iterator_tag, T> {
0620 friend class const_iterator;
0621
0622 Node *N = nullptr;
0623
0624 public:
0625 iterator() = default;
0626 explicit iterator(T *N) : N(N) {}
0627
0628 iterator &operator++() {
0629 N = N->getNext();
0630 return *this;
0631 }
0632
0633 explicit operator bool() const { return N; }
0634 T &operator*() const { return *static_cast<T *>(N); }
0635
0636 bool operator==(const iterator &X) const { return N == X.N; }
0637 };
0638
0639 class const_iterator
0640 : public iterator_facade_base<const_iterator, std::forward_iterator_tag,
0641 const T> {
0642 const Node *N = nullptr;
0643
0644 public:
0645 const_iterator() = default;
0646
0647 const_iterator(typename IntrusiveBackList<T>::iterator X) : N(X.N) {}
0648 explicit const_iterator(const T *N) : N(N) {}
0649
0650 const_iterator &operator++() {
0651 N = N->getNext();
0652 return *this;
0653 }
0654
0655 explicit operator bool() const { return N; }
0656 const T &operator*() const { return *static_cast<const T *>(N); }
0657
0658 bool operator==(const const_iterator &X) const { return N == X.N; }
0659 };
0660
0661 iterator begin() {
0662 return Last ? iterator(static_cast<T *>(Last->Next.getPointer())) : end();
0663 }
0664 const_iterator begin() const {
0665 return const_cast<IntrusiveBackList *>(this)->begin();
0666 }
0667 iterator end() { return iterator(); }
0668 const_iterator end() const { return const_iterator(); }
0669
0670 static iterator toIterator(T &N) { return iterator(&N); }
0671 static const_iterator toIterator(const T &N) { return const_iterator(&N); }
0672 };
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689 class DIEValueList {
0690 struct Node : IntrusiveBackListNode {
0691 DIEValue V;
0692
0693 explicit Node(DIEValue V) : V(V) {}
0694 };
0695
0696 using ListTy = IntrusiveBackList<Node>;
0697
0698 ListTy List;
0699
0700 public:
0701 class const_value_iterator;
0702 class value_iterator
0703 : public iterator_adaptor_base<value_iterator, ListTy::iterator,
0704 std::forward_iterator_tag, DIEValue> {
0705 friend class const_value_iterator;
0706
0707 using iterator_adaptor =
0708 iterator_adaptor_base<value_iterator, ListTy::iterator,
0709 std::forward_iterator_tag, DIEValue>;
0710
0711 public:
0712 value_iterator() = default;
0713 explicit value_iterator(ListTy::iterator X) : iterator_adaptor(X) {}
0714
0715 explicit operator bool() const { return bool(wrapped()); }
0716 DIEValue &operator*() const { return wrapped()->V; }
0717 };
0718
0719 class const_value_iterator : public iterator_adaptor_base<
0720 const_value_iterator, ListTy::const_iterator,
0721 std::forward_iterator_tag, const DIEValue> {
0722 using iterator_adaptor =
0723 iterator_adaptor_base<const_value_iterator, ListTy::const_iterator,
0724 std::forward_iterator_tag, const DIEValue>;
0725
0726 public:
0727 const_value_iterator() = default;
0728 const_value_iterator(DIEValueList::value_iterator X)
0729 : iterator_adaptor(X.wrapped()) {}
0730 explicit const_value_iterator(ListTy::const_iterator X)
0731 : iterator_adaptor(X) {}
0732
0733 explicit operator bool() const { return bool(wrapped()); }
0734 const DIEValue &operator*() const { return wrapped()->V; }
0735 };
0736
0737 using value_range = iterator_range<value_iterator>;
0738 using const_value_range = iterator_range<const_value_iterator>;
0739
0740 value_iterator addValue(BumpPtrAllocator &Alloc, const DIEValue &V) {
0741 List.push_back(*new (Alloc) Node(V));
0742 return value_iterator(ListTy::toIterator(List.back()));
0743 }
0744 template <class T>
0745 value_iterator addValue(BumpPtrAllocator &Alloc, dwarf::Attribute Attribute,
0746 dwarf::Form Form, T &&Value) {
0747 return addValue(Alloc, DIEValue(Attribute, Form, std::forward<T>(Value)));
0748 }
0749
0750
0751 template <class T>
0752 bool replaceValue(BumpPtrAllocator &Alloc, dwarf::Attribute Attribute,
0753 dwarf::Attribute NewAttribute, dwarf::Form Form,
0754 T &&NewValue) {
0755 for (llvm::DIEValue &val : values()) {
0756 if (val.getAttribute() == Attribute) {
0757 val = *new (Alloc)
0758 DIEValue(NewAttribute, Form, std::forward<T>(NewValue));
0759 return true;
0760 }
0761 }
0762
0763 return false;
0764 }
0765
0766 template <class T>
0767 bool replaceValue(BumpPtrAllocator &Alloc, dwarf::Attribute Attribute,
0768 dwarf::Form Form, T &&NewValue) {
0769 for (llvm::DIEValue &val : values()) {
0770 if (val.getAttribute() == Attribute) {
0771 val = *new (Alloc) DIEValue(Attribute, Form, std::forward<T>(NewValue));
0772 return true;
0773 }
0774 }
0775
0776 return false;
0777 }
0778
0779 bool replaceValue(BumpPtrAllocator &Alloc, dwarf::Attribute Attribute,
0780 dwarf::Form Form, DIEValue &NewValue) {
0781 for (llvm::DIEValue &val : values()) {
0782 if (val.getAttribute() == Attribute) {
0783 val = NewValue;
0784 return true;
0785 }
0786 }
0787
0788 return false;
0789 }
0790
0791 bool deleteValue(dwarf::Attribute Attribute) {
0792
0793 for (auto &node : List) {
0794 if (node.V.getAttribute() == Attribute) {
0795 return List.deleteNode(node);
0796 }
0797 }
0798
0799 return false;
0800 }
0801
0802
0803
0804
0805 void takeValues(DIEValueList &Other) { List.takeNodes(Other.List); }
0806
0807 value_range values() {
0808 return make_range(value_iterator(List.begin()), value_iterator(List.end()));
0809 }
0810 const_value_range values() const {
0811 return make_range(const_value_iterator(List.begin()),
0812 const_value_iterator(List.end()));
0813 }
0814 };
0815
0816
0817
0818
0819 class DIE : IntrusiveBackListNode, public DIEValueList {
0820 friend class IntrusiveBackList<DIE>;
0821 friend class DIEUnit;
0822
0823
0824 unsigned Offset = 0;
0825
0826 unsigned Size = 0;
0827 unsigned AbbrevNumber = ~0u;
0828
0829 dwarf::Tag Tag = (dwarf::Tag)0;
0830
0831
0832 bool ForceChildren = false;
0833
0834 IntrusiveBackList<DIE> Children;
0835
0836
0837
0838 PointerUnion<DIE *, DIEUnit *> Owner;
0839
0840 explicit DIE(dwarf::Tag Tag) : Tag(Tag) {}
0841
0842 public:
0843 DIE() = delete;
0844 DIE(const DIE &RHS) = delete;
0845 DIE(DIE &&RHS) = delete;
0846 DIE &operator=(const DIE &RHS) = delete;
0847 DIE &operator=(const DIE &&RHS) = delete;
0848
0849 static DIE *get(BumpPtrAllocator &Alloc, dwarf::Tag Tag) {
0850 return new (Alloc) DIE(Tag);
0851 }
0852
0853
0854 unsigned getAbbrevNumber() const { return AbbrevNumber; }
0855 dwarf::Tag getTag() const { return Tag; }
0856
0857 unsigned getOffset() const {
0858
0859 assert(Offset && "Offset being queried before it's been computed.");
0860 return Offset;
0861 }
0862 unsigned getSize() const {
0863
0864 assert(Size && "Size being queried before it's been ocmputed.");
0865 return Size;
0866 }
0867 bool hasChildren() const { return ForceChildren || !Children.empty(); }
0868 void setForceChildren(bool B) { ForceChildren = B; }
0869
0870 using child_iterator = IntrusiveBackList<DIE>::iterator;
0871 using const_child_iterator = IntrusiveBackList<DIE>::const_iterator;
0872 using child_range = iterator_range<child_iterator>;
0873 using const_child_range = iterator_range<const_child_iterator>;
0874
0875 child_range children() {
0876 return make_range(Children.begin(), Children.end());
0877 }
0878 const_child_range children() const {
0879 return make_range(Children.begin(), Children.end());
0880 }
0881
0882 DIE *getParent() const;
0883
0884
0885
0886
0887
0888 DIEAbbrev generateAbbrev() const;
0889
0890
0891 void setAbbrevNumber(unsigned I) { AbbrevNumber = I; }
0892
0893
0894
0895 uint64_t getDebugSectionOffset() const;
0896
0897
0898
0899
0900
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912
0913 unsigned computeOffsetsAndAbbrevs(const dwarf::FormParams &FormParams,
0914 DIEAbbrevSet &AbbrevSet, unsigned CUOffset);
0915
0916
0917
0918
0919
0920
0921 const DIE *getUnitDie() const;
0922
0923
0924
0925
0926
0927
0928 DIEUnit *getUnit() const;
0929
0930 void setOffset(unsigned O) { Offset = O; }
0931 void setSize(unsigned S) { Size = S; }
0932
0933
0934 DIE &addChild(DIE *Child) {
0935 assert(!Child->getParent() && "Child should be orphaned");
0936 Child->Owner = this;
0937 Children.push_back(*Child);
0938 return Children.back();
0939 }
0940
0941 DIE &addChildFront(DIE *Child) {
0942 assert(!Child->getParent() && "Child should be orphaned");
0943 Child->Owner = this;
0944 Children.push_front(*Child);
0945 return Children.front();
0946 }
0947
0948
0949
0950
0951
0952 DIEValue findAttribute(dwarf::Attribute Attribute) const;
0953
0954 void print(raw_ostream &O, unsigned IndentCount = 0) const;
0955 void dump() const;
0956 };
0957
0958
0959
0960 class DIEUnit {
0961
0962
0963
0964
0965
0966 DIE Die;
0967
0968
0969 MCSection *Section = nullptr;
0970 uint64_t Offset = 0;
0971 protected:
0972 virtual ~DIEUnit() = default;
0973
0974 public:
0975 explicit DIEUnit(dwarf::Tag UnitTag);
0976 DIEUnit(const DIEUnit &RHS) = delete;
0977 DIEUnit(DIEUnit &&RHS) = delete;
0978 void operator=(const DIEUnit &RHS) = delete;
0979 void operator=(const DIEUnit &&RHS) = delete;
0980
0981
0982
0983
0984 void setSection(MCSection *Section) {
0985 assert(!this->Section);
0986 this->Section = Section;
0987 }
0988
0989 virtual const MCSymbol *getCrossSectionRelativeBaseAddress() const {
0990 return nullptr;
0991 }
0992
0993
0994
0995
0996 MCSection *getSection() const { return Section; }
0997 void setDebugSectionOffset(uint64_t O) { Offset = O; }
0998 uint64_t getDebugSectionOffset() const { return Offset; }
0999 DIE &getUnitDie() { return Die; }
1000 const DIE &getUnitDie() const { return Die; }
1001 };
1002
1003 struct BasicDIEUnit final : DIEUnit {
1004 explicit BasicDIEUnit(dwarf::Tag UnitTag) : DIEUnit(UnitTag) {}
1005 };
1006
1007
1008
1009
1010 class DIELoc : public DIEValueList {
1011 mutable unsigned Size = 0;
1012
1013 public:
1014 DIELoc() = default;
1015
1016
1017 unsigned computeSize(const dwarf::FormParams &FormParams) const;
1018
1019
1020 void setSize(unsigned size) { Size = size; }
1021
1022
1023
1024 dwarf::Form BestForm(unsigned DwarfVersion) const {
1025 if (DwarfVersion > 3)
1026 return dwarf::DW_FORM_exprloc;
1027
1028 if ((unsigned char)Size == Size)
1029 return dwarf::DW_FORM_block1;
1030 if ((unsigned short)Size == Size)
1031 return dwarf::DW_FORM_block2;
1032 if ((unsigned int)Size == Size)
1033 return dwarf::DW_FORM_block4;
1034 return dwarf::DW_FORM_block;
1035 }
1036
1037 void emitValue(const AsmPrinter *Asm, dwarf::Form Form) const;
1038 unsigned sizeOf(const dwarf::FormParams &, dwarf::Form Form) const;
1039
1040 void print(raw_ostream &O) const;
1041 };
1042
1043
1044
1045
1046 class DIEBlock : public DIEValueList {
1047 mutable unsigned Size = 0;
1048
1049 public:
1050 DIEBlock() = default;
1051
1052
1053 unsigned computeSize(const dwarf::FormParams &FormParams) const;
1054
1055
1056 void setSize(unsigned size) { Size = size; }
1057
1058
1059
1060 dwarf::Form BestForm() const {
1061 if ((unsigned char)Size == Size)
1062 return dwarf::DW_FORM_block1;
1063 if ((unsigned short)Size == Size)
1064 return dwarf::DW_FORM_block2;
1065 if ((unsigned int)Size == Size)
1066 return dwarf::DW_FORM_block4;
1067 return dwarf::DW_FORM_block;
1068 }
1069
1070 void emitValue(const AsmPrinter *Asm, dwarf::Form Form) const;
1071 unsigned sizeOf(const dwarf::FormParams &, dwarf::Form Form) const;
1072
1073 void print(raw_ostream &O) const;
1074 };
1075
1076 }
1077
1078 #endif