1 //===--- lib/CodeGen/DIE.h - DWARF Info Entries -----------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // Data structures for DWARF info entries. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DIE_H 15 #define LLVM_LIB_CODEGEN_ASMPRINTER_DIE_H 16 17 #include "llvm/ADT/FoldingSet.h" 18 #include "llvm/ADT/PointerIntPair.h" 19 #include "llvm/ADT/STLExtras.h" 20 #include "llvm/ADT/SmallVector.h" 21 #include "llvm/CodeGen/DwarfStringPoolEntry.h" 22 #include "llvm/Support/Dwarf.h" 23 #include <vector> 24 25 namespace llvm { 26 class AsmPrinter; 27 class MCExpr; 28 class MCSymbol; 29 class raw_ostream; 30 class DwarfTypeUnit; 31 32 //===--------------------------------------------------------------------===// 33 /// DIEAbbrevData - Dwarf abbreviation data, describes one attribute of a 34 /// Dwarf abbreviation. 35 class DIEAbbrevData { 36 /// Attribute - Dwarf attribute code. 37 /// 38 dwarf::Attribute Attribute; 39 40 /// Form - Dwarf form code. 41 /// 42 dwarf::Form Form; 43 44 public: DIEAbbrevData(dwarf::Attribute A,dwarf::Form F)45 DIEAbbrevData(dwarf::Attribute A, dwarf::Form F) : Attribute(A), Form(F) {} 46 47 // Accessors. getAttribute()48 dwarf::Attribute getAttribute() const { return Attribute; } getForm()49 dwarf::Form getForm() const { return Form; } 50 51 /// Profile - Used to gather unique data for the abbreviation folding set. 52 /// 53 void Profile(FoldingSetNodeID &ID) const; 54 }; 55 56 //===--------------------------------------------------------------------===// 57 /// DIEAbbrev - Dwarf abbreviation, describes the organization of a debug 58 /// information object. 59 class DIEAbbrev : public FoldingSetNode { 60 /// Unique number for node. 61 /// 62 unsigned Number; 63 64 /// Tag - Dwarf tag code. 65 /// 66 dwarf::Tag Tag; 67 68 /// Children - Whether or not this node has children. 69 /// 70 // This cheats a bit in all of the uses since the values in the standard 71 // are 0 and 1 for no children and children respectively. 72 bool Children; 73 74 /// Data - Raw data bytes for abbreviation. 75 /// 76 SmallVector<DIEAbbrevData, 12> Data; 77 78 public: DIEAbbrev(dwarf::Tag T,bool C)79 DIEAbbrev(dwarf::Tag T, bool C) : Tag(T), Children(C), Data() {} 80 81 // Accessors. getTag()82 dwarf::Tag getTag() const { return Tag; } getNumber()83 unsigned getNumber() const { return Number; } hasChildren()84 bool hasChildren() const { return Children; } getData()85 const SmallVectorImpl<DIEAbbrevData> &getData() const { return Data; } setChildrenFlag(bool hasChild)86 void setChildrenFlag(bool hasChild) { Children = hasChild; } setNumber(unsigned N)87 void setNumber(unsigned N) { Number = N; } 88 89 /// AddAttribute - Adds another set of attribute information to the 90 /// abbreviation. AddAttribute(dwarf::Attribute Attribute,dwarf::Form Form)91 void AddAttribute(dwarf::Attribute Attribute, dwarf::Form Form) { 92 Data.push_back(DIEAbbrevData(Attribute, Form)); 93 } 94 95 /// Profile - Used to gather unique data for the abbreviation folding set. 96 /// 97 void Profile(FoldingSetNodeID &ID) const; 98 99 /// Emit - Print the abbreviation using the specified asm printer. 100 /// 101 void Emit(const AsmPrinter *AP) const; 102 103 #ifndef NDEBUG 104 void print(raw_ostream &O); 105 void dump(); 106 #endif 107 }; 108 109 //===--------------------------------------------------------------------===// 110 /// DIEInteger - An integer value DIE. 111 /// 112 class DIEInteger { 113 uint64_t Integer; 114 115 public: DIEInteger(uint64_t I)116 explicit DIEInteger(uint64_t I) : Integer(I) {} 117 118 /// BestForm - Choose the best form for integer. 119 /// BestForm(bool IsSigned,uint64_t Int)120 static dwarf::Form BestForm(bool IsSigned, uint64_t Int) { 121 if (IsSigned) { 122 const int64_t SignedInt = Int; 123 if ((char)Int == SignedInt) 124 return dwarf::DW_FORM_data1; 125 if ((short)Int == SignedInt) 126 return dwarf::DW_FORM_data2; 127 if ((int)Int == SignedInt) 128 return dwarf::DW_FORM_data4; 129 } else { 130 if ((unsigned char)Int == Int) 131 return dwarf::DW_FORM_data1; 132 if ((unsigned short)Int == Int) 133 return dwarf::DW_FORM_data2; 134 if ((unsigned int)Int == Int) 135 return dwarf::DW_FORM_data4; 136 } 137 return dwarf::DW_FORM_data8; 138 } 139 getValue()140 uint64_t getValue() const { return Integer; } setValue(uint64_t Val)141 void setValue(uint64_t Val) { Integer = Val; } 142 143 void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; 144 unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; 145 146 #ifndef NDEBUG 147 void print(raw_ostream &O) const; 148 #endif 149 }; 150 151 //===--------------------------------------------------------------------===// 152 /// DIEExpr - An expression DIE. 153 // 154 class DIEExpr { 155 const MCExpr *Expr; 156 157 public: DIEExpr(const MCExpr * E)158 explicit DIEExpr(const MCExpr *E) : Expr(E) {} 159 160 /// getValue - Get MCExpr. 161 /// getValue()162 const MCExpr *getValue() const { return Expr; } 163 164 void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; 165 unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; 166 167 #ifndef NDEBUG 168 void print(raw_ostream &O) const; 169 #endif 170 }; 171 172 //===--------------------------------------------------------------------===// 173 /// DIELabel - A label DIE. 174 // 175 class DIELabel { 176 const MCSymbol *Label; 177 178 public: DIELabel(const MCSymbol * L)179 explicit DIELabel(const MCSymbol *L) : Label(L) {} 180 181 /// getValue - Get MCSymbol. 182 /// getValue()183 const MCSymbol *getValue() const { return Label; } 184 185 void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; 186 unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; 187 188 #ifndef NDEBUG 189 void print(raw_ostream &O) const; 190 #endif 191 }; 192 193 //===--------------------------------------------------------------------===// 194 /// DIEDelta - A simple label difference DIE. 195 /// 196 class DIEDelta { 197 const MCSymbol *LabelHi; 198 const MCSymbol *LabelLo; 199 200 public: DIEDelta(const MCSymbol * Hi,const MCSymbol * Lo)201 DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo) : LabelHi(Hi), LabelLo(Lo) {} 202 203 void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; 204 unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; 205 206 #ifndef NDEBUG 207 void print(raw_ostream &O) const; 208 #endif 209 }; 210 211 //===--------------------------------------------------------------------===// 212 /// DIEString - A container for string values. 213 /// 214 class DIEString { 215 DwarfStringPoolEntryRef S; 216 217 public: DIEString(DwarfStringPoolEntryRef S)218 DIEString(DwarfStringPoolEntryRef S) : S(S) {} 219 220 /// getString - Grab the string out of the object. getString()221 StringRef getString() const { return S.getString(); } 222 223 void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; 224 unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; 225 226 #ifndef NDEBUG 227 void print(raw_ostream &O) const; 228 #endif 229 }; 230 231 //===--------------------------------------------------------------------===// 232 /// DIEEntry - A pointer to another debug information entry. An instance of 233 /// this class can also be used as a proxy for a debug information entry not 234 /// yet defined (ie. types.) 235 class DIE; 236 class DIEEntry { 237 DIE *Entry; 238 239 DIEEntry() = delete; 240 241 public: DIEEntry(DIE & E)242 explicit DIEEntry(DIE &E) : Entry(&E) {} 243 getEntry()244 DIE &getEntry() const { return *Entry; } 245 246 /// Returns size of a ref_addr entry. 247 static unsigned getRefAddrSize(const AsmPrinter *AP); 248 249 void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; SizeOf(const AsmPrinter * AP,dwarf::Form Form)250 unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { 251 return Form == dwarf::DW_FORM_ref_addr ? getRefAddrSize(AP) 252 : sizeof(int32_t); 253 } 254 255 #ifndef NDEBUG 256 void print(raw_ostream &O) const; 257 #endif 258 }; 259 260 //===--------------------------------------------------------------------===// 261 /// \brief A signature reference to a type unit. 262 class DIETypeSignature { 263 const DwarfTypeUnit *Unit; 264 265 DIETypeSignature() = delete; 266 267 public: DIETypeSignature(const DwarfTypeUnit & Unit)268 explicit DIETypeSignature(const DwarfTypeUnit &Unit) : Unit(&Unit) {} 269 270 void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; SizeOf(const AsmPrinter * AP,dwarf::Form Form)271 unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const { 272 assert(Form == dwarf::DW_FORM_ref_sig8); 273 return 8; 274 } 275 276 #ifndef NDEBUG 277 void print(raw_ostream &O) const; 278 #endif 279 }; 280 281 //===--------------------------------------------------------------------===// 282 /// DIELocList - Represents a pointer to a location list in the debug_loc 283 /// section. 284 // 285 class DIELocList { 286 // Index into the .debug_loc vector. 287 size_t Index; 288 289 public: DIELocList(size_t I)290 DIELocList(size_t I) : Index(I) {} 291 292 /// getValue - Grab the current index out. getValue()293 size_t getValue() const { return Index; } 294 295 void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; 296 unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; 297 298 #ifndef NDEBUG 299 void print(raw_ostream &O) const; 300 #endif 301 }; 302 303 //===--------------------------------------------------------------------===// 304 /// DIEValue - A debug information entry value. Some of these roughly correlate 305 /// to DWARF attribute classes. 306 /// 307 class DIEBlock; 308 class DIELoc; 309 class DIEValue { 310 public: 311 enum Type { 312 isNone, 313 #define HANDLE_DIEVALUE(T) is##T, 314 #include "llvm/CodeGen/DIEValue.def" 315 }; 316 317 private: 318 /// Ty - Type of data stored in the value. 319 /// 320 Type Ty = isNone; 321 dwarf::Attribute Attribute = (dwarf::Attribute)0; 322 dwarf::Form Form = (dwarf::Form)0; 323 324 /// Storage for the value. 325 /// 326 /// All values that aren't standard layout (or are larger than 8 bytes) 327 /// should be stored by reference instead of by value. 328 typedef AlignedCharArrayUnion<DIEInteger, DIEString, DIEExpr, DIELabel, 329 DIEDelta *, DIEEntry, DIETypeSignature, 330 DIEBlock *, DIELoc *, DIELocList> ValTy; 331 static_assert(sizeof(ValTy) <= sizeof(uint64_t) || 332 sizeof(ValTy) <= sizeof(void *), 333 "Expected all large types to be stored via pointer"); 334 335 /// Underlying stored value. 336 ValTy Val; 337 construct(T V)338 template <class T> void construct(T V) { 339 static_assert(std::is_standard_layout<T>::value || 340 std::is_pointer<T>::value, 341 "Expected standard layout or pointer"); 342 new (reinterpret_cast<void *>(Val.buffer)) T(V); 343 } 344 get()345 template <class T> T *get() { return reinterpret_cast<T *>(Val.buffer); } get()346 template <class T> const T *get() const { 347 return reinterpret_cast<const T *>(Val.buffer); 348 } destruct()349 template <class T> void destruct() { get<T>()->~T(); } 350 351 /// Destroy the underlying value. 352 /// 353 /// This should get optimized down to a no-op. We could skip it if we could 354 /// add a static assert on \a std::is_trivially_copyable(), but we currently 355 /// support versions of GCC that don't understand that. destroyVal()356 void destroyVal() { 357 switch (Ty) { 358 case isNone: 359 return; 360 #define HANDLE_DIEVALUE_SMALL(T) \ 361 case is##T: \ 362 destruct<DIE##T>(); 363 return; 364 #define HANDLE_DIEVALUE_LARGE(T) \ 365 case is##T: \ 366 destruct<const DIE##T *>(); 367 return; 368 #include "llvm/CodeGen/DIEValue.def" 369 } 370 } 371 372 /// Copy the underlying value. 373 /// 374 /// This should get optimized down to a simple copy. We need to actually 375 /// construct the value, rather than calling memcpy, to satisfy strict 376 /// aliasing rules. copyVal(const DIEValue & X)377 void copyVal(const DIEValue &X) { 378 switch (Ty) { 379 case isNone: 380 return; 381 #define HANDLE_DIEVALUE_SMALL(T) \ 382 case is##T: \ 383 construct<DIE##T>(*X.get<DIE##T>()); \ 384 return; 385 #define HANDLE_DIEVALUE_LARGE(T) \ 386 case is##T: \ 387 construct<const DIE##T *>(*X.get<const DIE##T *>()); \ 388 return; 389 #include "llvm/CodeGen/DIEValue.def" 390 } 391 } 392 393 public: 394 DIEValue() = default; DIEValue(const DIEValue & X)395 DIEValue(const DIEValue &X) : Ty(X.Ty), Attribute(X.Attribute), Form(X.Form) { 396 copyVal(X); 397 } 398 DIEValue &operator=(const DIEValue &X) { 399 destroyVal(); 400 Ty = X.Ty; 401 Attribute = X.Attribute; 402 Form = X.Form; 403 copyVal(X); 404 return *this; 405 } ~DIEValue()406 ~DIEValue() { destroyVal(); } 407 408 #define HANDLE_DIEVALUE_SMALL(T) \ 409 DIEValue(dwarf::Attribute Attribute, dwarf::Form Form, const DIE##T &V) \ 410 : Ty(is##T), Attribute(Attribute), Form(Form) { \ 411 construct<DIE##T>(V); \ 412 } 413 #define HANDLE_DIEVALUE_LARGE(T) \ 414 DIEValue(dwarf::Attribute Attribute, dwarf::Form Form, const DIE##T *V) \ 415 : Ty(is##T), Attribute(Attribute), Form(Form) { \ 416 assert(V && "Expected valid value"); \ 417 construct<const DIE##T *>(V); \ 418 } 419 #include "llvm/CodeGen/DIEValue.def" 420 421 // Accessors getType()422 Type getType() const { return Ty; } getAttribute()423 dwarf::Attribute getAttribute() const { return Attribute; } getForm()424 dwarf::Form getForm() const { return Form; } 425 explicit operator bool() const { return Ty; } 426 427 #define HANDLE_DIEVALUE_SMALL(T) \ 428 const DIE##T &getDIE##T() const { \ 429 assert(getType() == is##T && "Expected " #T); \ 430 return *get<DIE##T>(); \ 431 } 432 #define HANDLE_DIEVALUE_LARGE(T) \ 433 const DIE##T &getDIE##T() const { \ 434 assert(getType() == is##T && "Expected " #T); \ 435 return **get<const DIE##T *>(); \ 436 } 437 #include "llvm/CodeGen/DIEValue.def" 438 439 /// EmitValue - Emit value via the Dwarf writer. 440 /// 441 void EmitValue(const AsmPrinter *AP) const; 442 443 /// SizeOf - Return the size of a value in bytes. 444 /// 445 unsigned SizeOf(const AsmPrinter *AP) const; 446 447 #ifndef NDEBUG 448 void print(raw_ostream &O) const; 449 void dump() const; 450 #endif 451 }; 452 453 struct IntrusiveBackListNode { 454 PointerIntPair<IntrusiveBackListNode *, 1> Next; IntrusiveBackListNodeIntrusiveBackListNode455 IntrusiveBackListNode() : Next(this, true) {} 456 getNextIntrusiveBackListNode457 IntrusiveBackListNode *getNext() const { 458 return Next.getInt() ? nullptr : Next.getPointer(); 459 } 460 }; 461 462 struct IntrusiveBackListBase { 463 typedef IntrusiveBackListNode Node; 464 Node *Last = nullptr; 465 emptyIntrusiveBackListBase466 bool empty() const { return !Last; } push_backIntrusiveBackListBase467 void push_back(Node &N) { 468 assert(N.Next.getPointer() == &N && "Expected unlinked node"); 469 assert(N.Next.getInt() == true && "Expected unlinked node"); 470 471 if (Last) { 472 N.Next = Last->Next; 473 Last->Next.setPointerAndInt(&N, false); 474 } 475 Last = &N; 476 } 477 }; 478 479 template <class T> class IntrusiveBackList : IntrusiveBackListBase { 480 public: 481 using IntrusiveBackListBase::empty; push_back(T & N)482 void push_back(T &N) { IntrusiveBackListBase::push_back(N); } back()483 T &back() { return *static_cast<T *>(Last); } back()484 const T &back() const { return *static_cast<T *>(Last); } 485 486 class const_iterator; 487 class iterator 488 : public iterator_facade_base<iterator, std::forward_iterator_tag, T> { 489 friend class const_iterator; 490 Node *N = nullptr; 491 492 public: 493 iterator() = default; iterator(T * N)494 explicit iterator(T *N) : N(N) {} 495 496 iterator &operator++() { 497 N = N->getNext(); 498 return *this; 499 } 500 501 explicit operator bool() const { return N; } 502 T &operator*() const { return *static_cast<T *>(N); } 503 504 bool operator==(const iterator &X) const { return N == X.N; } 505 bool operator!=(const iterator &X) const { return N != X.N; } 506 }; 507 508 class const_iterator 509 : public iterator_facade_base<const_iterator, std::forward_iterator_tag, 510 const T> { 511 const Node *N = nullptr; 512 513 public: 514 const_iterator() = default; 515 // Placate MSVC by explicitly scoping 'iterator'. const_iterator(typename IntrusiveBackList<T>::iterator X)516 const_iterator(typename IntrusiveBackList<T>::iterator X) : N(X.N) {} const_iterator(const T * N)517 explicit const_iterator(const T *N) : N(N) {} 518 519 const_iterator &operator++() { 520 N = N->getNext(); 521 return *this; 522 } 523 524 explicit operator bool() const { return N; } 525 const T &operator*() const { return *static_cast<const T *>(N); } 526 527 bool operator==(const const_iterator &X) const { return N == X.N; } 528 bool operator!=(const const_iterator &X) const { return N != X.N; } 529 }; 530 begin()531 iterator begin() { 532 return Last ? iterator(static_cast<T *>(Last->Next.getPointer())) : end(); 533 } begin()534 const_iterator begin() const { 535 return const_cast<IntrusiveBackList *>(this)->begin(); 536 } end()537 iterator end() { return iterator(); } end()538 const_iterator end() const { return const_iterator(); } 539 toIterator(T & N)540 static iterator toIterator(T &N) { return iterator(&N); } toIterator(const T & N)541 static const_iterator toIterator(const T &N) { return const_iterator(&N); } 542 }; 543 544 /// A list of DIE values. 545 /// 546 /// This is a singly-linked list, but instead of reversing the order of 547 /// insertion, we keep a pointer to the back of the list so we can push in 548 /// order. 549 /// 550 /// There are two main reasons to choose a linked list over a customized 551 /// vector-like data structure. 552 /// 553 /// 1. For teardown efficiency, we want DIEs to be BumpPtrAllocated. Using a 554 /// linked list here makes this way easier to accomplish. 555 /// 2. Carrying an extra pointer per \a DIEValue isn't expensive. 45% of DIEs 556 /// have 2 or fewer values, and 90% have 5 or fewer. A vector would be 557 /// over-allocated by 50% on average anyway, the same cost as the 558 /// linked-list node. 559 class DIEValueList { 560 struct Node : IntrusiveBackListNode { 561 DIEValue V; NodeNode562 explicit Node(DIEValue V) : V(V) {} 563 }; 564 565 typedef IntrusiveBackList<Node> ListTy; 566 ListTy List; 567 568 public: empty()569 bool empty() const { return List.empty(); } 570 571 class const_iterator; 572 class iterator 573 : public iterator_adaptor_base<iterator, ListTy::iterator, 574 std::forward_iterator_tag, DIEValue> { 575 friend class const_iterator; 576 typedef iterator_adaptor_base<iterator, ListTy::iterator, 577 std::forward_iterator_tag, 578 DIEValue> iterator_adaptor; 579 580 public: 581 iterator() = default; iterator(ListTy::iterator X)582 explicit iterator(ListTy::iterator X) : iterator_adaptor(X) {} 583 584 explicit operator bool() const { return bool(wrapped()); } 585 DIEValue &operator*() const { return wrapped()->V; } 586 }; 587 588 class const_iterator 589 : public iterator_adaptor_base<const_iterator, ListTy::const_iterator, 590 std::forward_iterator_tag, 591 const DIEValue> { 592 typedef iterator_adaptor_base<const_iterator, ListTy::const_iterator, 593 std::forward_iterator_tag, 594 const DIEValue> iterator_adaptor; 595 596 public: 597 const_iterator() = default; const_iterator(DIEValueList::iterator X)598 const_iterator(DIEValueList::iterator X) : iterator_adaptor(X.wrapped()) {} const_iterator(ListTy::const_iterator X)599 explicit const_iterator(ListTy::const_iterator X) : iterator_adaptor(X) {} 600 601 explicit operator bool() const { return bool(wrapped()); } 602 const DIEValue &operator*() const { return wrapped()->V; } 603 }; 604 insert(BumpPtrAllocator & Alloc,DIEValue V)605 iterator insert(BumpPtrAllocator &Alloc, DIEValue V) { 606 List.push_back(*new (Alloc) Node(V)); 607 return iterator(ListTy::toIterator(List.back())); 608 } 609 template <class... Ts> emplace(BumpPtrAllocator & Alloc,Ts &&...Args)610 iterator emplace(BumpPtrAllocator &Alloc, Ts &&... Args) { 611 return insert(Alloc, DIEValue(std::forward<Ts>(Args)...)); 612 } 613 begin()614 iterator begin() { return iterator(List.begin()); } end()615 iterator end() { return iterator(List.end()); } begin()616 const_iterator begin() const { return const_iterator(List.begin()); } end()617 const_iterator end() const { return const_iterator(List.end()); } 618 }; 619 620 //===--------------------------------------------------------------------===// 621 /// DIE - A structured debug information entry. Has an abbreviation which 622 /// describes its organization. 623 class DIE : IntrusiveBackListNode { 624 friend class IntrusiveBackList<DIE>; 625 626 protected: 627 /// Offset - Offset in debug info section. 628 /// 629 unsigned Offset; 630 631 /// Size - Size of instance + children. 632 /// 633 unsigned Size; 634 635 unsigned AbbrevNumber = ~0u; 636 637 /// Tag - Dwarf tag code. 638 /// 639 dwarf::Tag Tag = (dwarf::Tag)0; 640 641 /// Children DIEs. 642 IntrusiveBackList<DIE> Children; 643 644 DIE *Parent = nullptr; 645 646 /// Attribute values. 647 /// 648 DIEValueList Values; 649 650 protected: DIE()651 DIE() : Offset(0), Size(0) {} 652 653 private: DIE(dwarf::Tag Tag)654 explicit DIE(dwarf::Tag Tag) : Offset(0), Size(0), Tag(Tag) {} 655 656 public: get(BumpPtrAllocator & Alloc,dwarf::Tag Tag)657 static DIE *get(BumpPtrAllocator &Alloc, dwarf::Tag Tag) { 658 return new (Alloc) DIE(Tag); 659 } 660 661 // Accessors. getAbbrevNumber()662 unsigned getAbbrevNumber() const { return AbbrevNumber; } getTag()663 dwarf::Tag getTag() const { return Tag; } getOffset()664 unsigned getOffset() const { return Offset; } getSize()665 unsigned getSize() const { return Size; } hasChildren()666 bool hasChildren() const { return !Children.empty(); } 667 668 typedef IntrusiveBackList<DIE>::iterator child_iterator; 669 typedef IntrusiveBackList<DIE>::const_iterator const_child_iterator; 670 typedef iterator_range<child_iterator> child_range; 671 typedef iterator_range<const_child_iterator> const_child_range; 672 children()673 child_range children() { 674 return llvm::make_range(Children.begin(), Children.end()); 675 } children()676 const_child_range children() const { 677 return llvm::make_range(Children.begin(), Children.end()); 678 } 679 680 typedef DIEValueList::iterator value_iterator; 681 typedef iterator_range<value_iterator> value_range; 682 values()683 value_range values() { 684 return llvm::make_range(Values.begin(), Values.end()); 685 } 686 687 typedef DIEValueList::const_iterator const_value_iterator; 688 typedef iterator_range<const_value_iterator> const_value_range; 689 values()690 const_value_range values() const { 691 return llvm::make_range(Values.begin(), Values.end()); 692 } 693 getParent()694 DIE *getParent() const { return Parent; } 695 696 /// Generate the abbreviation for this DIE. 697 /// 698 /// Calculate the abbreviation for this, which should be uniqued and 699 /// eventually used to call \a setAbbrevNumber(). 700 DIEAbbrev generateAbbrev() const; 701 702 /// Set the abbreviation number for this DIE. setAbbrevNumber(unsigned I)703 void setAbbrevNumber(unsigned I) { AbbrevNumber = I; } 704 705 /// Climb up the parent chain to get the compile or type unit DIE this DIE 706 /// belongs to. 707 const DIE *getUnit() const; 708 /// Similar to getUnit, returns null when DIE is not added to an 709 /// owner yet. 710 const DIE *getUnitOrNull() const; setOffset(unsigned O)711 void setOffset(unsigned O) { Offset = O; } setSize(unsigned S)712 void setSize(unsigned S) { Size = S; } 713 714 /// addValue - Add a value and attributes to a DIE. 715 /// addValue(BumpPtrAllocator & Alloc,DIEValue Value)716 value_iterator addValue(BumpPtrAllocator &Alloc, DIEValue Value) { 717 return Values.insert(Alloc, Value); 718 } 719 template <class T> addValue(BumpPtrAllocator & Alloc,dwarf::Attribute Attribute,dwarf::Form Form,T && Value)720 value_iterator addValue(BumpPtrAllocator &Alloc, dwarf::Attribute Attribute, 721 dwarf::Form Form, T &&Value) { 722 return Values.emplace(Alloc, Attribute, Form, std::forward<T>(Value)); 723 } 724 725 /// Add a child to the DIE. addChild(DIE * Child)726 DIE &addChild(DIE *Child) { 727 assert(!Child->getParent() && "Child should be orphaned"); 728 Child->Parent = this; 729 Children.push_back(*Child); 730 return Children.back(); 731 } 732 733 /// Find a value in the DIE with the attribute given. 734 /// 735 /// Returns a default-constructed DIEValue (where \a DIEValue::getType() 736 /// gives \a DIEValue::isNone) if no such attribute exists. 737 DIEValue findAttribute(dwarf::Attribute Attribute) const; 738 739 #ifndef NDEBUG 740 void print(raw_ostream &O, unsigned IndentCount = 0) const; 741 void dump(); 742 #endif 743 }; 744 745 //===--------------------------------------------------------------------===// 746 /// DIELoc - Represents an expression location. 747 // 748 class DIELoc : public DIE { 749 mutable unsigned Size; // Size in bytes excluding size header. 750 751 public: DIELoc()752 DIELoc() : Size(0) {} 753 754 /// ComputeSize - Calculate the size of the location expression. 755 /// 756 unsigned ComputeSize(const AsmPrinter *AP) const; 757 758 /// BestForm - Choose the best form for data. 759 /// BestForm(unsigned DwarfVersion)760 dwarf::Form BestForm(unsigned DwarfVersion) const { 761 if (DwarfVersion > 3) 762 return dwarf::DW_FORM_exprloc; 763 // Pre-DWARF4 location expressions were blocks and not exprloc. 764 if ((unsigned char)Size == Size) 765 return dwarf::DW_FORM_block1; 766 if ((unsigned short)Size == Size) 767 return dwarf::DW_FORM_block2; 768 if ((unsigned int)Size == Size) 769 return dwarf::DW_FORM_block4; 770 return dwarf::DW_FORM_block; 771 } 772 773 void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; 774 unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; 775 776 #ifndef NDEBUG 777 void print(raw_ostream &O) const; 778 #endif 779 }; 780 781 //===--------------------------------------------------------------------===// 782 /// DIEBlock - Represents a block of values. 783 // 784 class DIEBlock : public DIE { 785 mutable unsigned Size; // Size in bytes excluding size header. 786 787 public: DIEBlock()788 DIEBlock() : Size(0) {} 789 790 /// ComputeSize - Calculate the size of the location expression. 791 /// 792 unsigned ComputeSize(const AsmPrinter *AP) const; 793 794 /// BestForm - Choose the best form for data. 795 /// BestForm()796 dwarf::Form BestForm() const { 797 if ((unsigned char)Size == Size) 798 return dwarf::DW_FORM_block1; 799 if ((unsigned short)Size == Size) 800 return dwarf::DW_FORM_block2; 801 if ((unsigned int)Size == Size) 802 return dwarf::DW_FORM_block4; 803 return dwarf::DW_FORM_block; 804 } 805 806 void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const; 807 unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; 808 809 #ifndef NDEBUG 810 void print(raw_ostream &O) const; 811 #endif 812 }; 813 814 } // end llvm namespace 815 816 #endif 817