diff options
author | Reid Kleckner <rnk@google.com> | 2016-06-24 16:24:24 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2016-06-24 16:24:24 +0000 |
commit | 9f7f3e1e64067c6802882e691a7a3c8a5926a737 (patch) | |
tree | 4c3d67d10f7f213f79aa0fcd42dd39abd67b868e /llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | |
parent | e794678404abc41ce3b22625da39c1379c1d7a1d (diff) | |
download | llvm-9f7f3e1e64067c6802882e691a7a3c8a5926a737.zip llvm-9f7f3e1e64067c6802882e691a7a3c8a5926a737.tar.gz llvm-9f7f3e1e64067c6802882e691a7a3c8a5926a737.tar.bz2 |
[codeview] Emit base class information from DW_TAG_inheritance nodes
There are two remaining issues here:
1. No vbptr information
2. Need to mention indirect virtual bases
Getting indirect virtual bases is just a matter of adding an "indirect"
flag, emitting them in the frontend, and ignoring them when appropriate
for DWARF.
All virtual bases use the same artificial vbptr field, so I think the
vbptr offset will be best represented by an implicit __vbptr$ClassName
member similar to our existing __vptr$ member.
llvm-svn: 273688
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 48 |
1 files changed, 45 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index ed06c5a..ca2482a 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -1319,6 +1319,9 @@ struct llvm::ClassInfo { // MethodName -> MethodsList typedef MapVector<MDString *, MethodsList> MethodsMap; + /// Base classes. + std::vector<const DIDerivedType *> Inheritance; + /// Direct members. MemberList Members; // Direct overloaded methods gathered by name. @@ -1366,10 +1369,10 @@ ClassInfo CodeViewDebug::collectClassInfo(const DICompositeType *Ty) { if (auto *SP = dyn_cast<DISubprogram>(Element)) { Info.Methods[SP->getRawName()].push_back(SP); } else if (auto *DDTy = dyn_cast<DIDerivedType>(Element)) { - if (DDTy->getTag() == dwarf::DW_TAG_member) + if (DDTy->getTag() == dwarf::DW_TAG_member) { collectMemberInfo(Info, DDTy); - else if (DDTy->getTag() == dwarf::DW_TAG_inheritance) { - // FIXME: collect class info from inheritance. + } else if (DDTy->getTag() == dwarf::DW_TAG_inheritance) { + Info.Inheritance.push_back(DDTy); } else if (DDTy->getTag() == dwarf::DW_TAG_friend) { // Ignore friend members. It appears that MSVC emitted info about // friends in the past, but modern versions do not. @@ -1474,6 +1477,27 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) { ClassInfo Info = collectClassInfo(Ty); FieldListRecordBuilder Fields; + // Create base classes. + for (const DIDerivedType *I : Info.Inheritance) { + if (I->getFlags() & DINode::FlagVirtual) { + // Virtual base. + // FIXME: Emit VBPtrOffset when the frontend provides it. + unsigned VBPtrOffset = 0; + // FIXME: Despite the accessor name, the offset is really in bytes. + unsigned VBTableIndex = I->getOffsetInBits() / 4; + Fields.writeVirtualBaseClass(VirtualBaseClassRecord( + translateAccessFlags(Ty->getTag(), I->getFlags()), + getTypeIndex(I->getBaseType()), getVBPTypeIndex(), VBPtrOffset, + VBTableIndex)); + } else { + assert(I->getOffsetInBits() % 8 == 0 && + "bases must be on byte boundaries"); + Fields.writeBaseClass(BaseClassRecord( + translateAccessFlags(Ty->getTag(), I->getFlags()), + getTypeIndex(I->getBaseType()), I->getOffsetInBits() / 8)); + } + } + // Create members. for (ClassInfo::MemberInfo &MemberInfo : Info.Members) { const DIDerivedType *Member = MemberInfo.MemberTypeNode; @@ -1532,6 +1556,24 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) { return std::make_tuple(FieldTI, TypeIndex(), MemberCount); } +TypeIndex CodeViewDebug::getVBPTypeIndex() { + if (!VBPType.getIndex()) { + // Make a 'const int *' type. + ModifierRecord MR(TypeIndex::Int32(), ModifierOptions::Const); + TypeIndex ModifiedTI = TypeTable.writeModifier(MR); + + PointerKind PK = getPointerSizeInBytes() == 8 ? PointerKind::Near64 + : PointerKind::Near32; + PointerMode PM = PointerMode::Pointer; + PointerOptions PO = PointerOptions::None; + PointerRecord PR(ModifiedTI, PK, PM, PO, getPointerSizeInBytes()); + + VBPType = TypeTable.writePointer(PR); + } + + return VBPType; +} + struct CodeViewDebug::TypeLoweringScope { TypeLoweringScope(CodeViewDebug &CVD) : CVD(CVD) { ++CVD.TypeEmissionLevel; } ~TypeLoweringScope() { |