DwarfWriter reading basic type information from llvm-gcc4 code.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@26331 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/llvm/CodeGen/DwarfWriter.h b/include/llvm/CodeGen/DwarfWriter.h
index 5fbc8d9..b995300 100644
--- a/include/llvm/CodeGen/DwarfWriter.h
+++ b/include/llvm/CodeGen/DwarfWriter.h
@@ -43,6 +43,7 @@
   class Module;
   class SubprogramDesc;
   class Type;
+  class TypeDesc;
   
   //===--------------------------------------------------------------------===//
   // DWLabel - Labels are used to track locations in the assembler file.
@@ -626,6 +627,14 @@
     void NewGlobalEntity(const std::string &Name, DIE *Entity);
 
 private:
+
+    /// NewType - Create a new type DIE.
+    ///
+    DIE *NewType(DIE *Unit, TypeDesc *TyDesc);
+    
+    /// NewCompileUnit - Create new compile unit DIE.
+    ///
+    DIE *NewCompileUnit(CompileUnitDesc *CompileUnit);
     
     /// NewGlobalVariable - Make a new global variable DIE.
     ///
@@ -635,10 +644,6 @@
     ///
     DIE *NewSubprogram(SubprogramDesc *SPD);
 
-    /// NewCompileUnit - Create new compile unit information.
-    ///
-    DIE *NewCompileUnit(CompileUnitDesc *CompileUnit);
-
     /// EmitInitial - Emit initial Dwarf declarations.
     ///
     void EmitInitial() const;
diff --git a/include/llvm/CodeGen/MachineDebugInfo.h b/include/llvm/CodeGen/MachineDebugInfo.h
index 60eebd9..c51b3ea 100644
--- a/include/llvm/CodeGen/MachineDebugInfo.h
+++ b/include/llvm/CodeGen/MachineDebugInfo.h
@@ -61,7 +61,8 @@
   DI_TAG_anchor = 0,
   DI_TAG_compile_unit,
   DI_TAG_global_variable,
-  DI_TAG_subprogram
+  DI_TAG_subprogram,
+  DI_TAG_basictype
 };
 
 //===----------------------------------------------------------------------===//
@@ -80,6 +81,7 @@
   /// appropriate action for the type of field.
   virtual void Apply(int &Field) = 0;
   virtual void Apply(unsigned &Field) = 0;
+  virtual void Apply(uint64_t &Field) = 0;
   virtual void Apply(bool &Field) = 0;
   virtual void Apply(std::string &Field) = 0;
   virtual void Apply(DebugInfoDesc *&Field) = 0;
@@ -274,14 +276,80 @@
 };
 
 //===----------------------------------------------------------------------===//
+/// TypeDesc - This class packages debug information associated with a type.
+///
+class TypeDesc : public DebugInfoDesc {
+private:
+  DebugInfoDesc *Context;               // Context debug descriptor.
+  std::string Name;                     // Type name.
+  uint64_t Size;                        // Type size.
+
+protected:
+  TypeDesc(unsigned T);
+
+public:
+  // Accessors
+  DebugInfoDesc *getContext()                const { return Context; }
+  const std::string &getName()               const { return Name; }
+  uint64_t getSize()                         const { return Size; }
+  void setContext(DebugInfoDesc *C)                { Context = C; }
+  void setName(const std::string &N)               { Name = N; }
+  void setSize(uint64_t S)                         { Size = S; }
+  
+  /// ApplyToFields - Target the visitor to the fields of the  TypeDesc.
+  ///
+  virtual void ApplyToFields(DIVisitor *Visitor);
+
+  /// getDescString - Return a string used to compose global names and labels.
+  ///
+  virtual const char *getDescString() const;
+
+  /// getTypeString - Return a string used to label this descriptor's type.
+  ///
+  virtual const char *getTypeString() const;
+  
+#ifndef NDEBUG
+  virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
+/// BasicTypeDesc - This class packages debug information associated with a
+/// basic type (eg. int, bool, double.)
+class BasicTypeDesc : public TypeDesc {
+private:
+  unsigned Encoding;                    // Type encoding.
+  
+public:
+  BasicTypeDesc();
+  
+  // Accessors
+  unsigned getEncoding()                     const { return Encoding; }
+  void setEncoding(unsigned E)                     { Encoding = E; }
+
+  // Implement isa/cast/dyncast.
+  static bool classof(const BasicTypeDesc *)  { return true; }
+  static bool classof(const DebugInfoDesc *D) {
+    return D->getTag() == DI_TAG_basictype;
+  }
+  
+  /// ApplyToFields - Target the visitor to the fields of the  BasicTypeDesc.
+  ///
+  virtual void ApplyToFields(DIVisitor *Visitor);
+
+#ifndef NDEBUG
+  virtual void dump();
+#endif
+};
+
+//===----------------------------------------------------------------------===//
 /// GlobalDesc - This class is the base descriptor for global functions and
 /// variables.
 class GlobalDesc : public AnchoredDesc {
 private:
   DebugInfoDesc *Context;               // Context debug descriptor.
   std::string Name;                     // Global name.
-  // FIXME - Use a descriptor.
-  GlobalVariable *TyDesc;               // Type debug descriptor.
+  TypeDesc *TyDesc;                     // Type debug descriptor.
   bool IsStatic;                        // Is the global a static.
   bool IsDefinition;                    // Is the global defined in context.
   
@@ -292,10 +360,12 @@
   // Accessors
   DebugInfoDesc *getContext()                const { return Context; }
   const std::string &getName()               const { return Name; }
+  TypeDesc *getTypeDesc()                    const { return TyDesc; }
   bool isStatic()                            const { return IsStatic; }
   bool isDefinition()                        const { return IsDefinition; }
   void setContext(DebugInfoDesc *C)                { Context = C; }
   void setName(const std::string &N)               { Name = N; }
+  void setTypeDesc(TypeDesc *T)                    { TyDesc = T; }
   void setIsStatic(bool IS)                        { IsStatic = IS; }
   void setIsDefinition(bool ID)                    { IsDefinition = ID; }
 
diff --git a/lib/CodeGen/DwarfWriter.cpp b/lib/CodeGen/DwarfWriter.cpp
index 2a07110..2ead4ce 100644
--- a/lib/CodeGen/DwarfWriter.cpp
+++ b/lib/CodeGen/DwarfWriter.cpp
@@ -1232,7 +1232,40 @@
   GlobalEntities[Name] = Entity;
 }
 
-/// NewCompileUnit - Create new compile unit information.
+/// NewType - Create a new type DIE.
+///
+DIE *DwarfWriter::NewType(DIE *Unit, TypeDesc *TyDesc) {
+  // Check for pre-existence.
+  DIE *&Slot = DescToDieMap[TyDesc];
+  if (Slot) return Slot;
+
+  // Get core information.
+  const std::string &Name = TyDesc->getName();
+  // FIXME - handle larger sizes.
+  unsigned Size = TyDesc->getSize() >> 3;
+  
+  // Determine how to handle.
+  if (BasicTypeDesc *BasicTyDesc = dyn_cast<BasicTypeDesc>(TyDesc)) {
+    unsigned Encoding = BasicTyDesc->getEncoding();
+  
+    DIE *Ty = new DIE(DW_TAG_base_type);
+    if (!Name.empty())  Ty->AddString(DW_AT_name, DW_FORM_string, Name);
+
+    Ty->AddUInt  (DW_AT_byte_size, 0,              Size);
+    Ty->AddUInt  (DW_AT_encoding,  DW_FORM_data1,  Encoding);
+    
+    Slot = Ty;
+  } else {
+    assert(0 && "Type not supported yet");
+  }
+ 
+  // Add to context owner.
+  Unit->AddChild(Slot);
+  
+  return Slot;
+}
+
+/// NewCompileUnit - Create new compile unit DIE.
 ///
 DIE *DwarfWriter::NewCompileUnit(CompileUnitDesc *CompileUnit) {
   // Check for pre-existence.
@@ -1275,9 +1308,10 @@
   unsigned FileID = DebugInfo->RecordSource(CompileUnit);
   unsigned Line = GVD->getLine();
   
-  // FIXME - faking the type for the time being.
-  DIE *Type = NewBasicType(Unit, Type::IntTy); 
-                                    
+  // Get the global's type.
+  DIE *Type = NewType(Unit, GVD->getTypeDesc()); 
+
+  // Create the globale variable DIE.
   DIE *VariableDie = new DIE(DW_TAG_variable);
   VariableDie->AddString     (DW_AT_name,      DW_FORM_string, Name);
   VariableDie->AddUInt       (DW_AT_decl_file, 0,              FileID);
diff --git a/lib/CodeGen/MachineDebugInfo.cpp b/lib/CodeGen/MachineDebugInfo.cpp
index b801cad..44b71fa 100644
--- a/lib/CodeGen/MachineDebugInfo.cpp
+++ b/lib/CodeGen/MachineDebugInfo.cpp
@@ -197,6 +197,7 @@
   ///
   virtual void Apply(int &Field)             { ++Count; }
   virtual void Apply(unsigned &Field)        { ++Count; }
+  virtual void Apply(uint64_t &Field)        { ++Count; }
   virtual void Apply(bool &Field)            { ++Count; }
   virtual void Apply(std::string &Field)     { ++Count; }
   virtual void Apply(DebugInfoDesc *&Field)  { ++Count; }
@@ -230,6 +231,10 @@
     Constant *C = CI->getOperand(I++);
     Field = cast<ConstantUInt>(C)->getValue();
   }
+  virtual void Apply(uint64_t &Field) {
+    Constant *C = CI->getOperand(I++);
+    Field = cast<ConstantUInt>(C)->getValue();
+  }
   virtual void Apply(bool &Field) {
     Constant *C = CI->getOperand(I++);
     Field = cast<ConstantBool>(C)->getValue();
@@ -271,6 +276,9 @@
   virtual void Apply(unsigned &Field) {
     Elements.push_back(ConstantUInt::get(Type::UIntTy, Field));
   }
+  virtual void Apply(uint64_t &Field) {
+    Elements.push_back(ConstantUInt::get(Type::UIntTy, Field));
+  }
   virtual void Apply(bool &Field) {
     Elements.push_back(ConstantBool::get(Field));
   }
@@ -327,6 +335,9 @@
   virtual void Apply(unsigned &Field) {
     Fields.push_back(Type::UIntTy);
   }
+  virtual void Apply(uint64_t &Field) {
+    Fields.push_back(Type::UIntTy);
+  }
   virtual void Apply(bool &Field) {
     Fields.push_back(Type::BoolTy);
   }
@@ -377,6 +388,10 @@
     Constant *C = CI->getOperand(I++);
     IsValid = IsValid && isa<ConstantInt>(C);
   }
+  virtual void Apply(uint64_t &Field) {
+    Constant *C = CI->getOperand(I++);
+    IsValid = IsValid && isa<ConstantInt>(C);
+  }
   virtual void Apply(bool &Field) {
     Constant *C = CI->getOperand(I++);
     IsValid = IsValid && isa<ConstantBool>(C);
@@ -414,6 +429,7 @@
   case DI_TAG_compile_unit:    return new CompileUnitDesc();
   case DI_TAG_global_variable: return new GlobalVariableDesc();
   case DI_TAG_subprogram:      return new SubprogramDesc();
+  case DI_TAG_basictype:       return new BasicTypeDesc();
   default: break;
   }
   return NULL;
@@ -545,6 +561,75 @@
 
 //===----------------------------------------------------------------------===//
 
+//===----------------------------------------------------------------------===//
+
+TypeDesc::TypeDesc(unsigned T)
+: DebugInfoDesc(T)
+, Context(NULL)
+, Name("")
+, Size(0)
+{}
+
+/// ApplyToFields - Target the visitor to the fields of the  TypeDesc.
+///
+void TypeDesc::ApplyToFields(DIVisitor *Visitor) {
+  DebugInfoDesc::ApplyToFields(Visitor);
+  
+  Visitor->Apply(Context);
+  Visitor->Apply(Name);
+  Visitor->Apply(Size);
+}
+
+/// getDescString - Return a string used to compose global names and labels.
+///
+const char *TypeDesc::getDescString() const {
+  return "llvm.dbg.type";
+}
+
+/// getTypeString - Return a string used to label this descriptor's type.
+///
+const char *TypeDesc::getTypeString() const {
+  return "llvm.dbg.type.type";
+}
+
+#ifndef NDEBUG
+void TypeDesc::dump() {
+  std::cerr << getDescString() << " "
+            << "Tag(" << getTag() << "), "
+            << "Context(" << Context << "), "
+            << "Name(\"" << Name << "\"), "
+            << "Size(" << Size << ")\n";
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+
+BasicTypeDesc::BasicTypeDesc()
+: TypeDesc(DI_TAG_basictype)
+, Encoding(0)
+{}
+
+/// ApplyToFields - Target the visitor to the fields of the  BasicTypeDesc.
+///
+void BasicTypeDesc::ApplyToFields(DIVisitor *Visitor) {
+  TypeDesc::ApplyToFields(Visitor);
+  
+  Visitor->Apply(Encoding);
+}
+
+#ifndef NDEBUG
+void BasicTypeDesc::dump() {
+  std::cerr << getDescString() << " "
+            << "Tag(" << getTag() << "), "
+            << "Context(" << getContext() << "), "
+            << "Name(\"" << getName() << "\"), "
+            << "Size(" << getSize() << "), "
+            << "Encoding(" << Encoding << ")\n";
+}
+#endif
+
+//===----------------------------------------------------------------------===//
+
 GlobalDesc::GlobalDesc(unsigned T)
 : AnchoredDesc(T)
 , Context(0)
@@ -561,7 +646,7 @@
 
   Visitor->Apply(Context);
   Visitor->Apply(Name);
-  Visitor->Apply(TyDesc);
+  Visitor->Apply((DebugInfoDesc *&)TyDesc);
   Visitor->Apply(IsStatic);
   Visitor->Apply(IsDefinition);
 }
@@ -606,6 +691,7 @@
             << "Tag(" << getTag() << "), "
             << "Anchor(" << getAnchor() << "), "
             << "Name(\"" << getName() << "\"), "
+            << "Type(\"" << getTypeDesc() << "\"), "
             << "IsStatic(" << (isStatic() ? "true" : "false") << "), "
             << "IsDefinition(" << (isDefinition() ? "true" : "false") << "), "
             << "Global(" << Global << "), "
@@ -649,13 +735,12 @@
             << "Tag(" << getTag() << "), "
             << "Anchor(" << getAnchor() << "), "
             << "Name(\"" << getName() << "\"), "
+            << "Type(\"" << getTypeDesc() << "\"), "
             << "IsStatic(" << (isStatic() ? "true" : "false") << "), "
             << "IsDefinition(" << (isDefinition() ? "true" : "false") << ")\n";
 }
 #endif
 
-//===----------------------------------------------------------------------===//
-
 DebugInfoDesc *DIDeserializer::Deserialize(Value *V) {
   return Deserialize(getGlobalVariable(V));
 }