diff options
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 70 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp | 27 |
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 |