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   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:
DIEInteger(uint64_t I)114   explicit DIEInteger(uint64_t I) : Integer(I) {}
115 
116   /// BestForm - Choose the best form for integer.
117   ///
BestForm(bool IsSigned,uint64_t Int)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 
getValue()138   uint64_t getValue() const { return Integer; }
setValue(uint64_t Val)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:
DIEExpr(const MCExpr * E)154   explicit DIEExpr(const MCExpr *E) : Expr(E) {}
155 
156   /// getValue - Get MCExpr.
157   ///
getValue()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:
DIELabel(const MCSymbol * L)173   explicit DIELabel(const MCSymbol *L) : Label(L) {}
174 
175   /// getValue - Get MCSymbol.
176   ///
getValue()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:
DIEDelta(const MCSymbol * Hi,const MCSymbol * Lo)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:
DIEString(DwarfStringPoolEntryRef S)208   DIEString(DwarfStringPoolEntryRef S) : S(S) {}
209 
210   /// getString - Grab the string out of the object.
getString()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:
DIEEntry(DIE & E)230   explicit DIEEntry(DIE &E) : Entry(&E) {}
231 
getEntry()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;
SizeOf(const AsmPrinter * AP,dwarf::Form Form)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:
DIETypeSignature(const DwarfTypeUnit & Unit)254   explicit DIETypeSignature(const DwarfTypeUnit &Unit) : Unit(&Unit) {}
255 
256   void EmitValue(const AsmPrinter *AP, dwarf::Form Form) const;
SizeOf(const AsmPrinter * AP,dwarf::Form Form)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:
DIELocList(size_t I)274   DIELocList(size_t I) : Index(I) {}
275 
276   /// getValue - Grab the current index out.
getValue()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 
construct(T V)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 
get()327   template <class T> T *get() { return reinterpret_cast<T *>(Val.buffer); }
get()328   template <class T> const T *get() const {
329     return reinterpret_cast<const T *>(Val.buffer);
330   }
destruct()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.
destroyVal()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.
copyVal(const DIEValue & X)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;
DIEValue(const DIEValue & X)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   }
~DIEValue()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
getType()404   Type getType() const { return Ty; }
getAttribute()405   dwarf::Attribute getAttribute() const { return Attribute; }
getForm()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;
IntrusiveBackListNodeIntrusiveBackListNode435   IntrusiveBackListNode() : Next(this, true) {}
436 
getNextIntrusiveBackListNode437   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 
emptyIntrusiveBackListBase446   bool empty() const { return !Last; }
push_backIntrusiveBackListBase447   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;
push_back(T & N)462   void push_back(T &N) { IntrusiveBackListBase::push_back(N); }
back()463   T &back() { return *static_cast<T *>(Last); }
back()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;
iterator(T * N)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'.
const_iterator(typename IntrusiveBackList<T>::iterator X)496     const_iterator(typename IntrusiveBackList<T>::iterator X) : N(X.N) {}
const_iterator(const T * 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 
begin()511   iterator begin() {
512     return Last ? iterator(static_cast<T *>(Last->Next.getPointer())) : end();
513   }
begin()514   const_iterator begin() const {
515     return const_cast<IntrusiveBackList *>(this)->begin();
516   }
end()517   iterator end() { return iterator(); }
end()518   const_iterator end() const { return const_iterator(); }
519 
toIterator(T & N)520   static iterator toIterator(T &N) { return iterator(&N); }
toIterator(const T & 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;
NodeNode542     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;
value_iterator(ListTy::iterator X)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;
const_value_iterator(DIEValueList::value_iterator X)575     const_value_iterator(DIEValueList::value_iterator X)
576         : iterator_adaptor(X.wrapped()) {}
const_value_iterator(ListTy::const_iterator X)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 
addValue(BumpPtrAllocator & Alloc,DIEValue V)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>
addValue(BumpPtrAllocator & Alloc,dwarf::Attribute Attribute,dwarf::Form Form,T && Value)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 
values()597   value_range values() {
598     return llvm::make_range(value_iterator(List.begin()),
599                             value_iterator(List.end()));
600   }
values()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;
DIE(dwarf::Tag Tag)633   explicit DIE(dwarf::Tag Tag) : Offset(0), Size(0), Tag(Tag) {}
634 
635 public:
get(BumpPtrAllocator & Alloc,dwarf::Tag Tag)636   static DIE *get(BumpPtrAllocator &Alloc, dwarf::Tag Tag) {
637     return new (Alloc) DIE(Tag);
638   }
639 
640   // Accessors.
getAbbrevNumber()641   unsigned getAbbrevNumber() const { return AbbrevNumber; }
getTag()642   dwarf::Tag getTag() const { return Tag; }
getOffset()643   unsigned getOffset() const { return Offset; }
getSize()644   unsigned getSize() const { return Size; }
hasChildren()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 
children()652   child_range children() {
653     return llvm::make_range(Children.begin(), Children.end());
654   }
children()655   const_child_range children() const {
656     return llvm::make_range(Children.begin(), Children.end());
657   }
658 
getParent()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.
setAbbrevNumber(unsigned I)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;
setOffset(unsigned O)676   void setOffset(unsigned O) { Offset = O; }
setSize(unsigned S)677   void setSize(unsigned S) { Size = S; }
678 
679   /// Add a child to the DIE.
addChild(DIE * Child)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:
DIELoc()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   ///
BestForm(unsigned DwarfVersion)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:
DIEBlock()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   ///
BestForm()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