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));
}