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