aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2016-06-24 16:24:24 +0000
committerReid Kleckner <rnk@google.com>2016-06-24 16:24:24 +0000
commit9f7f3e1e64067c6802882e691a7a3c8a5926a737 (patch)
tree4c3d67d10f7f213f79aa0fcd42dd39abd67b868e /llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
parente794678404abc41ce3b22625da39c1379c1d7a1d (diff)
downloadllvm-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.cpp48
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() {