DIE.h revision 8a6983493595a896cfca8392a2676bf425349cee
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 CODEGEN_ASMPRINTER_DIE_H__
15#define CODEGEN_ASMPRINTER_DIE_H__
16
17#include "llvm/ADT/FoldingSet.h"
18#include "llvm/ADT/SmallVector.h"
19#include "llvm/Support/Compiler.h"
20#include "llvm/Support/Dwarf.h"
21#include <vector>
22
23namespace llvm {
24  class AsmPrinter;
25  class MCSymbol;
26  class raw_ostream;
27
28  //===--------------------------------------------------------------------===//
29  /// DIEAbbrevData - Dwarf abbreviation data, describes the one attribute of a
30  /// Dwarf abbreviation.
31  class DIEAbbrevData {
32    /// Attribute - Dwarf attribute code.
33    ///
34    unsigned Attribute;
35
36    /// Form - Dwarf form code.
37    ///
38    unsigned Form;
39  public:
40    DIEAbbrevData(unsigned A, unsigned F) : Attribute(A), Form(F) {}
41
42    // Accessors.
43    unsigned getAttribute() const { return Attribute; }
44    unsigned getForm()      const { return Form; }
45
46    /// Profile - Used to gather unique data for the abbreviation folding set.
47    ///
48    void Profile(FoldingSetNodeID &ID) const;
49  };
50
51  //===--------------------------------------------------------------------===//
52  /// DIEAbbrev - Dwarf abbreviation, describes the organization of a debug
53  /// information object.
54  class DIEAbbrev : public FoldingSetNode {
55    /// Tag - Dwarf tag code.
56    ///
57    unsigned Tag;
58
59    /// Unique number for node.
60    ///
61    unsigned Number;
62
63    /// ChildrenFlag - Dwarf children flag.
64    ///
65    unsigned ChildrenFlag;
66
67    /// Data - Raw data bytes for abbreviation.
68    ///
69    SmallVector<DIEAbbrevData, 8> Data;
70
71  public:
72    DIEAbbrev(unsigned T, unsigned C) : Tag(T), ChildrenFlag(C), Data() {}
73
74    // Accessors.
75    unsigned getTag() const { return Tag; }
76    unsigned getNumber() const { return Number; }
77    unsigned getChildrenFlag() const { return ChildrenFlag; }
78    const SmallVector<DIEAbbrevData, 8> &getData() const { return Data; }
79    void setTag(unsigned T) { Tag = T; }
80    void setChildrenFlag(unsigned CF) { ChildrenFlag = CF; }
81    void setNumber(unsigned N) { Number = N; }
82
83    /// AddAttribute - Adds another set of attribute information to the
84    /// abbreviation.
85    void AddAttribute(unsigned Attribute, unsigned Form) {
86      Data.push_back(DIEAbbrevData(Attribute, Form));
87    }
88
89    /// AddFirstAttribute - Adds a set of attribute information to the front
90    /// of the abbreviation.
91    void AddFirstAttribute(unsigned Attribute, unsigned Form) {
92      Data.insert(Data.begin(), 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(AsmPrinter *AP) const;
102
103#ifndef NDEBUG
104    void print(raw_ostream &O);
105    void dump();
106#endif
107  };
108
109  //===--------------------------------------------------------------------===//
110  /// DIE - A structured debug information entry.  Has an abbreviation which
111  /// describes it's organization.
112  class DIEValue;
113
114  class DIE {
115  protected:
116    /// Abbrev - Buffer for constructing abbreviation.
117    ///
118    DIEAbbrev Abbrev;
119
120    /// Offset - Offset in debug info section.
121    ///
122    unsigned Offset;
123
124    /// Size - Size of instance + children.
125    ///
126    unsigned Size;
127
128    /// Children DIEs.
129    ///
130    std::vector<DIE *> Children;
131
132    DIE *Parent;
133
134    /// Attributes values.
135    ///
136    SmallVector<DIEValue*, 32> Values;
137
138    // Private data for print()
139    mutable unsigned IndentCount;
140  public:
141    explicit DIE(unsigned Tag)
142      : Abbrev(Tag, dwarf::DW_CHILDREN_no), Offset(0),
143        Size(0), Parent(0), IndentCount(0) {}
144    virtual ~DIE();
145
146    // Accessors.
147    DIEAbbrev &getAbbrev() { return Abbrev; }
148    unsigned getAbbrevNumber() const { return Abbrev.getNumber(); }
149    unsigned getTag() const { return Abbrev.getTag(); }
150    unsigned getOffset() const { return Offset; }
151    unsigned getSize() const { return Size; }
152    const std::vector<DIE *> &getChildren() const { return Children; }
153    const SmallVector<DIEValue*, 32> &getValues() const { return Values; }
154    DIE *getParent() const { return Parent; }
155    void setTag(unsigned Tag) { Abbrev.setTag(Tag); }
156    void setOffset(unsigned O) { Offset = O; }
157    void setSize(unsigned S) { Size = S; }
158
159    /// addValue - Add a value and attributes to a DIE.
160    ///
161    void addValue(unsigned Attribute, unsigned Form, DIEValue *Value) {
162      Abbrev.AddAttribute(Attribute, Form);
163      Values.push_back(Value);
164    }
165
166    /// addChild - Add a child to the DIE.
167    ///
168    void addChild(DIE *Child) {
169      if (Child->getParent()) {
170        assert (Child->getParent() == this && "Unexpected DIE Parent!");
171        return;
172      }
173      Abbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes);
174      Children.push_back(Child);
175      Child->Parent = this;
176    }
177
178#ifndef NDEBUG
179    void print(raw_ostream &O, unsigned IncIndent = 0);
180    void dump();
181#endif
182  };
183
184  //===--------------------------------------------------------------------===//
185  /// DIEValue - A debug information entry value.
186  ///
187  class DIEValue {
188    virtual void anchor();
189  public:
190    enum {
191      isInteger,
192      isString,
193      isLabel,
194      isDelta,
195      isEntry,
196      isBlock
197    };
198  protected:
199    /// Type - Type of data stored in the value.
200    ///
201    unsigned Type;
202  public:
203    explicit DIEValue(unsigned T) : Type(T) {}
204    virtual ~DIEValue() {}
205
206    // Accessors
207    unsigned getType()  const { return Type; }
208
209    /// EmitValue - Emit value via the Dwarf writer.
210    ///
211    virtual void EmitValue(AsmPrinter *AP, unsigned Form) const = 0;
212
213    /// SizeOf - Return the size of a value in bytes.
214    ///
215    virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const = 0;
216
217    // Implement isa/cast/dyncast.
218    static bool classof(const DIEValue *) { return true; }
219
220#ifndef NDEBUG
221    virtual void print(raw_ostream &O) = 0;
222    void dump();
223#endif
224  };
225
226  //===--------------------------------------------------------------------===//
227  /// DIEInteger - An integer value DIE.
228  ///
229  class DIEInteger : public DIEValue {
230    uint64_t Integer;
231  public:
232    explicit DIEInteger(uint64_t I) : DIEValue(isInteger), Integer(I) {}
233
234    /// BestForm - Choose the best form for integer.
235    ///
236    static unsigned BestForm(bool IsSigned, uint64_t Int) {
237      if (IsSigned) {
238        if ((char)Int == (signed)Int)   return dwarf::DW_FORM_data1;
239        if ((short)Int == (signed)Int)  return dwarf::DW_FORM_data2;
240        if ((int)Int == (signed)Int)    return dwarf::DW_FORM_data4;
241      } else {
242        if ((unsigned char)Int == Int)  return dwarf::DW_FORM_data1;
243        if ((unsigned short)Int == Int) return dwarf::DW_FORM_data2;
244        if ((unsigned int)Int == Int)   return dwarf::DW_FORM_data4;
245      }
246      return dwarf::DW_FORM_data8;
247    }
248
249    /// EmitValue - Emit integer of appropriate size.
250    ///
251    virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
252
253    uint64_t getValue() const { return Integer; }
254
255    /// SizeOf - Determine size of integer value in bytes.
256    ///
257    virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const;
258
259    // Implement isa/cast/dyncast.
260    static bool classof(const DIEInteger *) { return true; }
261    static bool classof(const DIEValue *I) { return I->getType() == isInteger; }
262
263#ifndef NDEBUG
264    virtual void print(raw_ostream &O);
265#endif
266  };
267
268  //===--------------------------------------------------------------------===//
269  /// DIELabel - A label expression DIE.
270  //
271  class DIELabel : public DIEValue {
272    const MCSymbol *Label;
273  public:
274    explicit DIELabel(const MCSymbol *L) : DIEValue(isLabel), Label(L) {}
275
276    /// EmitValue - Emit label value.
277    ///
278    virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
279
280    /// getValue - Get MCSymbol.
281    ///
282    const MCSymbol *getValue()       const { return Label; }
283
284    /// SizeOf - Determine size of label value in bytes.
285    ///
286    virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const;
287
288    // Implement isa/cast/dyncast.
289    static bool classof(const DIELabel *)  { return true; }
290    static bool classof(const DIEValue *L) { return L->getType() == isLabel; }
291
292#ifndef NDEBUG
293    virtual void print(raw_ostream &O);
294#endif
295  };
296
297  //===--------------------------------------------------------------------===//
298  /// DIEDelta - A simple label difference DIE.
299  ///
300  class DIEDelta : public DIEValue {
301    const MCSymbol *LabelHi;
302    const MCSymbol *LabelLo;
303  public:
304    DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo)
305      : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {}
306
307    /// EmitValue - Emit delta value.
308    ///
309    virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
310
311    /// SizeOf - Determine size of delta value in bytes.
312    ///
313    virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const;
314
315    // Implement isa/cast/dyncast.
316    static bool classof(const DIEDelta *)  { return true; }
317    static bool classof(const DIEValue *D) { return D->getType() == isDelta; }
318
319#ifndef NDEBUG
320    virtual void print(raw_ostream &O);
321#endif
322  };
323
324  //===--------------------------------------------------------------------===//
325  /// DIEEntry - A pointer to another debug information entry.  An instance of
326  /// this class can also be used as a proxy for a debug information entry not
327  /// yet defined (ie. types.)
328  class DIEEntry : public DIEValue {
329    DIE *const Entry;
330  public:
331    explicit DIEEntry(DIE *E) : DIEValue(isEntry), Entry(E) {}
332
333    DIE *getEntry() const { return Entry; }
334
335    /// EmitValue - Emit debug information entry offset.
336    ///
337    virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
338
339    /// SizeOf - Determine size of debug information entry in bytes.
340    ///
341    virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const {
342      return sizeof(int32_t);
343    }
344
345    // Implement isa/cast/dyncast.
346    static bool classof(const DIEEntry *)  { return true; }
347    static bool classof(const DIEValue *E) { return E->getType() == isEntry; }
348
349#ifndef NDEBUG
350    virtual void print(raw_ostream &O);
351#endif
352  };
353
354  //===--------------------------------------------------------------------===//
355  /// DIEBlock - A block of values.  Primarily used for location expressions.
356  //
357  class DIEBlock : public DIEValue, public DIE {
358    unsigned Size;                // Size in bytes excluding size header.
359  public:
360    DIEBlock()
361      : DIEValue(isBlock), DIE(0), Size(0) {}
362    virtual ~DIEBlock() {}
363
364    /// ComputeSize - calculate the size of the block.
365    ///
366    unsigned ComputeSize(AsmPrinter *AP);
367
368    /// BestForm - Choose the best form for data.
369    ///
370    unsigned BestForm() const {
371      if ((unsigned char)Size == Size)  return dwarf::DW_FORM_block1;
372      if ((unsigned short)Size == Size) return dwarf::DW_FORM_block2;
373      if ((unsigned int)Size == Size)   return dwarf::DW_FORM_block4;
374      return dwarf::DW_FORM_block;
375    }
376
377    /// EmitValue - Emit block data.
378    ///
379    virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
380
381    /// SizeOf - Determine size of block data in bytes.
382    ///
383    virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const;
384
385    // Implement isa/cast/dyncast.
386    static bool classof(const DIEBlock *)  { return true; }
387    static bool classof(const DIEValue *E) { return E->getType() == isBlock; }
388
389#ifndef NDEBUG
390    virtual void print(raw_ostream &O);
391#endif
392  };
393
394} // end llvm namespace
395
396#endif
397