[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