Reworked how Dwarf debug info entries and abbreviations are handled. Added
authorJim Laskey <jlaskey@mac.com>
Fri, 20 Jan 2006 20:34:06 +0000 (20:34 +0000)
committerJim Laskey <jlaskey@mac.com>
Fri, 20 Jan 2006 20:34:06 +0000 (20:34 +0000)
pubnames and debuy str sections.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25487 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/DwarfWriter.h
lib/CodeGen/DwarfWriter.cpp

index c371783a555bbb0619ef73b4fed97a8c16e238c7..8c0bcb9ec52456c3ab95d2e33f2114dae61e5f11 100644 (file)
@@ -437,6 +437,15 @@ namespace llvm {
     DW_CFA_hi_user = 0x3f
   };
   
+  //===--------------------------------------------------------------------===//
+  // Forward declarations.
+  //
+  class AsmPrinter;
+  class DIE;
+  class DwarfWriter; 
+  class DWContext;
+  class MachineDebugInfo;
+  
   //===--------------------------------------------------------------------===//
   // DWLabel - Labels are used to track locations in the assembler file.
   // Labels appear in the form <prefix>debug_<Tag><Number>, where the tag is a
@@ -445,57 +454,89 @@ namespace llvm {
   struct DWLabel {
     const char *Tag;                    // Label category tag. Should always be
                                         // a staticly declared C string.
-    unsigned    Number;                 // Unique number
+    unsigned    Number;                 // Unique number.
 
-    DWLabel() : Tag(NULL), Number(0) {}
     DWLabel(const char *T, unsigned N) : Tag(T), Number(N) {}
   };
-
+  
+  //===--------------------------------------------------------------------===//
+  // DIEAbbrevData - Dwarf abbreviation data, describes the one attribute of a
+  // Dwarf abbreviation.
+  class DIEAbbrevData {
+  private:
+    unsigned Attribute;                 // Dwarf attribute code.
+    unsigned Form;                      // Dwarf form code.
+    
+  public:
+    DIEAbbrevData(unsigned A, unsigned F)
+    : Attribute(A)
+    , Form(F)
+    {}
+    
+    // Accessors
+    unsigned getAttribute() const { return Attribute; }
+    unsigned getForm()      const { return Form; }
+  };
+  
   //===--------------------------------------------------------------------===//
   // DIEAbbrev - Dwarf abbreviation, describes the organization of a debug
   // information object.
-  //
   class DIEAbbrev {
   private:
-    const unsigned char *Data;          // Static array of bytes containing the
-                                        // image of the raw abbreviation data.
+    unsigned Tag;                       // Dwarf tag code.
+    unsigned ChildrenFlag;              // Dwarf children flag.
+    std::vector<DIEAbbrevData> Data;    // Raw data bytes for abbreviation.
 
   public:
   
-    DIEAbbrev(const unsigned char *D)
-    : Data(D)
+    DIEAbbrev(unsigned T, unsigned C)
+    : Tag(T)
+    , ChildrenFlag(C)
+    , Data()
     {}
+    ~DIEAbbrev() {}
     
+    // Accessors
+    unsigned getTag()                           const { return Tag; }
+    unsigned getChildrenFlag()                  const { return ChildrenFlag; }
+    const std::vector<DIEAbbrevData> &getData() const { return Data; }
+
     /// operator== - Used by UniqueVector to locate entry.
     ///
-    bool operator==(const DIEAbbrev &DA) const {
-      return Data == DA.Data;
-    }
+    bool operator==(const DIEAbbrev &DA) const;
 
     /// operator< - Used by UniqueVector to locate entry.
     ///
-    bool operator<(const DIEAbbrev &DA) const {
-      return Data < DA.Data;
-    }
+    bool operator<(const DIEAbbrev &DA) const;
 
-    // Accessors
-    unsigned getTag()                 const { return Data[0]; }
-    unsigned getChildrenFlag()        const { return Data[1]; }
-    unsigned getAttribute(unsigned i) const { return Data[2 + 2 * i + 0]; }
-    unsigned getForm(unsigned i)      const { return Data[2 + 2 * i + 1]; }
+    /// AddAttribute - Adds another set of attribute information to the
+    /// abbreviation.
+    void AddAttribute(unsigned Attribute, unsigned Form) {
+      Data.push_back(DIEAbbrevData(Attribute, Form));
+    }
+    
+    /// Emit - Print the abbreviation using the specified Dwarf writer.
+    ///
+    void Emit(const DwarfWriter &DW) const; 
+        
+#ifndef NDEBUG
+    void print(std::ostream &O);
+    void dump();
+#endif
   };
 
   //===--------------------------------------------------------------------===//
   // DIEValue - A debug information entry value.
   //
-  class DwarfWriter; 
   class DIEValue {
   public:
     enum {
       isInteger,
       isString,
       isLabel,
-      isDelta
+      isAsIsLabel,
+      isDelta,
+      isEntry
     };
     
     unsigned Type;                      // Type of the value
@@ -520,14 +561,14 @@ namespace llvm {
   // 
   class DIEInteger : public DIEValue {
   private:
-    int Value;
+    int Integer;
     
   public:
-    DIEInteger(int V) : DIEValue(isInteger), Value(V) {}
+    DIEInteger(int I) : DIEValue(isInteger), Integer(I) {}
 
     // Implement isa/cast/dyncast.
     static bool classof(const DIEInteger *) { return true; }
-    static bool classof(const DIEValue *V)  { return V->Type == isInteger; }
+    static bool classof(const DIEValue *I)  { return I->Type == isInteger; }
     
     /// EmitValue - Emit integer of appropriate size.
     ///
@@ -542,13 +583,13 @@ namespace llvm {
   // DIEString - A string value DIE.
   // 
   struct DIEString : public DIEValue {
-    const std::string Value;
+    const std::string String;
     
-    DIEString(const std::string &V) : DIEValue(isString), Value(V) {}
+    DIEString(const std::string &S) : DIEValue(isString), String(S) {}
 
     // Implement isa/cast/dyncast.
     static bool classof(const DIEString *) { return true; }
-    static bool classof(const DIEValue *V) { return V->Type == isString; }
+    static bool classof(const DIEValue *S) { return S->Type == isString; }
     
     /// EmitValue - Emit string value.
     ///
@@ -563,13 +604,35 @@ namespace llvm {
   // DIELabel - A simple label expression DIE.
   //
   struct DIELabel : public DIEValue {
-    const DWLabel Value;
+    const DWLabel Label;
+    
+    DIELabel(const DWLabel &L) : DIEValue(isLabel), Label(L) {}
+
+    // Implement isa/cast/dyncast.
+    static bool classof(const DIELabel *)  { return true; }
+    static bool classof(const DIEValue *L) { return L->Type == isLabel; }
+    
+    /// EmitValue - Emit label value.
+    ///
+    virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const;
+    
+    /// SizeOf - Determine size of label value in bytes.
+    ///
+    virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const;
+  };
+
+
+  //===--------------------------------------------------------------------===//
+  // DIEAsIsLabel - An exact name of a label.
+  //
+  struct DIEAsIsLabel : public DIEValue {
+    const std::string Label;
     
-    DIELabel(const DWLabel &V) : DIEValue(isLabel), Value(V) {}
+    DIEAsIsLabel(const std::string &L) : DIEValue(isAsIsLabel), Label(L) {}
 
     // Implement isa/cast/dyncast.
-    static bool classof(const DWLabel *)   { return true; }
-    static bool classof(const DIEValue *V) { return V->Type == isLabel; }
+    static bool classof(const DIEAsIsLabel *) { return true; }
+    static bool classof(const DIEValue *L)    { return L->Type == isAsIsLabel; }
     
     /// EmitValue - Emit label value.
     ///
@@ -584,15 +647,36 @@ namespace llvm {
   // DIEDelta - A simple label difference DIE.
   // 
   struct DIEDelta : public DIEValue {
-    const DWLabel Value1;
-    const DWLabel Value2;
+    const DWLabel LabelHi;
+    const DWLabel LabelLo;
     
-    DIEDelta(const DWLabel &V1, const DWLabel &V2)
-    : DIEValue(isDelta), Value1(V1), Value2(V2) {}
+    DIEDelta(const DWLabel &Hi, const DWLabel &Lo)
+    : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {}
 
     // Implement isa/cast/dyncast.
     static bool classof(const DIEDelta *)  { return true; }
-    static bool classof(const DIEValue *V) { return V->Type == isDelta; }
+    static bool classof(const DIEValue *D) { return D->Type == isDelta; }
+    
+    /// EmitValue - Emit delta value.
+    ///
+    virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const;
+    
+    /// SizeOf - Determine size of delta value in bytes.
+    ///
+    virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const;
+  };
+  
+  //===--------------------------------------------------------------------===//
+  // DIEntry - A pointer to a debug information entry.
+  // 
+  struct DIEntry : public DIEValue {
+    DIE *Entry;
+    
+    DIEntry(DIE *E) : DIEValue(isEntry), Entry(E) {}
+
+    // Implement isa/cast/dyncast.
+    static bool classof(const DIEntry *)   { return true; }
+    static bool classof(const DIEValue *E) { return E->Type == isEntry; }
     
     /// EmitValue - Emit delta value.
     ///
@@ -608,70 +692,106 @@ namespace llvm {
   // describes it's organization.
   class DIE {
   private:
+    DIEAbbrev *Abbrev;                    // Temporary buffer for abbreviation.
     unsigned AbbrevID;                    // Decribing abbreviation ID.
-    unsigned Offset;                      // Offset in debug info section
-    unsigned Size;                        // Size of instance + children
-    std::vector<DIE *> Children;          // Children DIEs
-    std::vector<DIEValue *> Values;       // Attributes values
+    unsigned Offset;                      // Offset in debug info section.
+    unsigned Size;                        // Size of instance + children.
+    DWContext *Context;                   // Context for types and values.
+    std::vector<DIE *> Children;          // Children DIEs.
+    std::vector<DIEValue *> Values;       // Attributes values.
     
   public:
-    DIE(unsigned AbbrevID)
-    : AbbrevID(AbbrevID)
-    , Offset(0)
-    , Size(0)
-    , Children()
-    , Values()
-    {}
-    ~DIE() {
-      for (unsigned i = 0, N = Children.size(); i < N; i++) {
-        delete Children[i];
-      }
-
-      for (unsigned j = 0, M = Children.size(); j < M; j++) {
-        delete Children[j];
-      }
-    }
+    DIE(unsigned Tag, unsigned ChildrenFlag);
+    ~DIE();
     
     // Accessors
-    unsigned getAbbrevID()                     const { return AbbrevID; }
-    unsigned getOffset()                       const { return Offset; }
-    unsigned getSize()                         const { return Size; }
+    unsigned   getAbbrevID()                   const { return AbbrevID; }
+    unsigned   getOffset()                     const { return Offset; }
+    unsigned   getSize()                       const { return Size; }
+    DWContext *getContext()                    const { return Context; }
     const std::vector<DIE *> &getChildren()    const { return Children; }
     const std::vector<DIEValue *> &getValues() const { return Values; }
     void setOffset(unsigned O)                 { Offset = O; }
     void setSize(unsigned S)                   { Size = S; }
-    
-    /// AddValue - Add an attribute value of appropriate type.
-    ///
-    void AddValue(int Value) {
-      Values.push_back(new DIEInteger(Value));
-    }
-    void AddValue(const std::string &Value) {
-      Values.push_back(new DIEString(Value));
-    }
-    void AddValue(const DWLabel &Value) {
-      Values.push_back(new DIELabel(Value));
-    }
-    void AddValue(const DWLabel &Value1, const DWLabel &Value2) {
-      Values.push_back(new DIEDelta(Value1, Value2));
-    }
+    void setContext(DWContext *C)              { Context = C; }
     
     /// SiblingOffset - Return the offset of the debug information entry's
     /// sibling.
     unsigned SiblingOffset() const { return Offset + Size; }
-  };
 
-  //===--------------------------------------------------------------------===//
-  // Forward declarations.
-  //
-  class AsmPrinter;
-  class MachineDebugInfo;
+    /// AddInt - Add a simple integer attribute data and value.
+    ///
+    void AddInt(unsigned Attribute, unsigned Form,  int Integer);
+        
+    /// AddString - Add a std::string attribute data and value.
+    ///
+    void AddString(unsigned Attribute, unsigned Form,
+                   const std::string &String);
+        
+    /// AddLabel - Add a Dwarf label attribute data and value.
+    ///
+    void AddLabel(unsigned Attribute, unsigned Form, const DWLabel &Label);
+        
+    /// AddAsIsLabel - Add a non-Dwarf label attribute data and value.
+    ///
+    void AddAsIsLabel(unsigned Attribute, unsigned Form,
+                      const std::string &Label);
+        
+    /// AddDelta - Add a label delta attribute data and value.
+    ///
+    void AddDelta(unsigned Attribute, unsigned Form,
+                  const DWLabel &Hi, const DWLabel &Lo);
+        
+    ///  AddDIEntry - Add a DIE attribute data and value.
+    ///
+    void AddDIEntry(unsigned Attribute, unsigned Form, DIE *Entry);
+
+    /// Complete - Indicate that all attributes have been added and
+    /// ready to get an abbreviation ID.
+    ///
+    void Complete(DwarfWriter &DW);
+    
+    /// AddChild - Add a child to the DIE.
+    void AddChild(DIE *Child);
+  };
   
   //===--------------------------------------------------------------------===//
-  // DwarfWriter - emits Dwarf debug and exception handling directives.
+  /// DWContext - Name context for types and values.
+  ///
+  class DWContext {
+  private:
+    DwarfWriter &DW;                    // DwarfWriter for global information.
+    DIE *Owner;                         // Owning debug information entry.
+    std::map<std::string, DIE*> Types;  // Named types in context.
+    std::map<std::string, DIE*> Variables;// Named variables in context.
+    
+  public:
+    DWContext(DwarfWriter &D, DIE *O)
+    : DW(D)
+    , Owner(O)
+    , Types()
+    , Variables()
+    {
+      Owner->setContext(this);
+    }
+    ~DWContext() {}
+    
+    /// NewBasicType - Creates a new basic type, if necessary, then adds in the
+    /// context and owner.
+    DIE *NewBasicType(const std::string &Name, unsigned Size,
+                                               unsigned Encoding);
+                                               
+    /// NewVariable - Creates a basic variable, if necessary, then adds in the
+    /// context and owner.
+    DIE *NewVariable(const std::string &Name,
+                     unsigned SourceFileID, unsigned Line,
+                     DIE *Type, bool IsExternal);
+  };
+
+  //===--------------------------------------------------------------------===//
+  // DwarfWriter - Emits Dwarf debug and exception handling directives.
   //
   class DwarfWriter {
-  
   protected:
   
     //===------------------------------------------------------------------===//
@@ -707,6 +827,18 @@ namespace llvm {
     ///
     UniqueVector<DIEAbbrev> Abbreviations;
     
+    /// GlobalTypes - A map of globally visible named types.
+    ///
+    std::map<std::string, DIE *> GlobalTypes;
+    
+    /// GlobalEntities - A map of globally visible named entities.
+    ///
+    std::map<std::string, DIE *> GlobalEntities;
+     
+    /// StringPool - A UniqueVector of strings used by indirect references.
+    ///
+    UniqueVector<std::string> StringPool;
+    
     //===------------------------------------------------------------------===//
     // Properties to be set by the derived class ctor, used to configure the
     // Dwarf writer.
@@ -861,21 +993,34 @@ public:
       EmitReference(Label.Tag, Label.Number);
     }
     void EmitReference(const char *Tag, unsigned Number) const;
+    void EmitReference(const std::string Name) const;
 
     /// EmitDifference - Emit the difference between two labels.  Some
     /// assemblers do not behave with absolute expressions with data directives,
     /// so there is an option (needsSet) to use an intermediary set expression.
-    void EmitDifference(DWLabel Label1, DWLabel Label2) const {
-      EmitDifference(Label1.Tag, Label1.Number, Label2.Tag, Label2.Number);
+    void EmitDifference(DWLabel LabelHi, DWLabel LabelLo) const {
+      EmitDifference(LabelHi.Tag, LabelHi.Number, LabelLo.Tag, LabelLo.Number);
     }
-    void EmitDifference(const char *Tag1, unsigned Number1,
-                        const char *Tag2, unsigned Number2) const;
+    void EmitDifference(const char *TagHi, unsigned NumberHi,
+                        const char *TagLo, unsigned NumberLo) const;
                                    
-private:
-    /// NewDIE - Construct a new structured debug information entry.
+    /// NewAbbreviation - Add the abbreviation to the Abbreviation vector.
     ///  
-    DIE *NewDIE(const unsigned char *AbbrevData);
+    unsigned NewAbbreviation(DIEAbbrev *Abbrev);
+    
+    /// NewString - Add a string to the constant pool and returns a label.
+    ///
+    DWLabel NewString(const std::string &String);
+    
+    /// NewGlobalType - Make the type visible globally using the given name.
+    ///
+    void NewGlobalType(const std::string &Name, DIE *Type);
+    
+    /// NewGlobalEntity - Make the entity visible globally using the given name.
+    ///
+    void NewGlobalEntity(const std::string &Name, DIE *Entity);
 
+private:
     /// NewCompileUnit - Create new compile unit information.
     ///
     DIE *NewCompileUnit(const std::string &Directory,
@@ -956,7 +1101,7 @@ private:
     void SetDebugInfo(MachineDebugInfo *di) { DebugInfo = di; }
     
     //===------------------------------------------------------------------===//
-    // Main enties.
+    // Main entry points.
     //
     
     /// BeginModule - Emit all Dwarf sections that should come prior to the
index 824e94fc26819b90d420494891971172db8799c2..a90a13a07641cffe836a9d0d5df4b3bff26f332e 100644 (file)
@@ -26,84 +26,6 @@ static cl::opt<bool>
 DwarfVerbose("dwarf-verbose", cl::Hidden,
                                 cl::desc("Add comments to Dwarf directives."));
 
-//===----------------------------------------------------------------------===//
-// Dwarf abbreviations used by this emitter.
-//
-
-static const unsigned char AbbrevTAG_compile_unit[] = {
-  DW_TAG_compile_unit,     DW_CHILDREN_yes,
-  DW_AT_stmt_list,         DW_FORM_data4,
-  DW_AT_high_pc,           DW_FORM_addr,
-  DW_AT_low_pc,            DW_FORM_addr,
-  DW_AT_producer,          DW_FORM_string,
-  DW_AT_language,          DW_FORM_data1,
-  DW_AT_name,              DW_FORM_string,
-  DW_AT_comp_dir,          DW_FORM_string,
-  0,                       0
-};
-  
-static const unsigned char AbbrevTAG_subprogram[] = {
-  DW_TAG_subprogram,       DW_CHILDREN_yes,
-  DW_AT_sibling,           DW_FORM_ref4,
-  DW_AT_external,          DW_FORM_flag,
-  DW_AT_name,              DW_FORM_string,
-  DW_AT_decl_file,         DW_FORM_data1,
-  DW_AT_decl_line,         DW_FORM_data1,
-  DW_AT_prototyped,        DW_FORM_flag,
-  DW_AT_type,              DW_FORM_ref4,
-  DW_AT_low_pc,            DW_FORM_addr,
-  DW_AT_high_pc,           DW_FORM_addr,
-  DW_AT_frame_base,        DW_FORM_block1,
-  0,                       0
-};
-  
-static const unsigned char AbbrevTAG_formal_parameter[] = {
-  DW_TAG_formal_parameter, DW_CHILDREN_no,
-  DW_AT_name,              DW_FORM_string,
-  DW_AT_decl_file,         DW_FORM_data1,
-  DW_AT_decl_line,         DW_FORM_data1,
-  DW_AT_type,              DW_FORM_ref4,
-  DW_AT_location,          DW_FORM_block1,
-  0,                       0
-};
-  
-static const unsigned char AbbrevTAG_base_type[] = {
-  DW_TAG_base_type,        DW_CHILDREN_no,
-  DW_AT_name,              DW_FORM_string,
-  DW_AT_byte_size,         DW_FORM_data1,
-  DW_AT_encoding,          DW_FORM_data1,
-  0,                       0
-};
-  
-static const unsigned char AbbrevTAG_pointer_type[] = {
-  DW_TAG_pointer_type,     DW_CHILDREN_no,
-  DW_AT_byte_size,         DW_FORM_data1,
-  DW_AT_type,              DW_FORM_ref4,
-  0,                       0
-};
-  
-static const unsigned char AbbrevTAG_array_type[] = {
-  DW_TAG_array_type,       DW_CHILDREN_yes,
-  DW_AT_sibling,           DW_FORM_ref4,
-  DW_AT_type,              DW_FORM_ref4,
-  0,                       0
-};
-  
-static const unsigned char AbbrevTAG_subrange_type[] = {
-  DW_TAG_subrange_type,    DW_CHILDREN_no,
-  0,                       0
-};
-  
-static const unsigned char AbbrevTAG_variable[] = {
-  DW_TAG_variable,         DW_CHILDREN_no,
-  DW_AT_name,              DW_FORM_string,
-  DW_AT_type,              DW_FORM_ref4,
-  DW_AT_external,          DW_FORM_flag,
-  DW_AT_artificial,        DW_FORM_flag,
-  DW_AT_declaration,       DW_FORM_flag,
-  0,                       0
-};
-
 //===----------------------------------------------------------------------===//
 
 /// TagString - Return the string for the specified tag.
@@ -659,13 +581,102 @@ static const char *CallFrameString(unsigned Encoding) {
 
 //===----------------------------------------------------------------------===//
 
+/// operator== - Used by UniqueVector to locate entry.
+///
+bool DIEAbbrev::operator==(const DIEAbbrev &DA) const {
+  if (Tag != DA.Tag) return false;
+  if (ChildrenFlag != DA.ChildrenFlag) return false;
+  if (Data.size() != DA.Data.size()) return false;
+  
+  for (unsigned i = 0, N = Data.size(); i < N; i++) {
+    const DIEAbbrevData &AttrData = Data[i];
+    const DIEAbbrevData &DAAttrData = Data[i];
+    if (AttrData.getAttribute() != DAAttrData.getAttribute()) return false;
+    if (AttrData.getForm() != DAAttrData.getForm()) return false;
+  }
+  
+  return true;
+}
+
+/// operator< - Used by UniqueVector to locate entry.
+///
+bool DIEAbbrev::operator<(const DIEAbbrev &DA) const {
+  if (Tag != DA.Tag) return Tag < DA.Tag;
+  if (ChildrenFlag != DA.ChildrenFlag) return ChildrenFlag < DA.ChildrenFlag;
+  if (Data.size() != DA.Data.size()) return Data.size() < DA.Data.size();
+  
+  for (unsigned i = 0, N = Data.size(); i < N; i++) {
+    const DIEAbbrevData &AttrData = Data[i];
+    const DIEAbbrevData &DAAttrData = DA.Data[i];
+    if (AttrData.getAttribute() != DAAttrData.getAttribute())
+      return AttrData.getAttribute() < DAAttrData.getAttribute();
+    if (AttrData.getForm() != DAAttrData.getForm())
+      return AttrData.getForm() < DAAttrData.getForm();
+  }
+  
+  return false;
+}
+    
+/// Emit - Print the abbreviation using the specified Dwarf writer.
+///
+void DIEAbbrev::Emit(const DwarfWriter &DW) const {
+  // Emit its Dwarf tag type.
+  DW.EmitULEB128Bytes(Tag);
+  DW.EOL(TagString(Tag));
+  
+  // Emit whether it has children DIEs.
+  DW.EmitULEB128Bytes(ChildrenFlag);
+  DW.EOL(ChildrenString(ChildrenFlag));
+  
+  // For each attribute description.
+  for (unsigned i = 0, N = Data.size(); i < N; i++) {
+    const DIEAbbrevData &AttrData = Data[i];
+    
+    // Emit attribute type.
+    DW.EmitULEB128Bytes(AttrData.getAttribute());
+    DW.EOL(AttributeString(AttrData.getAttribute()));
+    
+    // Emit form type.
+    DW.EmitULEB128Bytes(AttrData.getForm());
+    DW.EOL(FormEncodingString(AttrData.getForm()));
+  }
+
+  // Mark end of abbreviation.
+  DW.EmitULEB128Bytes(0); DW.EOL("EOM(1)");
+  DW.EmitULEB128Bytes(0); DW.EOL("EOM(2)");
+}
+
+#ifndef NDEBUG
+  void DIEAbbrev::print(std::ostream &O) {
+    O << "Abbreviation @"
+      << std::hex << (unsigned)this << std::dec
+      << "  "
+      << TagString(Tag)
+      << " "
+      << ChildrenString(ChildrenFlag)
+      << "\n";
+    
+    for (unsigned i = 0, N = Data.size(); i < N; i++) {
+      O << "  "
+        << AttributeString(Data[i].getAttribute())
+        << "  "
+        << FormEncodingString(Data[i].getForm())
+        << "\n";
+    }
+  }
+  void DIEAbbrev::dump() { print(std::cerr); }
+#endif
+
+//===----------------------------------------------------------------------===//
+
 /// EmitValue - Emit integer of appropriate size.
 ///
 void DIEInteger::EmitValue(const DwarfWriter &DW, unsigned Form) const {
   switch (Form) {
-  case DW_FORM_data1: DW.EmitByte(Value);  break;
-  case DW_FORM_data2: DW.EmitShort(Value); break;
-  case DW_FORM_data4: DW.EmitLong(Value);  break;
+  case DW_FORM_data1: // Fall thru
+  case DW_FORM_flag:  DW.EmitByte(Integer);  break;
+  case DW_FORM_data2: DW.EmitShort(Integer); break;
+  case DW_FORM_data4: DW.EmitLong(Integer);  break;
   default: assert(0 && "DIE Value form not supported yet"); break;
   }
 }
@@ -674,6 +685,7 @@ void DIEInteger::EmitValue(const DwarfWriter &DW, unsigned Form) const {
 ///
 unsigned DIEInteger::SizeOf(const DwarfWriter &DW, unsigned Form) const {
   switch (Form) {
+  case DW_FORM_flag:  // Fall thru
   case DW_FORM_data1: return sizeof(int8_t);
   case DW_FORM_data2: return sizeof(int16_t);
   case DW_FORM_data4: return sizeof(int32_t);
@@ -687,13 +699,13 @@ unsigned DIEInteger::SizeOf(const DwarfWriter &DW, unsigned Form) const {
 /// EmitValue - Emit string value.
 ///
 void DIEString::EmitValue(const DwarfWriter &DW, unsigned Form) const {
-  DW.EmitString(Value);
+  DW.EmitString(String);
 }
 
 /// SizeOf - Determine size of string value in bytes.
 ///
 unsigned DIEString::SizeOf(const DwarfWriter &DW, unsigned Form) const {
-  return Value.size() + sizeof(int8_t);
+  return String.size() + sizeof('\0');
 }
 
 //===----------------------------------------------------------------------===//
@@ -701,7 +713,7 @@ unsigned DIEString::SizeOf(const DwarfWriter &DW, unsigned Form) const {
 /// EmitValue - Emit label value.
 ///
 void DIELabel::EmitValue(const DwarfWriter &DW, unsigned Form) const {
-  DW.EmitReference(Value);
+  DW.EmitReference(Label);
 }
 
 /// SizeOf - Determine size of label value in bytes.
@@ -712,10 +724,24 @@ unsigned DIELabel::SizeOf(const DwarfWriter &DW, unsigned Form) const {
     
 //===----------------------------------------------------------------------===//
 
+/// EmitValue - Emit label value.
+///
+void DIEAsIsLabel::EmitValue(const DwarfWriter &DW, unsigned Form) const {
+  DW.EmitReference(Label);
+}
+
+/// SizeOf - Determine size of label value in bytes.
+///
+unsigned DIEAsIsLabel::SizeOf(const DwarfWriter &DW, unsigned Form) const {
+  return DW.getAddressSize();
+}
+    
+//===----------------------------------------------------------------------===//
+
 /// EmitValue - Emit delta value.
 ///
 void DIEDelta::EmitValue(const DwarfWriter &DW, unsigned Form) const {
-  DW.EmitDifference(Value1, Value2);
+  DW.EmitDifference(LabelHi, LabelLo);
 }
 
 /// SizeOf - Determine size of delta value in bytes.
@@ -724,6 +750,171 @@ unsigned DIEDelta::SizeOf(const DwarfWriter &DW, unsigned Form) const {
   return DW.getAddressSize();
 }
 
+//===----------------------------------------------------------------------===//
+/// EmitValue - Emit extry offset.
+///
+void DIEntry::EmitValue(const DwarfWriter &DW, unsigned Form) const {
+  DW.EmitLong(Entry->getOffset());
+}
+
+/// SizeOf - Determine size of label value in bytes.
+///
+unsigned DIEntry::SizeOf(const DwarfWriter &DW, unsigned Form) const {
+  return sizeof(int32_t);
+}
+    
+//===----------------------------------------------------------------------===//
+
+DIE::DIE(unsigned Tag, unsigned ChildrenFlag)
+: Abbrev(new DIEAbbrev(Tag, ChildrenFlag))
+, AbbrevID(0)
+, Offset(0)
+, Size(0)
+, Context(NULL)
+, Children()
+, Values()
+{}
+
+DIE::~DIE() {
+  if (Abbrev) delete Abbrev;
+  
+  for (unsigned i = 0, N = Children.size(); i < N; i++) {
+    delete Children[i];
+  }
+
+  for (unsigned j = 0, M = Values.size(); j < M; j++) {
+    delete Values[j];
+  }
+  
+  if (Context) delete Context;
+}
+    
+/// AddInt - Add a simple integer attribute data and value.
+///
+void DIE::AddInt(unsigned Attribute, unsigned Form,
+                 int Integer) {
+  Abbrev->AddAttribute(Attribute, Form);
+  Values.push_back(new DIEInteger(Integer));
+}
+    
+/// AddString - Add a std::string attribute data and value.
+///
+void DIE::AddString(unsigned Attribute, unsigned Form,
+                    const std::string &String) {
+  Abbrev->AddAttribute(Attribute, Form);
+  Values.push_back(new DIEString(String));
+}
+    
+/// AddLabel - Add a Dwarf label attribute data and value.
+///
+void DIE::AddLabel(unsigned Attribute, unsigned Form,
+                   const DWLabel &Label) {
+  Abbrev->AddAttribute(Attribute, Form);
+  Values.push_back(new DIELabel(Label));
+}
+    
+/// AddAsIsLabel - Add an non-Dwarf label attribute data and value.
+///
+void DIE::AddAsIsLabel(unsigned Attribute, unsigned Form,
+                       const std::string &Label) {
+  Abbrev->AddAttribute(Attribute, Form);
+  Values.push_back(new DIEAsIsLabel(Label));
+}
+    
+/// AddDelta - Add a label delta attribute data and value.
+///
+void DIE::AddDelta(unsigned Attribute, unsigned Form,
+                   const DWLabel &Hi, const DWLabel &Lo) {
+  Abbrev->AddAttribute(Attribute, Form);
+  Values.push_back(new DIEDelta(Hi, Lo));
+}
+    
+/// AddDIEntry - Add a DIE attribute data and value.
+///
+void DIE::AddDIEntry(unsigned Attribute,
+                     unsigned Form, DIE *Entry) {
+  Abbrev->AddAttribute(Attribute, Form);
+  Values.push_back(new DIEntry(Entry));
+}
+
+/// Complete - Indicate that all attributes have been added and ready to get an
+/// abbreviation ID.
+void DIE::Complete(DwarfWriter &DW) {
+  AbbrevID = DW.NewAbbreviation(Abbrev);
+  delete Abbrev;
+  Abbrev = NULL;
+}
+
+/// AddChild - Add a child to the DIE.
+///
+void DIE::AddChild(DIE *Child) {
+  Children.push_back(Child);
+}
+
+//===----------------------------------------------------------------------===//
+
+/// NewBasicType - Creates a new basic type if necessary, then adds in the
+/// context and owner.
+DIE *DWContext::NewBasicType(const std::string &Name, unsigned Size,
+                                                      unsigned Encoding) {
+  // FIXME - Just a prototype.
+  DIE *Type = Types[Name];
+  
+  // If first occurance of type.
+  if (!Type) {
+    // construct the type DIE.
+    Type = new DIE(DW_TAG_base_type, DW_CHILDREN_no);
+    Type->AddString(DW_AT_name,      DW_FORM_string, Name);
+    Type->AddInt   (DW_AT_byte_size, DW_FORM_data1,  Size);
+    Type->AddInt   (DW_AT_encoding,  DW_FORM_data1,  Encoding);
+    Type->Complete(DW);
+    
+    // Add to context owner.
+    Owner->AddChild(Type);
+
+    // Add to map.
+    Types[Name] = Type;
+  }
+  
+  return Type;
+}
+
+/// NewVariable - Creates a basic variable, if necessary, then adds in the
+/// context and owner.
+DIE *DWContext::NewVariable(const std::string &Name,
+                            unsigned SourceFileID, unsigned Line,
+                            DIE *Type, bool IsExternal) {
+  // FIXME - Just a prototype.
+  DIE *Variable = Variables[Name];
+  
+  // If first occurance of variable.
+  if (!Variable) {
+    assert(IsExternal && "Internal variables not handled yet");
+    Variable = new DIE(DW_TAG_variable, DW_CHILDREN_no);
+    Variable->AddString   (DW_AT_name,      DW_FORM_string, Name);
+    Variable->AddInt      (DW_AT_decl_file, DW_FORM_data1,  SourceFileID);
+    Variable->AddInt      (DW_AT_decl_line, DW_FORM_data1,  Line);
+    Variable->AddDIEntry  (DW_AT_type,      DW_FORM_ref4,   Type);
+    Variable->AddInt      (DW_AT_external,  DW_FORM_flag,   (int)IsExternal);
+    Variable->AddAsIsLabel(DW_AT_location,  DW_FORM_block1,
+                           std::string("_")+Name+".b");
+    Variable->Complete(DW);
+    // Add to context owner.
+    Owner->AddChild(Variable);
+    
+    // Add to map.
+    Variables[Name] = Variable;
+    
+    // If external add to visible names.
+    if (IsExternal) {
+      DW.NewGlobalEntity(Name, Variable);
+    }
+  }
+  
+  return Variable;
+}
+
 //===----------------------------------------------------------------------===//
 
 /// PrintHex - Print a value as a hexidecimal value.
@@ -903,20 +1094,29 @@ void DwarfWriter::EmitReference(const char *Tag, unsigned Number) const {
     
   PrintLabelName(Tag, Number);
 }
+void DwarfWriter::EmitReference(const std::string Name) const {
+  if (AddressSize == 4)
+    O << Asm->Data32bitsDirective;
+  else
+    O << Asm->Data64bitsDirective;
+    
+  O << Name;
+}
 
 /// EmitDifference - Emit an label difference as sizeof(pointer) value.  Some
 /// assemblers do not accept absolute expressions with data directives, so there 
 /// is an option (needsSet) to use an intermediary 'set' expression.
-void DwarfWriter::EmitDifference(const char *Tag1, unsigned Number1,
-                                 const char *Tag2, unsigned Number2) const {
+void DwarfWriter::EmitDifference(const char *TagHi, unsigned NumberHi,
+                                 const char *TagLo, unsigned NumberLo) const {
   if (needsSet) {
     static unsigned SetCounter = 0;
+    
     O << "\t.set\t";
     PrintLabelName("set", SetCounter);
     O << ",";
-    PrintLabelName(Tag1, Number1);
+    PrintLabelName(TagHi, NumberHi);
     O << "-";
-    PrintLabelName(Tag2, Number2);
+    PrintLabelName(TagLo, NumberLo);
     O << "\n";
     
     if (AddressSize == sizeof(int32_t))
@@ -933,40 +1133,58 @@ void DwarfWriter::EmitDifference(const char *Tag1, unsigned Number1,
     else
       O << Asm->Data64bitsDirective;
       
-    PrintLabelName(Tag1, Number1);
+    PrintLabelName(TagHi, NumberHi);
     O << "-";
-    PrintLabelName(Tag2, Number2);
+    PrintLabelName(TagLo, NumberLo);
   }
 }
 
-/// NewDIE - Construct a new structured debug information entry.
+/// NewAbbreviation - Add the abbreviation to the Abbreviation vector.
 ///  
-DIE *DwarfWriter::NewDIE(const unsigned char *AbbrevData) {
-  // Get the abbreviation ID.
-  unsigned AbbrevID = Abbreviations.insert(DIEAbbrev(AbbrevData));
-  // Allocate new new structured DIE.
-  DIE *Die = new DIE(AbbrevID);
-  // Return  structured DIE.
-  return Die;
+unsigned DwarfWriter::NewAbbreviation(DIEAbbrev *Abbrev) {
+  return Abbreviations.insert(*Abbrev);
+}
+
+/// NewString - Add a string to the constant pool and returns a label.
+///
+DWLabel DwarfWriter::NewString(const std::string &String) {
+  unsigned StringID = StringPool.insert(String);
+  return DWLabel("string", StringID);
+}
+
+/// NewGlobalType - Make the type visible globally using the given name.
+///
+void DwarfWriter::NewGlobalType(const std::string &Name, DIE *Type) {
+  // FIXME - check for duplication.
+  GlobalTypes[Name] = Type;
+}
+
+/// NewGlobalEntity - Make the entity visible globally using the given name.
+///
+void DwarfWriter::NewGlobalEntity(const std::string &Name, DIE *Entity) {
+  // FIXME - check for duplication.
+  GlobalEntities[Name] = Entity;
 }
 
 /// NewCompileUnit - Create new compile unit information.
 ///
 DIE *DwarfWriter::NewCompileUnit(const std::string &Directory,
                                  const std::string &SourceName) {
-  DIE *Die = NewDIE(AbbrevTAG_compile_unit);
+  DIE *Unit = new DIE(DW_TAG_compile_unit, DW_CHILDREN_yes);
   // FIXME - use the correct line set.
-  Die->AddValue(DWLabel("line", 0));
-  Die->AddValue(DWLabel("text_end", 0));
-  Die->AddValue(DWLabel("text_begin", 0));
+  Unit->AddLabel (DW_AT_stmt_list, DW_FORM_data4,  DWLabel("line", 0));
+  Unit->AddLabel (DW_AT_high_pc,   DW_FORM_addr,   DWLabel("text_end", 0));
+  Unit->AddLabel (DW_AT_low_pc,    DW_FORM_addr,   DWLabel("text_begin", 0));
   // FIXME - The producer needs to be in this form, but should come from
   // an appropriate source.
-  Die->AddValue("llvm 3.4.x (LLVM Research Group)");
-  Die->AddValue(DW_LANG_C89);
-  Die->AddValue(SourceName);
-  Die->AddValue(Directory);
+  Unit->AddString(DW_AT_producer,  DW_FORM_string,
+                  "llvm 3.4.x (LLVM Research Group)");
+  Unit->AddInt   (DW_AT_language,  DW_FORM_data1,  DW_LANG_C89);
+  Unit->AddString(DW_AT_name,      DW_FORM_string, SourceName);
+  Unit->AddString(DW_AT_comp_dir,  DW_FORM_string, Directory);
+  Unit->Complete(*this);
   
-  return Die;
+  return Unit;
 }
 
 /// EmitInitial - Emit initial Dwarf declarations.  This is necessary for cc
@@ -1003,11 +1221,12 @@ void DwarfWriter::EmitDIE(DIE *Die) const {
       " ");
   
   const std::vector<DIEValue *> &Values = Die->getValues();
+  const std::vector<DIEAbbrevData> &AbbrevData = Abbrev.getData();
   
   // Emit the DIE attribute values.
   for (unsigned i = 0, N = Values.size(); i < N; i++) {
-    unsigned Attr = Abbrev.getAttribute(i);
-    unsigned Form = Abbrev.getForm(i);
+    unsigned Attr = AbbrevData[i].getAttribute();
+    unsigned Form = AbbrevData[i].getForm();
     assert(Form && "Too many attributes for DIE (check abbreviation)");
     
     switch (Attr) {
@@ -1053,11 +1272,12 @@ unsigned DwarfWriter::SizeAndOffsetDie(DIE *Die, unsigned Offset) const {
   Offset += SizeULEB128(AbbrevID);
   
   const std::vector<DIEValue *> &Values = Die->getValues();
+  const std::vector<DIEAbbrevData> &AbbrevData = Abbrev.getData();
 
   // Emit the DIE attribute values.
   for (unsigned i = 0, N = Values.size(); i < N; i++) {
     // Size attribute value.
-    Offset += Values[i]->SizeOf(*this, Abbrev.getForm(i));
+    Offset += Values[i]->SizeOf(*this, AbbrevData[i].getForm());
   }
   
   // Emit the DIE children if any.
@@ -1085,7 +1305,7 @@ void DwarfWriter::SizeAndOffsets() {
   unsigned Offset = sizeof(int32_t) + // Length of Compilation Unit Info
                     sizeof(int16_t) + // DWARF version number
                     sizeof(int32_t) + // Offset Into Abbrev. Section
-                    sizeof(int8_t);  // Pointer Size (in bytes)
+                    sizeof(int8_t);   // Pointer Size (in bytes)
   
   // Process each compile unit.
   for (unsigned i = 0, N = CompileUnits.size(); i < N; i++) {
@@ -1104,6 +1324,8 @@ void DwarfWriter::EmitDebugInfo() const {
   
   // If there are any compile units.
   if (N) {
+    EmitLabel("info_begin", 0);
+    
     // Emit the compile units header.
 
     // Emit size of content not including length itself
@@ -1113,7 +1335,7 @@ void DwarfWriter::EmitDebugInfo() const {
     
     EmitShort(DWARF_VERSION); EOL("DWARF version number");
 
-    EmitReference("abbrev", 0); EOL("Offset Into Abbrev. Section");
+    EmitReference("abbrev_begin", 0); EOL("Offset Into Abbrev. Section");
 
     EmitByte(AddressSize); EOL("Address Size (in bytes)");
     
@@ -1121,52 +1343,35 @@ void DwarfWriter::EmitDebugInfo() const {
     for (unsigned i = 0; i < N; i++) {
       EmitDIE(CompileUnits[i]);
     }
+    
+    EmitLabel("info_end", 0);
   }
 }
 
 /// EmitAbbreviations - Emit the abbreviation section.
 ///
 void DwarfWriter::EmitAbbreviations() const {
-  // Start the debug abbrev section.
-  Asm->SwitchSection(DwarfAbbrevSection, 0);
-  
-  // For each abbrevation.
-  for (unsigned AbbrevID = 1, NAID = Abbreviations.size();
-                AbbrevID <= NAID; AbbrevID++) {
-    // Get abbreviation data
-    const DIEAbbrev &Abbrev = Abbreviations[AbbrevID];
-    
-    // Emit the abbrevations code (base 1 index.)
-    EmitULEB128Bytes(AbbrevID); EOL("Abbreviation Code");
+  // Check to see if it is worth the effort.
+  if (!Abbreviations.empty()) {
+    // Start the debug abbrev section.
+    Asm->SwitchSection(DwarfAbbrevSection, 0);
     
-    // Emit its Dwarf tag type.
-    EmitULEB128Bytes(Abbrev.getTag());
-    EOL(TagString(Abbrev.getTag()));
+    EmitLabel("abbrev_begin", 0);
     
-    // Emit whether it has children DIEs.
-    EmitULEB128Bytes(Abbrev.getChildrenFlag());
-    EOL(ChildrenString(Abbrev.getChildrenFlag()));
-    
-    // For each attribute description.
-    for (unsigned i = 0; ; i++) {
-      unsigned Attr = Abbrev.getAttribute(i);
-      unsigned Form = Abbrev.getForm(i);
-      
-      // Attributes are null terminated.
-      if (!Attr) break;
+    // For each abbrevation.
+    for (unsigned AbbrevID = 1, NAID = Abbreviations.size();
+                  AbbrevID <= NAID; AbbrevID++) {
+      // Get abbreviation data
+      const DIEAbbrev &Abbrev = Abbreviations[AbbrevID];
       
-      // Emit attribute type.
-      EmitULEB128Bytes(Attr);
-      EOL(AttributeString(Attr));
+      // Emit the abbrevations code (base 1 index.)
+      EmitULEB128Bytes(AbbrevID); EOL("Abbreviation Code");
       
-      // Emit form type.
-      EmitULEB128Bytes(Form);
-      EOL(FormEncodingString(Form));
+      // Emit the abbreviations data.
+      Abbrev.Emit(*this);
     }
-
-    // Mark end of abbreviation.
-    EmitULEB128Bytes(0); EOL("EOM(1)");
-    EmitULEB128Bytes(0); EOL("EOM(2)");
+    
+    EmitLabel("abbrev_end", 0);
   }
 }
 
@@ -1303,22 +1508,67 @@ void DwarfWriter::EmitDebugFrame() {
 /// EmitDebugPubNames - Emit visible names into a debug pubnames section.
 ///
 void DwarfWriter::EmitDebugPubNames() {
-  // Start the dwarf pubnames section.
-  Asm->SwitchSection(DwarfPubNamesSection, 0);
+  // Check to see if it is worth the effort.
+  if (!GlobalEntities.empty()) {
+    // Start the dwarf pubnames section.
+    Asm->SwitchSection(DwarfPubNamesSection, 0);
+    
+    EmitDifference("pubnames_end", 0, "pubnames_begin", 0);
+    EOL("Length of Public Names Info");
+    
+    EmitLabel("pubnames_begin", 0);
+    
+    EmitShort(DWARF_VERSION); EOL("DWARF Version");
+    
+    EmitReference("info_begin", 0); EOL("Offset of Compilation Unit Info");
+
+    EmitDifference("info_end", 0, "info_begin", 0);
+    EOL("Compilation Unit Length");
+    
+    for (std::map<std::string, DIE *>::iterator G = GlobalTypes.begin(),
+                                                GE = GlobalTypes.begin();
+         G != GE; G++) {
+      const std::string &Name = (*G).first;
+      DIE * Entity = (*G).second;
+      
+      EmitLong(Entity->getOffset()); EOL("DIE offset");
+      EmitString(Name); EOL("External Name");
+      
+    }
+  
+    EmitLong(0); EOL("End Mark");
+    EmitLabel("pubnames_end", 0);
+  }
 }
 
 /// EmitDebugPubTypes - Emit visible names into a debug pubtypes section.
 ///
 void DwarfWriter::EmitDebugPubTypes() {
-  // Start the dwarf pubtypes section.
-  Asm->SwitchSection(DwarfPubTypesSection, 0);
+  // Check to see if it is worth the effort.
+  if (!GlobalTypes.empty()) {
+    // Start the dwarf pubtypes section.
+    Asm->SwitchSection(DwarfPubTypesSection, 0);
+  }
 }
 
 /// EmitDebugStr - Emit visible names into a debug str section.
 ///
 void DwarfWriter::EmitDebugStr() {
-  // Start the dwarf str section.
-  Asm->SwitchSection(DwarfStrSection, 0);
+  // Check to see if it is worth the effort.
+  if (!StringPool.empty()) {
+    // Start the dwarf str section.
+    Asm->SwitchSection(DwarfStrSection, 0);
+    
+    // For each of strings in teh string pool.
+    for (unsigned StringID = 1, N = StringPool.size();
+         StringID <= N; StringID++) {
+      // Emit a label for reference from debug information entries.
+      EmitLabel("string", StringID);
+      // Emit the string itself.
+      const std::string &String = StringPool[StringID];
+      EmitString(String); O << "\n";
+    }
+  }
 }
 
 /// EmitDebugLoc - Emit visible names into a debug loc section.
@@ -1341,7 +1591,7 @@ void DwarfWriter::EmitDebugARanges() {
   
   EmitShort(DWARF_VERSION); EOL("Dwarf Version");
   
-  EmitReference("info", 0); EOL("Offset of Compilation Unit Info");
+  EmitReference("info_begin", 0); EOL("Offset of Compilation Unit Info");
 
   EmitByte(AddressSize); EOL("Size of Address");
 
@@ -1389,7 +1639,7 @@ bool DwarfWriter::ShouldEmitDwarf() {
 }
 
 //===----------------------------------------------------------------------===//
-// Main enties.
+// Main entry points.
 //
     
   DwarfWriter::DwarfWriter(std::ostream &o, AsmPrinter *ap)
@@ -1399,6 +1649,9 @@ bool DwarfWriter::ShouldEmitDwarf() {
   , didInitial(false)
   , CompileUnits()
   , Abbreviations()
+  , GlobalTypes()
+  , GlobalEntities()
+  , StringPool()
   , AddressSize(sizeof(int32_t))
   , hasLEB128(false)
   , hasDotLoc(false)
@@ -1419,6 +1672,9 @@ bool DwarfWriter::ShouldEmitDwarf() {
   , DataSection(".data")
   {}
   DwarfWriter::~DwarfWriter() {
+    for (unsigned i = 0, N = CompileUnits.size(); i < N; i++) {
+      delete CompileUnits[i];
+    }
   }
 
 /// BeginModule - Emit all Dwarf sections that should come prior to the content.
@@ -1439,7 +1695,7 @@ void DwarfWriter::EndModule() {
   EmitLabel("text_end", 0);
   Asm->SwitchSection(DataSection, 0);
   EmitLabel("data_end", 0);
-
+  
   // Get directory and source information.
   const UniqueVector<std::string> &Directories = DebugInfo->getDirectories();
   const UniqueVector<SourceFileInfo> &SourceFiles = DebugInfo->getSourceFiles();
@@ -1450,8 +1706,16 @@ void DwarfWriter::EndModule() {
     const SourceFileInfo &SourceFile = SourceFiles[SourceID];
     const std::string &Directory = Directories[SourceFile.getDirectoryID()];
     const std::string &SourceName = SourceFile.getName();
-    DIE *CompileUnit = NewCompileUnit(Directory, SourceName);
-    CompileUnits.push_back(CompileUnit);
+    DIE *Unit = NewCompileUnit(Directory, SourceName);
+    
+#if 0
+    // FIXME - just testing.
+    DWContext *Context = new DWContext(*this, Unit);
+    DIE *TypeInt = Context->NewBasicType("int", sizeof(int32_t), DW_ATE_signed);
+    Context->NewVariable("MyGlobal", SourceID, 1, TypeInt, true);
+#endif
+
+    CompileUnits.push_back(Unit);
   }
 
   // Compute DIE offsets and sizes.