From 760383e298f5b4633b4454ad4184b379d56f17e2 Mon Sep 17 00:00:00 2001 From: Jim Laskey <jlaskey@mac.com> Date: Mon, 21 Aug 2006 21:20:18 +0000 Subject: [PATCH] Adding C++ member support. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29799 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/DwarfWriter.cpp | 210 ++++++++++++++++++++++--------- lib/CodeGen/MachineDebugInfo.cpp | 4 +- 2 files changed, 152 insertions(+), 62 deletions(-) diff --git a/lib/CodeGen/DwarfWriter.cpp b/lib/CodeGen/DwarfWriter.cpp index ff62b4624c5..e4f4001df93 100644 --- a/lib/CodeGen/DwarfWriter.cpp +++ b/lib/CodeGen/DwarfWriter.cpp @@ -1236,7 +1236,7 @@ void DwarfWriter::AddAddress(DIE *Die, unsigned Attribute, DIE *&DwarfWriter::getDieMapSlotFor(DebugInfoDesc *DD) { return DescToDieMap[DD]; } - + /// NewType - Create a new type DIE. /// DIE *DwarfWriter::NewType(DIE *Context, TypeDesc *TyDesc, CompileUnit *Unit) { @@ -1249,8 +1249,6 @@ DIE *DwarfWriter::NewType(DIE *Context, TypeDesc *TyDesc, CompileUnit *Unit) { return Die; } - // FIXME - Should handle other contexts that compile units. - // Check for pre-existence. DIE *&Slot = Unit->getDieMapSlotFor(TyDesc); if (Slot) return Slot; @@ -1326,71 +1324,161 @@ DIE *DwarfWriter::NewType(DIE *Context, TypeDesc *TyDesc, CompileUnit *Unit) { } case DW_TAG_structure_type: case DW_TAG_union_type: { - // FIXME - this is just the basics. // Add elements to structure type. for(unsigned i = 0, N = Elements.size(); i < N; ++i) { - DerivedTypeDesc *MemberDesc = cast<DerivedTypeDesc>(Elements[i]); + DebugInfoDesc *Element = Elements[i]; - // Extract the basic information. - const std::string &Name = MemberDesc->getName(); - TypeDesc *MemTy = MemberDesc->getFromType(); - uint64_t Size = MemberDesc->getSize(); - uint64_t Align = MemberDesc->getAlign(); - uint64_t Offset = MemberDesc->getOffset(); - - // Construct member debug information entry. - DIE *Member = new DIE(DW_TAG_member); - - // Add name if not "". - if (!Name.empty()) Member->AddString(DW_AT_name, DW_FORM_string, Name); - // Add location if available. - AddSourceLine(Member, MemberDesc->getFile(), MemberDesc->getLine()); - - // Most of the time the field info is the same as the members. - uint64_t FieldSize = Size; - uint64_t FieldAlign = Align; - uint64_t FieldOffset = Offset; - - if (TypeDesc *FromTy = MemberDesc->getFromType()) { - Member->AddDIEntry(DW_AT_type, DW_FORM_ref4, - NewType(Context, FromTy, Unit)); - FieldSize = FromTy->getSize(); - FieldAlign = FromTy->getSize(); - } - - // Unless we have a bit field. - if (FieldSize != Size) { - // Construct the alignment mask. - uint64_t AlignMask = ~(FieldAlign - 1); - // Determine the high bit + 1 of the declared size. - uint64_t HiMark = (Offset + FieldSize) & AlignMask; - // Work backwards to determine the base offset of the field. - FieldOffset = HiMark - FieldSize; - // Now normalize offset to the field. - Offset -= FieldOffset; + if (DerivedTypeDesc *MemberDesc = dyn_cast<DerivedTypeDesc>(Element)) { + // Add field or base class. - // Maybe we need to work from the other end. - if (TD->isLittleEndian()) Offset = FieldSize - (Offset + Size); - - Member->AddUInt(DW_AT_byte_size, 0, FieldSize >> 3); - Member->AddUInt(DW_AT_bit_size, 0, Size); - Member->AddUInt(DW_AT_bit_offset, 0, Offset); - } + unsigned Tag = MemberDesc->getTag(); - // Add computation for offset. - DIEBlock *Block = new DIEBlock(); - Block->AddUInt(DW_FORM_data1, DW_OP_plus_uconst); - Block->AddUInt(DW_FORM_udata, FieldOffset >> 3); - Block->ComputeSize(*this); - Member->AddBlock(DW_AT_data_member_location, 0, Block); + // Extract the basic information. + const std::string &Name = MemberDesc->getName(); + TypeDesc *MemTy = MemberDesc->getFromType(); + uint64_t Size = MemberDesc->getSize(); + uint64_t Align = MemberDesc->getAlign(); + uint64_t Offset = MemberDesc->getOffset(); + + // Construct member debug information entry. + DIE *Member = new DIE(Tag); + + // Add name if not "". + if (!Name.empty())Member->AddString(DW_AT_name, DW_FORM_string, Name); + // Add location if available. + AddSourceLine(Member, MemberDesc->getFile(), MemberDesc->getLine()); + + // Most of the time the field info is the same as the members. + uint64_t FieldSize = Size; + uint64_t FieldAlign = Align; + uint64_t FieldOffset = Offset; + + if (TypeDesc *FromTy = MemberDesc->getFromType()) { + Member->AddDIEntry(DW_AT_type, DW_FORM_ref4, + NewType(Context, FromTy, Unit)); + FieldSize = FromTy->getSize(); + FieldAlign = FromTy->getSize(); + } + + // Unless we have a bit field. + if (Tag == DW_TAG_member && FieldSize != Size) { + // Construct the alignment mask. + uint64_t AlignMask = ~(FieldAlign - 1); + // Determine the high bit + 1 of the declared size. + uint64_t HiMark = (Offset + FieldSize) & AlignMask; + // Work backwards to determine the base offset of the field. + FieldOffset = HiMark - FieldSize; + // Now normalize offset to the field. + Offset -= FieldOffset; + + // Maybe we need to work from the other end. + if (TD->isLittleEndian()) Offset = FieldSize - (Offset + Size); + + // Add size and offset. + Member->AddUInt(DW_AT_byte_size, 0, FieldSize >> 3); + Member->AddUInt(DW_AT_bit_size, 0, Size); + Member->AddUInt(DW_AT_bit_offset, 0, Offset); + } + + // Add computation for offset. + DIEBlock *Block = new DIEBlock(); + Block->AddUInt(DW_FORM_data1, DW_OP_plus_uconst); + Block->AddUInt(DW_FORM_udata, FieldOffset >> 3); + Block->ComputeSize(*this); + Member->AddBlock(DW_AT_data_member_location, 0, Block); - if (MemberDesc->isProtected()) { - Member->AddUInt(DW_AT_accessibility, 0, DW_ACCESS_protected); - } else if (MemberDesc->isPrivate()) { - Member->AddUInt(DW_AT_accessibility, 0, DW_ACCESS_private); + // Add accessibility (public default unless is base class. + if (MemberDesc->isProtected()) { + Member->AddUInt(DW_AT_accessibility, 0, DW_ACCESS_protected); + } else if (MemberDesc->isPrivate()) { + Member->AddUInt(DW_AT_accessibility, 0, DW_ACCESS_private); + } else if (Tag == DW_TAG_inheritance) { + Member->AddUInt(DW_AT_accessibility, 0, DW_ACCESS_public); + } + + Ty->AddChild(Member); + } else if (GlobalVariableDesc *StaticDesc = + dyn_cast<GlobalVariableDesc>(Element)) { + // Add static member. + + // Construct member debug information entry. + DIE *Static = new DIE(DW_TAG_variable); + + // Add name and mangled name. + const std::string &Name = StaticDesc->getDisplayName(); + const std::string &MangledName = StaticDesc->getName(); + Static->AddString(DW_AT_name, DW_FORM_string, Name); + Static->AddString(DW_AT_MIPS_linkage_name, DW_FORM_string, + MangledName); + + // Add location. + AddSourceLine(Static, StaticDesc->getFile(), StaticDesc->getLine()); + + // Add type. + if (TypeDesc *StaticTy = StaticDesc->getType()) { + Static->AddDIEntry(DW_AT_type, DW_FORM_ref4, + NewType(Context, StaticTy, Unit)); + } + + // Add flags. + Static->AddUInt(DW_AT_external, DW_FORM_flag, 1); + Static->AddUInt(DW_AT_declaration, DW_FORM_flag, 1); + + Ty->AddChild(Static); + } else if (SubprogramDesc *MethodDesc = + dyn_cast<SubprogramDesc>(Element)) { + // Add member function. + + // Construct member debug information entry. + DIE *Method = new DIE(DW_TAG_subprogram); + + // Add name and mangled name. + const std::string &Name = MethodDesc->getDisplayName(); + const std::string &MangledName = MethodDesc->getName(); + bool IsCTor = false; + + if (Name.empty()) { + Method->AddString(DW_AT_name, DW_FORM_string, MangledName); + IsCTor = TyDesc->getName() == MangledName; + } else { + Method->AddString(DW_AT_name, DW_FORM_string, Name); + Method->AddString(DW_AT_MIPS_linkage_name, DW_FORM_string, + MangledName); + } + + // Add location. + AddSourceLine(Method, MethodDesc->getFile(), MethodDesc->getLine()); + + // Add type. + if (CompositeTypeDesc *MethodTy = + dyn_cast_or_null<CompositeTypeDesc>(MethodDesc->getType())) { + // Get argument information. + std::vector<DebugInfoDesc *> &Args = MethodTy->getElements(); + + // If not a ctor. + if (!IsCTor) { + // Add return type. + Method->AddDIEntry(DW_AT_type, DW_FORM_ref4, + NewType(Context, dyn_cast<TypeDesc>(Args[0]), + Unit)); + } + + // Add arguments. + for(unsigned i = 1, N = Args.size(); i < N; ++i) { + DIE *Arg = new DIE(DW_TAG_formal_parameter); + Arg->AddDIEntry(DW_AT_type, DW_FORM_ref4, + NewType(Context, cast<TypeDesc>(Args[i]), Unit)); + Arg->AddUInt(DW_AT_artificial, DW_FORM_flag, 1); + Method->AddChild(Arg); + } + } + + // Add flags. + Method->AddUInt(DW_AT_external, DW_FORM_flag, 1); + Method->AddUInt(DW_AT_declaration, DW_FORM_flag, 1); + + Ty->AddChild(Method); } - - Ty->AddChild(Member); } break; } diff --git a/lib/CodeGen/MachineDebugInfo.cpp b/lib/CodeGen/MachineDebugInfo.cpp index fa2f57f0e0c..cab58218ba7 100644 --- a/lib/CodeGen/MachineDebugInfo.cpp +++ b/lib/CodeGen/MachineDebugInfo.cpp @@ -497,7 +497,8 @@ DebugInfoDesc *DebugInfoDesc::DescFactory(unsigned Tag) { case DW_TAG_const_type: case DW_TAG_volatile_type: case DW_TAG_restrict_type: - case DW_TAG_member: return new DerivedTypeDesc(Tag); + case DW_TAG_member: + case DW_TAG_inheritance: return new DerivedTypeDesc(Tag); case DW_TAG_array_type: case DW_TAG_structure_type: case DW_TAG_union_type: @@ -788,6 +789,7 @@ bool DerivedTypeDesc::classof(const DebugInfoDesc *D) { case DW_TAG_volatile_type: case DW_TAG_restrict_type: case DW_TAG_member: + case DW_TAG_inheritance: return true; default: break; }