diff --git a/include/llvm/CodeGen/MachineDebugInfo.h b/include/llvm/CodeGen/MachineDebugInfo.h index b27c0ab300e..b51ea646898 100644 --- a/include/llvm/CodeGen/MachineDebugInfo.h +++ b/include/llvm/CodeGen/MachineDebugInfo.h @@ -64,7 +64,9 @@ enum { DI_TAG_global_variable, DI_TAG_subprogram, DI_TAG_basictype, - DI_TAG_typedef + DI_TAG_typedef, + DI_TAG_pointer, + DI_TAG_reference }; //===----------------------------------------------------------------------===// @@ -283,8 +285,10 @@ public: class TypeDesc : public DebugInfoDesc { private: DebugInfoDesc *Context; // Context debug descriptor. - std::string Name; // Type name. - uint64_t Size; // Type size. + std::string Name; // Type name (may be empty.) + CompileUnitDesc *File; // Declared compile unit (may be NULL.) + int Line; // Declared line# (may be zero.) + uint64_t Size; // Type size (may be zero.) protected: TypeDesc(unsigned T); @@ -293,9 +297,13 @@ public: // Accessors DebugInfoDesc *getContext() const { return Context; } const std::string &getName() const { return Name; } + CompileUnitDesc *getFile() const { return File; } + int getLine() const { return Line; } uint64_t getSize() const { return Size; } void setContext(DebugInfoDesc *C) { Context = C; } void setName(const std::string &N) { Name = N; } + void setFile(CompileUnitDesc *U) { File = U; } + void setLine(int L) { Line = L; } void setSize(uint64_t S) { Size = S; } /// ApplyToFields - Target the visitor to the fields of the TypeDesc. @@ -346,32 +354,27 @@ public: //===----------------------------------------------------------------------===// -/// TypedefDesc - This class packages debug information associated with a -/// derived typedef. -class TypedefDesc : public TypeDesc { +/// DerivedTypeDesc - This class packages debug information associated with a +/// derived types (eg., typedef, pointer, reference.) +class DerivedTypeDesc : public TypeDesc { private: TypeDesc *FromType; // Type derived from. - CompileUnitDesc *File; // Declared compile unit. - int Line; // Declared line#. public: - TypedefDesc(); + DerivedTypeDesc(unsigned T); // Accessors TypeDesc *getFromType() const { return FromType; } - CompileUnitDesc *getFile() const { return File; } - int getLine() const { return Line; } void setFromType(TypeDesc *F) { FromType = F; } - void setFile(CompileUnitDesc *U) { File = U; } - void setLine(int L) { Line = L; } // Implement isa/cast/dyncast. - static bool classof(const TypedefDesc *) { return true; } + static bool classof(const DerivedTypeDesc *) { return true; } static bool classof(const DebugInfoDesc *D) { - return D->getTag() == DI_TAG_typedef; + unsigned T = D->getTag(); + return T == DI_TAG_typedef || T == DI_TAG_pointer || T == DI_TAG_reference; } - /// ApplyToFields - Target the visitor to the fields of the TypedefDesc. + /// ApplyToFields - Target the visitor to the fields of the DerivedTypeDesc. /// virtual void ApplyToFields(DIVisitor *Visitor); diff --git a/lib/CodeGen/DwarfWriter.cpp b/lib/CodeGen/DwarfWriter.cpp index 9512f54873e..c714cad5ce0 100644 --- a/lib/CodeGen/DwarfWriter.cpp +++ b/lib/CodeGen/DwarfWriter.cpp @@ -1235,6 +1235,9 @@ void DwarfWriter::NewGlobalEntity(const std::string &Name, DIE *Entity) { /// NewType - Create a new type DIE. /// DIE *DwarfWriter::NewType(DIE *Unit, TypeDesc *TyDesc) { + // FIXME - hack to get around NULL types short term. + if (!TyDesc) return NewBasicType(Unit, Type::IntTy); + // Check for pre-existence. DIE *&Slot = DescToDieMap[TyDesc]; if (Slot) return Slot; @@ -1246,29 +1249,43 @@ DIE *DwarfWriter::NewType(DIE *Unit, TypeDesc *TyDesc) { DIE *Ty = NULL; - // Determine how to handle. if (BasicTypeDesc *BasicTy = dyn_cast(TyDesc)) { + // Fundamental types like int, float, bool Slot = Ty = new DIE(DW_TAG_base_type); unsigned Encoding = BasicTy->getEncoding(); Ty->AddUInt (DW_AT_encoding, DW_FORM_data1, Encoding); - } else if (TypedefDesc *TypedefTy = dyn_cast(TyDesc)) { - Slot = Ty = new DIE(DW_TAG_typedef); - TypeDesc *FromTy = TypedefTy->getFromType(); - DIE *FromTyDie = NewType(Unit, FromTy); - CompileUnitDesc *File = TypedefTy->getFile(); - unsigned FileID = DebugInfo->RecordSource(File); - int Line = TypedefTy->getLine(); + } else if (DerivedTypeDesc *DerivedTy = dyn_cast(TyDesc)) { + // Determine which derived type. + unsigned T = 0; + switch (DerivedTy->getTag()) { + case DI_TAG_typedef: T = DW_TAG_typedef; break; + case DI_TAG_pointer: T = DW_TAG_pointer_type; break; + case DI_TAG_reference: T = DW_TAG_reference_type; break; + default: assert( 0 && "Unknown tag on derived type"); + } - Ty->AddDIEntry(DW_AT_type, DW_FORM_ref4, FromTyDie); - Ty->AddUInt (DW_AT_decl_file, 0, FileID); - Ty->AddUInt (DW_AT_decl_line, 0, Line); + // Create specific DIE. + Slot = Ty = new DIE(T); + + // Map to main type, void will not have a type. + if (TypeDesc *FromTy = DerivedTy->getFromType()) { + Ty->AddDIEntry(DW_AT_type, DW_FORM_ref4, NewType(Unit, FromTy)); + } } assert(Ty && "Type not supported yet"); - // Add common information. + // Add size if non-zero (derived types don't have a size.) if (Size) Ty->AddUInt(DW_AT_byte_size, 0, Size); + // Add name if not anonymous or intermediate type. if (!Name.empty()) Ty->AddString(DW_AT_name, DW_FORM_string, Name); + // Add source line info if present. + if (CompileUnitDesc *File = TyDesc->getFile()) { + unsigned FileID = DebugInfo->RecordSource(File); + int Line = TyDesc->getLine(); + Ty->AddUInt(DW_AT_decl_file, 0, FileID); + Ty->AddUInt(DW_AT_decl_line, 0, Line); + } // Add to context owner. Unit->AddChild(Ty); diff --git a/lib/CodeGen/MachineDebugInfo.cpp b/lib/CodeGen/MachineDebugInfo.cpp index 1652881268f..72da0a04060 100644 --- a/lib/CodeGen/MachineDebugInfo.cpp +++ b/lib/CodeGen/MachineDebugInfo.cpp @@ -430,7 +430,9 @@ DebugInfoDesc *DebugInfoDesc::DescFactory(unsigned Tag) { case DI_TAG_global_variable: return new GlobalVariableDesc(); case DI_TAG_subprogram: return new SubprogramDesc(); case DI_TAG_basictype: return new BasicTypeDesc(); - case DI_TAG_typedef: return new TypedefDesc(); + case DI_TAG_typedef: return new DerivedTypeDesc(DI_TAG_typedef); + case DI_TAG_pointer: return new DerivedTypeDesc(DI_TAG_pointer); + case DI_TAG_reference: return new DerivedTypeDesc(DI_TAG_reference); default: break; } return NULL; @@ -566,16 +568,19 @@ TypeDesc::TypeDesc(unsigned T) : DebugInfoDesc(T) , Context(NULL) , Name("") +, File(NULL) , Size(0) {} -/// ApplyToFields - Target the visitor to the fields of the TypeDesc. +/// 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((DebugInfoDesc *&)File); + Visitor->Apply(Line); Visitor->Apply(Size); } @@ -597,6 +602,8 @@ void TypeDesc::dump() { << "Tag(" << getTag() << "), " << "Context(" << Context << "), " << "Name(\"" << Name << "\"), " + << "File(" << File << "), " + << "Line(" << Line << "), " << "Size(" << Size << ")\n"; } #endif @@ -608,7 +615,7 @@ BasicTypeDesc::BasicTypeDesc() , Encoding(0) {} -/// ApplyToFields - Target the visitor to the fields of the BasicTypeDesc. +/// ApplyToFields - Target the visitor to the fields of the BasicTypeDesc. /// void BasicTypeDesc::ApplyToFields(DIVisitor *Visitor) { TypeDesc::ApplyToFields(Visitor); @@ -628,33 +635,32 @@ void BasicTypeDesc::dump() { #endif //===----------------------------------------------------------------------===// -TypedefDesc::TypedefDesc() -: TypeDesc(DI_TAG_typedef) +DerivedTypeDesc::DerivedTypeDesc(unsigned T) +: TypeDesc(T) , FromType(NULL) -, File(NULL) -, Line(0) -{} +{ + assert((T == DI_TAG_typedef || T == DI_TAG_pointer || T == DI_TAG_reference)&& + "Unknown derived type."); +} -/// ApplyToFields - Target the visitor to the fields of the TypedefDesc. +/// ApplyToFields - Target the visitor to the fields of the DerivedTypeDesc. /// -void TypedefDesc::ApplyToFields(DIVisitor *Visitor) { +void DerivedTypeDesc::ApplyToFields(DIVisitor *Visitor) { TypeDesc::ApplyToFields(Visitor); Visitor->Apply((DebugInfoDesc *&)FromType); - Visitor->Apply((DebugInfoDesc *&)File); - Visitor->Apply(Line); } #ifndef NDEBUG -void TypedefDesc::dump() { +void DerivedTypeDesc::dump() { std::cerr << getDescString() << " " << "Tag(" << getTag() << "), " << "Context(" << getContext() << "), " << "Name(\"" << getName() << "\"), " << "Size(" << getSize() << "), " - << "FromType(" << FromType << "), " - << "File(" << File << "), " - << "Line(" << Line << ")\n"; + << "File(" << getFile() << "), " + << "Line(" << getLine() << "), " + << "FromType(" << FromType << ")\n"; } #endif