[llvm-commits] CVS: llvm/lib/CodeGen/DwarfWriter.cpp

Jim Laskey jlaskey at apple.com
Fri Mar 3 13:00:26 PST 2006



Changes in directory llvm/lib/CodeGen:

DwarfWriter.cpp updated: 1.41 -> 1.42
---
Log message:

Added support for dwarf block data entries.


---
Diffs of the changes:  (+248 -49)

 DwarfWriter.cpp |  297 ++++++++++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 248 insertions(+), 49 deletions(-)


Index: llvm/lib/CodeGen/DwarfWriter.cpp
diff -u llvm/lib/CodeGen/DwarfWriter.cpp:1.41 llvm/lib/CodeGen/DwarfWriter.cpp:1.42
--- llvm/lib/CodeGen/DwarfWriter.cpp:1.41	Fri Mar  3 09:06:57 2006
+++ llvm/lib/CodeGen/DwarfWriter.cpp	Fri Mar  3 15:00:14 2006
@@ -174,7 +174,8 @@
     isLabel,
     isAsIsLabel,
     isDelta,
-    isEntry
+    isEntry,
+    isBlock
   };
   
   unsigned Type;                      // Type of the value
@@ -208,6 +209,10 @@
   static bool classof(const DIEInteger *) { return true; }
   static bool classof(const DIEValue *I)  { return I->Type == isInteger; }
   
+  /// BestForm - Choose the best form for integer.
+  ///
+  unsigned BestForm(bool IsSigned);
+
   /// EmitValue - Emit integer of appropriate size.
   ///
   virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const;
@@ -316,16 +321,82 @@
   static bool classof(const DIEntry *)   { return true; }
   static bool classof(const DIEValue *E) { return E->Type == isEntry; }
   
-  /// EmitValue - Emit delta value.
+  /// EmitValue - Emit die entry offset.
   ///
   virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const;
   
-  /// SizeOf - Determine size of delta value in bytes.
+  /// SizeOf - Determine size of die entry in bytes.
   ///
   virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const;
 };
 
 //===----------------------------------------------------------------------===//
+// DIEBlock - A block of values.  Primarily used for location expressions.
+//
+struct DIEBlock : public DIEValue {
+  unsigned Size;                        // Size in bytes excluding size header.
+  std::vector<unsigned> Forms;          // Data forms.
+  std::vector<DIEValue *> Values;       // Block values.
+  
+  DIEBlock()
+  : DIEValue(isBlock)
+  , Size(0)
+  , Forms()
+  , Values()
+  {}
+  ~DIEBlock();
+
+  // Implement isa/cast/dyncast.
+  static bool classof(const DIEBlock *)  { return true; }
+  static bool classof(const DIEValue *E) { return E->Type == isBlock; }
+  
+  /// ComputeSize - calculate the size of the block.
+  ///
+  unsigned ComputeSize(DwarfWriter &DW);
+  
+  /// BestForm - Choose the best form for data.
+  ///
+  unsigned BestForm();
+
+  /// EmitValue - Emit block data.
+  ///
+  virtual void EmitValue(const DwarfWriter &DW, unsigned Form) const;
+  
+  /// SizeOf - Determine size of block data in bytes.
+  ///
+  virtual unsigned SizeOf(const DwarfWriter &DW, unsigned Form) const;
+
+  /// AddUInt - Add an unsigned integer value.
+  ///
+  void AddUInt(unsigned Form, uint64_t Integer);
+
+  /// AddSInt - Add an signed integer value.
+  ///
+  void AddSInt(unsigned Form, int64_t Integer);
+      
+  /// AddString - Add a std::string value.
+  ///
+  void AddString(unsigned Form, const std::string &String);
+      
+  /// AddLabel - Add a Dwarf label value.
+  ///
+  void AddLabel(unsigned Form, const DWLabel &Label);
+      
+  /// AddObjectLabel - Add a non-Dwarf label value.
+  ///
+  void AddObjectLabel(unsigned Form, const std::string &Label);
+      
+  /// AddDelta - Add a label delta value.
+  ///
+  void AddDelta(unsigned Form, const DWLabel &Hi, const DWLabel &Lo);
+      
+  /// AddDIEntry - Add a DIE value.
+  ///
+  void AddDIEntry(unsigned Form, DIE *Entry);
+
+};
+
+//===----------------------------------------------------------------------===//
 // DIE - A structured debug information entry.  Has an abbreviation which
 // describes it's organization.
 class DIE {
@@ -381,10 +452,14 @@
   void AddDelta(unsigned Attribute, unsigned Form,
                 const DWLabel &Hi, const DWLabel &Lo);
       
-  ///  AddDIEntry - Add a DIE attribute data and value.
+  /// AddDIEntry - Add a DIE attribute data and value.
   ///
   void AddDIEntry(unsigned Attribute, unsigned Form, DIE *Entry);
 
+  /// AddBlock - Add block data.
+  ///
+  void AddBlock(unsigned Attribute, unsigned Form, DIEBlock *Block);
+
   /// Complete - Indicate that all attributes have been added and
   /// ready to get an abbreviation ID.
   ///
@@ -496,6 +571,21 @@
 
 //===----------------------------------------------------------------------===//
 
+/// BestForm - Choose the best form for integer.
+///
+unsigned DIEInteger::BestForm(bool IsSigned) {
+  if (IsSigned) {
+    if ((char)Integer == (signed)Integer)   return DW_FORM_data1;
+    if ((short)Integer == (signed)Integer)  return DW_FORM_data2;
+    if ((int)Integer == (signed)Integer)    return DW_FORM_data4;
+  } else {
+    if ((unsigned char)Integer == Integer)  return DW_FORM_data1;
+    if ((unsigned short)Integer == Integer) return DW_FORM_data2;
+    if ((unsigned int)Integer == Integer)   return DW_FORM_data4;
+  }
+  return DW_FORM_data8;
+}
+    
 /// EmitValue - Emit integer of appropriate size.
 ///
 void DIEInteger::EmitValue(const DwarfWriter &DW, unsigned Form) const {
@@ -507,13 +597,6 @@
   case DW_FORM_data8: DW.EmitInt64(Integer);        break;
   case DW_FORM_udata: DW.EmitULEB128Bytes(Integer); break;
   case DW_FORM_sdata: DW.EmitSLEB128Bytes(Integer); break;
-  // FIXME - Punting on field offsets.
-  case DW_FORM_block1: {
-    DW.EmitInt8(1 +  DW.SizeULEB128(Integer)); DW.EOL("Form1 Size");
-    DW.EmitInt8(DW_OP_plus_uconst); DW.EOL("DW_OP_plus_uconst");
-    DW.EmitULEB128Bytes(Integer);
-    break;
-  }
   default: assert(0 && "DIE Value form not supported yet"); break;
   }
 }
@@ -529,8 +612,6 @@
   case DW_FORM_data8: return sizeof(int64_t);
   case DW_FORM_udata: return DW.SizeULEB128(Integer);
   case DW_FORM_sdata: return DW.SizeSLEB128(Integer);
-  // FIXME - Punting on field offsets.
-  case DW_FORM_block1:   return 2 + DW.SizeULEB128(Integer);
   default: assert(0 && "DIE Value form not supported yet"); break;
   }
   return 0;
@@ -569,19 +650,13 @@
 /// EmitValue - Emit label value.
 ///
 void DIEObjectLabel::EmitValue(const DwarfWriter &DW, unsigned Form) const {
-  DW.EmitInt8(sizeof(int8_t) + DW.getAddressSize());
-  DW.EOL("DW_FORM_block1 length");
-  
-  DW.EmitInt8(DW_OP_addr);
-  DW.EOL("DW_OP_addr");
-  
   DW.EmitReference(Label);
 }
 
 /// SizeOf - Determine size of label value in bytes.
 ///
 unsigned DIEObjectLabel::SizeOf(const DwarfWriter &DW, unsigned Form) const {
-  return sizeof(int8_t) + sizeof(int8_t) + DW.getAddressSize();
+  return DW.getAddressSize();
 }
     
 //===----------------------------------------------------------------------===//
@@ -599,13 +674,13 @@
 }
 
 //===----------------------------------------------------------------------===//
-/// EmitValue - Emit extry offset.
+/// EmitValue - Emit die entry offset.
 ///
 void DIEntry::EmitValue(const DwarfWriter &DW, unsigned Form) const {
   DW.EmitInt32(Entry->getOffset());
 }
 
-/// SizeOf - Determine size of label value in bytes.
+/// SizeOf - Determine size of die value in bytes.
 ///
 unsigned DIEntry::SizeOf(const DwarfWriter &DW, unsigned Form) const {
   return sizeof(int32_t);
@@ -613,6 +688,115 @@
     
 //===----------------------------------------------------------------------===//
 
+DIEBlock::~DIEBlock() {
+  for (unsigned i = 0, N = Values.size(); i < N; ++i) {
+    delete Values[i];
+  }
+}
+
+/// ComputeSize - calculate the size of the block.
+///
+unsigned DIEBlock::ComputeSize(DwarfWriter &DW) {
+  Size = 0;
+  for (unsigned i = 0, N = Values.size(); i < N; ++i) {
+    Size += Values[i]->SizeOf(DW, Forms[i]);
+  }
+  return Size;
+}
+
+/// BestForm - Choose the best form for data.
+///
+unsigned DIEBlock::BestForm() {
+  if ((unsigned char)Size == Size)  return DW_FORM_block1;
+  if ((unsigned short)Size == Size) return DW_FORM_block2;
+  if ((unsigned int)Size == Size)   return DW_FORM_block4;
+  return DW_FORM_block;
+}
+
+/// EmitValue - Emit block data.
+///
+void DIEBlock::EmitValue(const DwarfWriter &DW, unsigned Form) const {
+  switch (Form) {
+  case DW_FORM_block1: DW.EmitInt8(Size);         break;
+  case DW_FORM_block2: DW.EmitInt16(Size);        break;
+  case DW_FORM_block4: DW.EmitInt32(Size);        break;
+  case DW_FORM_block:  DW.EmitULEB128Bytes(Size); break;
+  default: assert(0 && "Improper form for block"); break;
+  }
+  for (unsigned i = 0, N = Values.size(); i < N; ++i) {
+    DW.EOL("");
+    Values[i]->EmitValue(DW, Forms[i]);
+  }
+}
+
+/// SizeOf - Determine size of block data in bytes.
+///
+unsigned DIEBlock::SizeOf(const DwarfWriter &DW, unsigned Form) const {
+  switch (Form) {
+  case DW_FORM_block1: return Size + sizeof(int8_t);
+  case DW_FORM_block2: return Size + sizeof(int16_t);
+  case DW_FORM_block4: return Size + sizeof(int32_t);
+  case DW_FORM_block: return Size + DW.SizeULEB128(Size);
+  default: assert(0 && "Improper form for block"); break;
+  }
+  return 0;
+}
+
+/// AddUInt - Add an unsigned integer value.
+///
+void DIEBlock::AddUInt(unsigned Form, uint64_t Integer) {
+  DIEInteger *DI = new DIEInteger(Integer);
+  Values.push_back(DI);
+  if (Form == 0) Form = DI->BestForm(false);
+  Forms.push_back(Form);
+}
+
+/// AddSInt - Add an signed integer value.
+///
+void DIEBlock::AddSInt(unsigned Form, int64_t Integer) {
+  DIEInteger *DI = new DIEInteger(Integer);
+  Values.push_back(DI);
+  if (Form == 0) Form = DI->BestForm(true);
+  Forms.push_back(Form);
+}
+    
+/// AddString - Add a std::string value.
+///
+void DIEBlock::AddString(unsigned Form, const std::string &String) {
+  Values.push_back(new DIEString(String));
+  Forms.push_back(Form);
+}
+    
+/// AddLabel - Add a Dwarf label value.
+///
+void DIEBlock::AddLabel(unsigned Form, const DWLabel &Label) {
+  Values.push_back(new DIEDwarfLabel(Label));
+  Forms.push_back(Form);
+}
+    
+/// AddObjectLabel - Add a non-Dwarf label value.
+///
+void DIEBlock::AddObjectLabel(unsigned Form, const std::string &Label) {
+  Values.push_back(new DIEObjectLabel(Label));
+  Forms.push_back(Form);
+}
+    
+/// AddDelta - Add a label delta value.
+///
+void DIEBlock::AddDelta(unsigned Form, const DWLabel &Hi, const DWLabel &Lo) {
+  Values.push_back(new DIEDelta(Hi, Lo));
+  Forms.push_back(Form);
+}
+    
+/// AddDIEntry - Add a DIE value.
+///
+void DIEBlock::AddDIEntry(unsigned Form, DIE *Entry) {
+  Values.push_back(new DIEntry(Entry));
+  Forms.push_back(Form);
+}
+
+//===----------------------------------------------------------------------===//
+
 DIE::DIE(unsigned Tag)
 : Abbrev(new DIEAbbrev(Tag, DW_CHILDREN_no))
 , AbbrevID(0)
@@ -637,67 +821,67 @@
 /// AddUInt - Add an unsigned integer attribute data and value.
 ///
 void DIE::AddUInt(unsigned Attribute, unsigned Form, uint64_t Integer) {
-  if (Form == 0) {
-      if ((unsigned char)Integer == Integer)       Form = DW_FORM_data1;
-      else if ((unsigned short)Integer == Integer) Form = DW_FORM_data2;
-      else if ((unsigned int)Integer == Integer)   Form = DW_FORM_data4;
-      else                                         Form = DW_FORM_data8;
-  }
+  DIEInteger *DI = new DIEInteger(Integer);
+  Values.push_back(DI);
+  if (!Form) Form = DI->BestForm(false);
   Abbrev->AddAttribute(Attribute, Form);
-  Values.push_back(new DIEInteger(Integer));
 }
     
 /// AddSInt - Add an signed integer attribute data and value.
 ///
 void DIE::AddSInt(unsigned Attribute, unsigned Form, int64_t Integer) {
-  if (Form == 0) {
-      if ((char)Integer == Integer)       Form = DW_FORM_data1;
-      else if ((short)Integer == Integer) Form = DW_FORM_data2;
-      else if ((int)Integer == Integer)   Form = DW_FORM_data4;
-      else                                Form = DW_FORM_data8;
-  }
+  DIEInteger *DI = new DIEInteger(Integer);
+  Values.push_back(DI);
+  if (!Form) Form = DI->BestForm(true);
   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));
+  Abbrev->AddAttribute(Attribute, Form);
 }
     
 /// 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 DIEDwarfLabel(Label));
+  Abbrev->AddAttribute(Attribute, Form);
 }
     
 /// AddObjectLabel - Add an non-Dwarf label attribute data and value.
 ///
 void DIE::AddObjectLabel(unsigned Attribute, unsigned Form,
                          const std::string &Label) {
-  Abbrev->AddAttribute(Attribute, Form);
   Values.push_back(new DIEObjectLabel(Label));
+  Abbrev->AddAttribute(Attribute, Form);
 }
     
 /// 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));
+  Abbrev->AddAttribute(Attribute, Form);
 }
     
 /// AddDIEntry - Add a DIE attribute data and value.
 ///
-void DIE::AddDIEntry(unsigned Attribute,
-                     unsigned Form, DIE *Entry) {
-  Abbrev->AddAttribute(Attribute, Form);
+void DIE::AddDIEntry(unsigned Attribute, unsigned Form, DIE *Entry) {
   Values.push_back(new DIEntry(Entry));
+  Abbrev->AddAttribute(Attribute, Form);
+}
+
+/// AddBlock - Add block data.
+///
+void DIE::AddBlock(unsigned Attribute, unsigned Form, DIEBlock *Block) {
+  assert(Block->Size && "Block size has not been computed");
+  Values.push_back(Block);
+  if (!Form) Form = Block->BestForm();
+  Abbrev->AddAttribute(Attribute, Form);
 }
 
 /// Complete - Indicate that all attributes have been added and ready to get an
@@ -731,7 +915,7 @@
 /// EOL - Print a newline character to asm stream.  If a comment is present
 /// then it will be printed first.  Comments should not contain '\n'.
 void DwarfWriter::EOL(const std::string &Comment) const {
-  if (DwarfVerbose) {
+  if (DwarfVerbose && !Comment.empty()) {
     O << "\t"
       << Asm->CommentString
       << " "
@@ -1134,13 +1318,18 @@
       // Add elements to structure type.
       for(unsigned i = 0, N = Elements.size(); i < N; ++i) {
         DerivedTypeDesc *MemberDesc = cast<DerivedTypeDesc>(Elements[i]);
+        
+        // Extract the basic information.
         const std::string &Name = MemberDesc->getName();
         unsigned Line = MemberDesc->getLine();
         TypeDesc *MemTy = MemberDesc->getFromType();
         uint64_t Size = MemberDesc->getSize();
         uint64_t Offset = MemberDesc->getOffset();
    
+        // Construct member die.
         DIE *Member = new DIE(DW_TAG_member);
+        
+        // Add details.
         if (!Name.empty()) Member->AddString(DW_AT_name, DW_FORM_string, Name);
         if (CompileUnitDesc *File = MemberDesc->getFile()) {
           CompileUnit *FileUnit = FindCompileUnit(File);
@@ -1149,13 +1338,19 @@
           Member->AddUInt(DW_AT_decl_file, 0, FileID);
           Member->AddUInt(DW_AT_decl_line, 0, Line);
         }
+        
         if (TypeDesc *FromTy = MemberDesc->getFromType()) {
            Member->AddDIEntry(DW_AT_type, DW_FORM_ref4,
                               NewType(Context, FromTy));
         }
-        // FIXME - Punt on the Address.
-        Member->AddUInt(DW_AT_data_member_location, DW_FORM_block1,
-                                                    Offset >> 3);
+        
+        // Add computation for offset.
+        DIEBlock *Block = new DIEBlock();
+        Block->AddUInt(DW_FORM_data1, DW_OP_plus_uconst);
+        Block->AddUInt(DW_FORM_udata, Offset >> 3);
+        Block->ComputeSize(*this);
+        Member->AddBlock(DW_AT_data_member_location, 0, Block);
+        
         Ty->AddChild(Member);
       }
       break;
@@ -1263,8 +1458,12 @@
   VariableDie->AddUInt       (DW_AT_decl_line, 0,              Line);
   VariableDie->AddDIEntry    (DW_AT_type,      DW_FORM_ref4,   Type);
   VariableDie->AddUInt       (DW_AT_external,  DW_FORM_flag,   1);
-  // FIXME - needs to be a proper expression.
-  VariableDie->AddObjectLabel(DW_AT_location,  DW_FORM_block1, MangledName);
+
+  DIEBlock *Block = new DIEBlock();
+  Block->AddUInt(DW_FORM_data1, DW_OP_addr);
+  Block->AddObjectLabel(DW_FORM_udata, MangledName);
+  Block->ComputeSize(*this);
+  VariableDie->AddBlock(DW_AT_location,  0, Block);
   
   // Add to map.
   Slot = VariableDie;






More information about the llvm-commits mailing list