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: 44 DIEAbbrevData(dwarf::Attribute A, dwarf::Form F) : Attribute(A), Form(F) {} 45 46 // Accessors. 47 dwarf::Attribute getAttribute() const { return Attribute; } 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: 78 DIEAbbrev(dwarf::Tag T, bool C) : Tag(T), Children(C), Data() {} 79 80 // Accessors. 81 dwarf::Tag getTag() const { return Tag; } 82 unsigned getNumber() const { return Number; } 83 bool hasChildren() const { return Children; } 84 const SmallVectorImpl<DIEAbbrevData> &getData() const { return Data; } 85 void setChildrenFlag(bool hasChild) { Children = hasChild; } 86 void setNumber(unsigned N) { Number = N; } 87 88 /// AddAttribute - Adds another set of attribute information to the 89 /// abbreviation. 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: 113 explicit DIEInteger(uint64_t I) : Integer(I) {} 114 115 /// BestForm - Choose the best form for integer. 116 /// 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 137 uint64_t getValue() const { return Integer; } 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: 153 explicit DIEExpr(const MCExpr *E) : Expr(E) {} 154 155 /// getValue - Get MCExpr. 156 /// 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: 172 explicit DIELabel(const MCSymbol *L) : Label(L) {} 173 174 /// getValue - Get MCSymbol. 175 /// 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: 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: 207 DIEString(DwarfStringPoolEntryRef S) : S(S) {} 208 209 /// getString - Grab the string out of the object. 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: 229 explicit DIEEntry(DIE &E) : Entry(&E) {} 230 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; 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: 254 DIELocList(size_t I) : Index(I) {} 255 256 /// getValue - Grab the current index out. 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 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 308 template <class T> T *get() { return reinterpret_cast<T *>(Val.buffer); } 309 template <class T> const T *get() const { 310 return reinterpret_cast<const T *>(Val.buffer); 311 } 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. 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. 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; 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 } 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 385 Type getType() const { return Ty; } 386 dwarf::Attribute getAttribute() const { return Attribute; } 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; 416 IntrusiveBackListNode() : Next(this, true) {} 417 418 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 427 bool empty() const { return !Last; } 428 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; 443 void push_back(T &N) { IntrusiveBackListBase::push_back(N); } 444 T &back() { return *static_cast<T *>(Last); } 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; 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'. 477 const_iterator(typename IntrusiveBackList<T>::iterator X) : N(X.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 492 iterator begin() { 493 return Last ? iterator(static_cast<T *>(Last->Next.getPointer())) : end(); 494 } 495 const_iterator begin() const { 496 return const_cast<IntrusiveBackList *>(this)->begin(); 497 } 498 iterator end() { return iterator(); } 499 const_iterator end() const { return const_iterator(); } 500 501 static iterator toIterator(T &N) { return iterator(&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; 523 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; 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; 556 const_value_iterator(DIEValueList::value_iterator X) 557 : iterator_adaptor(X.wrapped()) {} 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 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> 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 578 value_range values() { 579 return llvm::make_range(value_iterator(List.begin()), 580 value_iterator(List.end())); 581 } 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; 614 explicit DIE(dwarf::Tag Tag) : Offset(0), Size(0), Tag(Tag) {} 615 616 public: 617 static DIE *get(BumpPtrAllocator &Alloc, dwarf::Tag Tag) { 618 return new (Alloc) DIE(Tag); 619 } 620 621 // Accessors. 622 unsigned getAbbrevNumber() const { return AbbrevNumber; } 623 dwarf::Tag getTag() const { return Tag; } 624 unsigned getOffset() const { return Offset; } 625 unsigned getSize() const { return Size; } 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 633 child_range children() { 634 return llvm::make_range(Children.begin(), Children.end()); 635 } 636 const_child_range children() const { 637 return llvm::make_range(Children.begin(), Children.end()); 638 } 639 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. 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; 657 void setOffset(unsigned O) { Offset = O; } 658 void setSize(unsigned S) { Size = S; } 659 660 /// Add a child to the DIE. 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: 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 /// 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: 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 /// 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