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