Debug info: Support variadic functions.
[oota-llvm.git] / lib / CodeGen / AsmPrinter / DIE.h
index 6d4f305c84005573b079edc89401910ff86076e0..d4f3154d15c7725ba277f3de7b5214ffedb0b0ed 100644 (file)
@@ -16,9 +16,9 @@
 
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/MC/MCExpr.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/Dwarf.h"
-#include "llvm/MC/MCExpr.h"
 #include <vector>
 
 namespace llvm {
@@ -26,6 +26,7 @@ namespace llvm {
   class MCSymbol;
   class MCSymbolRefExpr;
   class raw_ostream;
+  class DwarfTypeUnit;
 
   //===--------------------------------------------------------------------===//
   /// DIEAbbrevData - Dwarf abbreviation data, describes one attribute of a
@@ -134,7 +135,7 @@ namespace llvm {
     explicit DIE(unsigned Tag)
         : Offset(0), Size(0), Abbrev((dwarf::Tag)Tag, dwarf::DW_CHILDREN_no),
           Parent(0) {}
-    virtual ~DIE();
+    ~DIE();
 
     // Accessors.
     DIEAbbrev &getAbbrev() { return Abbrev; }
@@ -146,6 +147,12 @@ namespace llvm {
     const std::vector<DIE *> &getChildren() const { return Children; }
     const SmallVectorImpl<DIEValue*> &getValues() const { return Values; }
     DIE *getParent() const { return Parent; }
+    /// Climb up the parent chain to get the compile or type unit DIE this DIE
+    /// belongs to.
+    const DIE *getUnit() const;
+    /// Similar to getUnit, returns null when DIE is not added to an
+    /// owner yet.
+    const DIE *getUnitOrNull() const;
     void setOffset(unsigned O) { Offset = O; }
     void setSize(unsigned S) { Size = S; }
 
@@ -166,9 +173,9 @@ namespace llvm {
       Child->Parent = this;
     }
 
-    /// findAttribute - Find a value in the DIE with the attribute given, returns NULL
-    /// if no such attribute exists.
-    DIEValue *findAttribute(uint16_t Attribute);
+    /// findAttribute - Find a value in the DIE with the attribute given,
+    /// returns NULL if no such attribute exists.
+    DIEValue *findAttribute(uint16_t Attribute) const;
 
 #ifndef NDEBUG
     void print(raw_ostream &O, unsigned IndentCount = 0) const;
@@ -189,7 +196,9 @@ namespace llvm {
       isLabel,
       isDelta,
       isEntry,
-      isBlock
+      isTypeSignature,
+      isBlock,
+      isLoc
     };
   protected:
     /// Type - Type of data stored in the value.
@@ -406,16 +415,90 @@ namespace llvm {
   };
 
   //===--------------------------------------------------------------------===//
-  /// DIEBlock - A block of values.  Primarily used for location expressions.
+  /// \brief A signature reference to a type unit.
+  class DIETypeSignature : public DIEValue {
+    const DwarfTypeUnit &Unit;
+  public:
+    explicit DIETypeSignature(const DwarfTypeUnit &Unit)
+        : DIEValue(isTypeSignature), Unit(Unit) {}
+
+    /// \brief Emit type unit signature.
+    virtual void EmitValue(AsmPrinter *Asm, dwarf::Form Form) const;
+
+    /// Returns size of a ref_sig8 entry.
+    virtual unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const {
+      assert(Form == dwarf::DW_FORM_ref_sig8);
+      return 8;
+    }
+
+    // \brief Implement isa/cast/dyncast.
+    static bool classof(const DIEValue *E) {
+      return E->getType() == isTypeSignature;
+    }
+#ifndef NDEBUG
+    virtual void print(raw_ostream &O) const;
+    void dump() const;
+#endif
+  };
+
+  //===--------------------------------------------------------------------===//
+  /// DIELoc - Represents an expression location.
+  //
+  class DIELoc : public DIEValue, public DIE {
+    unsigned Size;                // Size in bytes excluding size header.
+  public:
+    DIELoc() : DIEValue(isLoc), DIE(0), Size(0) {}
+
+    /// ComputeSize - Calculate the size of the location expression.
+    ///
+    unsigned ComputeSize(AsmPrinter *AP) const;
+
+    /// setSize - Set the size of the location entry.
+    ///
+    void setSize(unsigned Sz) { Size = Sz; }
+
+    /// BestForm - Choose the best form for data.
+    ///
+    dwarf::Form BestForm(unsigned DwarfVersion) const {
+      if (DwarfVersion > 3) return dwarf::DW_FORM_exprloc;
+      // Pre-DWARF4 location expressions were blocks and not exprloc.
+      if ((unsigned char)Size == Size)  return dwarf::DW_FORM_block1;
+      if ((unsigned short)Size == Size) return dwarf::DW_FORM_block2;
+      if ((unsigned int)Size == Size)   return dwarf::DW_FORM_block4;
+      return dwarf::DW_FORM_block;
+    }
+
+    /// EmitValue - Emit location data.
+    ///
+    virtual void EmitValue(AsmPrinter *AP, dwarf::Form Form) const;
+
+    /// SizeOf - Determine size of location data in bytes.
+    ///
+    virtual unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const;
+
+    // Implement isa/cast/dyncast.
+    static bool classof(const DIEValue *E) { return E->getType() == isLoc; }
+
+#ifndef NDEBUG
+    virtual void print(raw_ostream &O) const;
+#endif
+  };
+
+  //===--------------------------------------------------------------------===//
+  /// DIEBlock - Represents a block of values.
   //
   class DIEBlock : public DIEValue, public DIE {
     unsigned Size;                // Size in bytes excluding size header.
   public:
     DIEBlock() : DIEValue(isBlock), DIE(0), Size(0) {}
 
-    /// ComputeSize - calculate the size of the block.
+    /// ComputeSize - Calculate the size of the location expression.
+    ///
+    unsigned ComputeSize(AsmPrinter *AP) const;
+
+    /// setSize - Set the size of the block.
     ///
-    unsigned ComputeSize(AsmPrinter *AP);
+    void setSize(unsigned Sz) { Size = Sz; }
 
     /// BestForm - Choose the best form for data.
     ///
@@ -426,22 +509,21 @@ namespace llvm {
       return dwarf::DW_FORM_block;
     }
 
-    /// EmitValue - Emit block data.
+    /// EmitValue - Emit location data.
     ///
     virtual void EmitValue(AsmPrinter *AP, dwarf::Form Form) const;
 
-    /// SizeOf - Determine size of block data in bytes.
+    /// SizeOf - Determine size of location data in bytes.
     ///
     virtual unsigned SizeOf(AsmPrinter *AP, dwarf::Form Form) const;
 
     // Implement isa/cast/dyncast.
     static bool classof(const DIEValue *E) { return E->getType() == isBlock; }
 
-#ifndef NDEBUG
+    #ifndef NDEBUG
     virtual void print(raw_ostream &O) const;
-#endif
+    #endif
   };
-
 } // end llvm namespace
 
 #endif