summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2016-08-31 15:59:30 +0000
committerReid Kleckner <rnk@google.com>2016-08-31 15:59:30 +0000
commit9dac47319d29430e6fc6e04d2839e0f2c45dffac (patch)
treea14fd5fa316c0b6db97cd62814052b0b6b009367 /llvm/lib/CodeGen
parent9099901099fe65df184c5ff9cb4d08cfc4fd5eea (diff)
downloadbcm5719-llvm-9dac47319d29430e6fc6e04d2839e0f2c45dffac.tar.gz
bcm5719-llvm-9dac47319d29430e6fc6e04d2839e0f2c45dffac.zip
[codeview] Emit vtable shape information
The shape of the vtable is passed down as the size of the __vtbl_ptr_type. This special pointer type appears both as the pointee type of the vptr type, and by itself in every dynamic class. For classes with multiple vtables, only the shape of the primary vftable is included, as the shape of all secondary vftables will be the same as in the base class. Fixes PR28150 llvm-svn: 280254
Diffstat (limited to 'llvm/lib/CodeGen')
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp25
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h1
2 files changed, 24 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index e30864e6934..63d9a4744a4 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());
}
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
index e4bbd61d4ce..2dc33235d80 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h
@@ -251,6 +251,7 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
codeview::TypeIndex lowerTypeMemberPointer(const DIDerivedType *Ty);
codeview::TypeIndex lowerTypeModifier(const DIDerivedType *Ty);
codeview::TypeIndex lowerTypeFunction(const DISubroutineType *Ty);
+ codeview::TypeIndex lowerTypeVFTableShape(const DIDerivedType *Ty);
codeview::TypeIndex lowerTypeMemberFunction(const DISubroutineType *Ty,
const DIType *ClassTy,
int ThisAdjustment);
OpenPOWER on IntegriCloud