diff --git a/include/llvm/CodeGen/DwarfWriter.h b/include/llvm/CodeGen/DwarfWriter.h index 5fbc8d9ceef..b9953004df3 100644 --- a/include/llvm/CodeGen/DwarfWriter.h +++ b/include/llvm/CodeGen/DwarfWriter.h @@ -43,6 +43,7 @@ namespace llvm { class Module; class SubprogramDesc; class Type; + class TypeDesc; //===--------------------------------------------------------------------===// // DWLabel - Labels are used to track locations in the assembler file. @@ -626,6 +627,14 @@ public: 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 @@ private: /// 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 60eebd9d624..c51b3ea84d7 100644 --- a/include/llvm/CodeGen/MachineDebugInfo.h +++ b/include/llvm/CodeGen/MachineDebugInfo.h @@ -61,7 +61,8 @@ enum { 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 @@ public: /// 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; @@ -273,6 +275,73 @@ public: #endif }; +//===----------------------------------------------------------------------===// +/// 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. @@ -280,8 +349,7 @@ 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 @@ public: // 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 2a07110c6b0..2ead4ce5afa 100644 --- a/lib/CodeGen/DwarfWriter.cpp +++ b/lib/CodeGen/DwarfWriter.cpp @@ -1232,7 +1232,40 @@ void DwarfWriter::NewGlobalEntity(const std::string &Name, DIE *Entity) { 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(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 @@ DIE *DwarfWriter::NewGlobalVariable(GlobalVariableDesc *GVD) { 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 b801cad3793..44b71fae539 100644 --- a/lib/CodeGen/MachineDebugInfo.cpp +++ b/lib/CodeGen/MachineDebugInfo.cpp @@ -197,6 +197,7 @@ public: /// 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 @@ public: Constant *C = CI->getOperand(I++); Field = cast(C)->getValue(); } + virtual void Apply(uint64_t &Field) { + Constant *C = CI->getOperand(I++); + Field = cast(C)->getValue(); + } virtual void Apply(bool &Field) { Constant *C = CI->getOperand(I++); Field = cast(C)->getValue(); @@ -271,6 +276,9 @@ public: 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 @@ public: 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 @@ public: Constant *C = CI->getOperand(I++); IsValid = IsValid && isa(C); } + virtual void Apply(uint64_t &Field) { + Constant *C = CI->getOperand(I++); + IsValid = IsValid && isa(C); + } virtual void Apply(bool &Field) { Constant *C = CI->getOperand(I++); IsValid = IsValid && isa(C); @@ -414,6 +429,7 @@ DebugInfoDesc *DebugInfoDesc::DescFactory(unsigned Tag) { 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 @@ void CompileUnitDesc::dump() { //===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// + +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 @@ void GlobalDesc::ApplyToFields(DIVisitor *Visitor) { Visitor->Apply(Context); Visitor->Apply(Name); - Visitor->Apply(TyDesc); + Visitor->Apply((DebugInfoDesc *&)TyDesc); Visitor->Apply(IsStatic); Visitor->Apply(IsDefinition); } @@ -606,6 +691,7 @@ void GlobalVariableDesc::dump() { << "Tag(" << getTag() << "), " << "Anchor(" << getAnchor() << "), " << "Name(\"" << getName() << "\"), " + << "Type(\"" << getTypeDesc() << "\"), " << "IsStatic(" << (isStatic() ? "true" : "false") << "), " << "IsDefinition(" << (isDefinition() ? "true" : "false") << "), " << "Global(" << Global << "), " @@ -649,13 +735,12 @@ void SubprogramDesc::dump() { << "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)); }