aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp25
1 files changed, 23 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index e30864e..63d9a47 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -937,6 +937,9 @@ TypeIndex CodeViewDebug::lowerType(const DIType *Ty, const DIType *ClassTy) {
case dwarf::DW_TAG_base_type:
return lowerTypeBasic(cast<DIBasicType>(Ty));
case dwarf::DW_TAG_pointer_type:
+ if (cast<DIDerivedType>(Ty)->getName() == "__vtbl_ptr_type")
+ return lowerTypeVFTableShape(cast<DIDerivedType>(Ty));
+ LLVM_FALLTHROUGH;
case dwarf::DW_TAG_reference_type:
case dwarf::DW_TAG_rvalue_reference_type:
return lowerTypePointer(cast<DIDerivedType>(Ty));
@@ -1321,6 +1324,12 @@ TypeIndex CodeViewDebug::lowerTypeMemberFunction(const DISubroutineType *Ty,
return TI;
}
+TypeIndex CodeViewDebug::lowerTypeVFTableShape(const DIDerivedType *Ty) {
+ unsigned VSlotCount = Ty->getSizeInBits() / (8 * Asm->MAI->getPointerSize());
+ SmallVector<VFTableSlotKind, 4> Slots(VSlotCount, VFTableSlotKind::Near);
+ return TypeTable.writeKnownType(VFTableShapeRecord(Slots));
+}
+
static MemberAccess translateAccessFlags(unsigned RecordTag, unsigned Flags) {
switch (Flags & DINode::FlagAccessibility) {
case DINode::FlagPrivate: return MemberAccess::Private;
@@ -1453,6 +1462,8 @@ struct llvm::ClassInfo {
// Direct overloaded methods gathered by name.
MethodsMap Methods;
+ TypeIndex VShapeTI;
+
std::vector<const DICompositeType *> NestedClasses;
};
@@ -1501,11 +1512,13 @@ ClassInfo CodeViewDebug::collectClassInfo(const DICompositeType *Ty) {
collectMemberInfo(Info, DDTy);
} else if (DDTy->getTag() == dwarf::DW_TAG_inheritance) {
Info.Inheritance.push_back(DDTy);
+ } else if (DDTy->getTag() == dwarf::DW_TAG_pointer_type &&
+ DDTy->getName() == "__vtbl_ptr_type") {
+ Info.VShapeTI = getTypeIndex(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.
}
- // FIXME: Get Clang to emit function virtual table here and handle it.
} else if (auto *Composite = dyn_cast<DICompositeType>(Element)) {
Info.NestedClasses.push_back(Composite);
}
@@ -1646,6 +1659,14 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) {
continue;
}
+ // Virtual function pointer member.
+ if ((Member->getFlags() & DINode::FlagArtificial) &&
+ Member->getName().startswith("_vptr$")) {
+ Fields.writeMemberType(VFPtrRecord(getTypeIndex(Member->getBaseType())));
+ MemberCount++;
+ continue;
+ }
+
// Data member.
uint64_t MemberOffsetInBits =
Member->getOffsetInBits() + MemberInfo.BaseOffset;
@@ -1704,7 +1725,7 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) {
}
TypeIndex FieldTI = TypeTable.writeFieldList(Fields);
- return std::make_tuple(FieldTI, TypeIndex(), MemberCount,
+ return std::make_tuple(FieldTI, Info.VShapeTI, MemberCount,
!Info.NestedClasses.empty());
}