summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CodeGenTypes.cpp
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2016-01-26 19:30:26 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2016-01-26 19:30:26 +0000
commit929025d1a614bef2ef68a50898cccfb283d3abf3 (patch)
tree758e87b50d534c9056b623580b78ade5983335b6 /clang/lib/CodeGen/CodeGenTypes.cpp
parent59066a0803e7cc10ba004cf862baf19a4ad161ca (diff)
downloadbcm5719-llvm-929025d1a614bef2ef68a50898cccfb283d3abf3.tar.gz
bcm5719-llvm-929025d1a614bef2ef68a50898cccfb283d3abf3.zip
[MS ABI] Allow a member pointers' converted type to change
Member pointers in the MS ABI are tricky for a variety of reasons. The size of a member pointer is indeterminate until the program reaches a point where the representation is required to be known. However, *pointers* to member pointers may exist without knowing the pointee type's representation. In these cases, we synthesize an opaque LLVM type for the pointee type. However, we can be in a situation where the underlying member pointer's representation became known mid-way through the program. To account for this, we attempted to manicure CodeGen's type-cache so that we can replace the opaque member pointer type with the real deal while leaving the pointer types unperturbed. This, unfortunately, is a problematic approach to take as we will violate CodeGen's invariants. These violations are mostly harmless but let's do the right thing instead: invalidate the type-cache if a member pointer's LLVM representation changes. This fixes PR26313. llvm-svn: 258839
Diffstat (limited to 'clang/lib/CodeGen/CodeGenTypes.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenTypes.cpp22
1 files changed, 18 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index 09d9bf17b3b..554f9ff640a 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -272,6 +272,17 @@ void CodeGenTypes::UpdateCompletedType(const TagDecl *TD) {
DI->completeType(RD);
}
+void CodeGenTypes::RefreshTypeCacheForClass(const CXXRecordDecl *RD) {
+ QualType T = Context.getRecordType(RD);
+ T = Context.getCanonicalType(T);
+
+ const Type *Ty = T.getTypePtr();
+ if (RecordsWithOpaqueMemberPointers.count(Ty)) {
+ TypeCache.clear();
+ RecordsWithOpaqueMemberPointers.clear();
+ }
+}
+
static llvm::Type *getTypeForFormat(llvm::LLVMContext &VMContext,
const llvm::fltSemantics &format,
bool UseNativeHalf = false) {
@@ -603,10 +614,13 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
}
case Type::MemberPointer: {
- if (!getCXXABI().isMemberPointerConvertible(cast<MemberPointerType>(Ty)))
- return llvm::StructType::create(getLLVMContext());
- ResultType =
- getCXXABI().ConvertMemberPointerType(cast<MemberPointerType>(Ty));
+ auto *MPTy = cast<MemberPointerType>(Ty);
+ if (!getCXXABI().isMemberPointerConvertible(MPTy)) {
+ RecordsWithOpaqueMemberPointers.insert(MPTy->getClass());
+ ResultType = llvm::StructType::create(getLLVMContext());
+ } else {
+ ResultType = getCXXABI().ConvertMemberPointerType(MPTy);
+ }
break;
}
OpenPOWER on IntegriCloud