summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/SemaType.cpp70
-rw-r--r--clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp27
2 files changed, 65 insertions, 32 deletions
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 57eae9a7fa1..f7042927e49 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -5147,6 +5147,45 @@ static bool hasVisibleDefinition(Sema &S, NamedDecl *D, NamedDecl **Suggested) {
return LookupResult::isVisible(S, D);
}
+/// Locks in the inheritance model for the given class and all of its bases.
+static void assignInheritanceModel(Sema &S, CXXRecordDecl *RD) {
+ RD = RD->getMostRecentDecl();
+ if (!RD->hasAttr<MSInheritanceAttr>()) {
+ MSInheritanceAttr::Spelling IM;
+
+ switch (S.MSPointerToMemberRepresentationMethod) {
+ case LangOptions::PPTMK_BestCase:
+ IM = RD->calculateInheritanceModel();
+ break;
+ case LangOptions::PPTMK_FullGeneralitySingleInheritance:
+ IM = MSInheritanceAttr::Keyword_single_inheritance;
+ break;
+ case LangOptions::PPTMK_FullGeneralityMultipleInheritance:
+ IM = MSInheritanceAttr::Keyword_multiple_inheritance;
+ break;
+ case LangOptions::PPTMK_FullGeneralityVirtualInheritance:
+ IM = MSInheritanceAttr::Keyword_unspecified_inheritance;
+ break;
+ }
+
+ RD->addAttr(MSInheritanceAttr::CreateImplicit(
+ S.getASTContext(), IM,
+ /*BestCase=*/S.MSPointerToMemberRepresentationMethod ==
+ LangOptions::PPTMK_BestCase,
+ S.ImplicitMSInheritanceAttrLoc.isValid()
+ ? S.ImplicitMSInheritanceAttrLoc
+ : RD->getSourceRange()));
+ }
+
+ if (RD->hasDefinition()) {
+ // Assign inheritance models to all of the base classes, because now we can
+ // form pointers to members of base classes without calling
+ // RequireCompleteType on the pointer to member of the base class type.
+ for (const CXXBaseSpecifier &BS : RD->bases())
+ assignInheritanceModel(S, BS.getType()->getAsCXXRecordDecl());
+ }
+}
+
/// \brief The implementation of RequireCompleteType
bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
TypeDiagnoser &Diagnoser) {
@@ -5185,36 +5224,7 @@ bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>()) {
if (!MPTy->getClass()->isDependentType()) {
RequireCompleteType(Loc, QualType(MPTy->getClass(), 0), 0);
-
- CXXRecordDecl *RD = MPTy->getMostRecentCXXRecordDecl();
- if (!RD->hasAttr<MSInheritanceAttr>()) {
- MSInheritanceAttr::Spelling InheritanceModel;
-
- switch (MSPointerToMemberRepresentationMethod) {
- case LangOptions::PPTMK_BestCase:
- InheritanceModel = RD->calculateInheritanceModel();
- break;
- case LangOptions::PPTMK_FullGeneralitySingleInheritance:
- InheritanceModel = MSInheritanceAttr::Keyword_single_inheritance;
- break;
- case LangOptions::PPTMK_FullGeneralityMultipleInheritance:
- InheritanceModel =
- MSInheritanceAttr::Keyword_multiple_inheritance;
- break;
- case LangOptions::PPTMK_FullGeneralityVirtualInheritance:
- InheritanceModel =
- MSInheritanceAttr::Keyword_unspecified_inheritance;
- break;
- }
-
- RD->addAttr(MSInheritanceAttr::CreateImplicit(
- getASTContext(), InheritanceModel,
- /*BestCase=*/MSPointerToMemberRepresentationMethod ==
- LangOptions::PPTMK_BestCase,
- ImplicitMSInheritanceAttrLoc.isValid()
- ? ImplicitMSInheritanceAttrLoc
- : RD->getSourceRange()));
- }
+ assignInheritanceModel(*this, MPTy->getMostRecentCXXRecordDecl());
}
}
}
diff --git a/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp b/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
index 4ce8a02dcb0..2570754fba3 100644
--- a/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
+++ b/clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s
-// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 | FileCheck %s -check-prefix=X64
+// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -fms-extensions | FileCheck %s
+// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=x86_64-pc-win32 -fms-extensions | FileCheck %s -check-prefix=X64
// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -fms-extensions -verify
// RUN: %clang_cc1 -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -DINCOMPLETE_VIRTUAL -DMEMFUN -fms-extensions -verify
// FIXME: Test x86_64 member pointers when codegen no longer asserts on records
@@ -607,6 +607,29 @@ void (C::*getmp())() {
}
+namespace pr2007 {
+struct A {
+ void f();
+ void f(int);
+};
+struct B : public A {};
+void test() { void (B::*a)() = &B::f; }
+// CHECK-LABEL: define void @"\01?test@pr2007@@YAXXZ"
+// CHECK: store i8* bitcast (void (%"struct.pr2007::A"*)* @"\01?f@A@pr2007@@QAEXXZ" to i8*)
+}
+
+namespace pr2007_kw {
+struct A {
+ void f();
+ void f(int);
+};
+struct __single_inheritance B;
+struct B : public A {};
+void test() { void (B::*a)() = &B::f; }
+// CHECK-LABEL: define void @"\01?test@pr2007_kw@@YAXXZ"
+// CHECK: store i8* bitcast (void (%"struct.pr2007_kw::A"*)* @"\01?f@A@pr2007_kw@@QAEXXZ" to i8*)
+}
+
#else
struct __virtual_inheritance A;
#ifdef MEMFUN
OpenPOWER on IntegriCloud