diff options
author | Reid Kleckner <reid@kleckner.net> | 2013-03-28 20:02:56 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2013-03-28 20:02:56 +0000 |
commit | 84e9ab44af3a16f66d62590505db2036ef0aa03b (patch) | |
tree | 00b6c47547bf981887f9ba8fecb25f918c601f44 /lib/Sema/SemaType.cpp | |
parent | ec8deba768e7ba93ad9974763dc3902896924a3c (diff) |
[ms-cxxabi] Correctly compute the size of member pointers
Summary:
This also relaxes the requirement on Windows that the member pointer
class type be a complete type (http://llvm.org/PR12070). We still ask
for a complete type to instantiate any templates (MSVC does this), but
if that fails we continue as normal, relying on any inheritance
attributes on the declaration.
Reviewers: rjmccall
CC: triton, timurrrr, cfe-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D568
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178283 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaType.cpp')
-rw-r--r-- | lib/Sema/SemaType.cpp | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 2bf4023548..bf28907481 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -1728,13 +1728,29 @@ QualType Sema::BuildMemberPointerType(QualType T, QualType Class, // according to the class type, which means that we really need a // complete type if possible, which means we need to instantiate templates. // - // For now, just require a complete type, which will instantiate - // templates. This will also error if the type is just forward-declared, - // which is a bug, but it's a bug that saves us from dealing with some - // complexities at the moment. - if (Context.getTargetInfo().getCXXABI().isMicrosoft() && - RequireCompleteType(Loc, Class, diag::err_incomplete_type)) - return QualType(); + // If template instantiation fails or the type is just incomplete, we have to + // add an extra slot to the member pointer. Yes, this does cause problems + // when passing pointers between TUs that disagree about the size. + if (Context.getTargetInfo().getCXXABI().isMicrosoft()) { + CXXRecordDecl *RD = Class->getAsCXXRecordDecl(); + if (!RD->hasAttr<MSInheritanceAttr>()) { + // Lock in the inheritance model on the first use of a member pointer. + // Otherwise we may disagree about the size at different points in the TU. + // FIXME: MSVC picks a model on the first use that needs to know the size, + // rather than on the first mention of the type, e.g. typedefs. + SourceRange DeclRange = RD->getSourceRange(); + if (RequireCompleteType(Loc, Class, 0) && !RD->isBeingDefined()) { + // We know it doesn't have an attribute and it's incomplete, so use the + // unspecified inheritance model. If we're in the record body, we can + // figure out the inheritance model. + for (CXXRecordDecl::redecl_iterator I = RD->redecls_begin(), + E = RD->redecls_end(); I != E; ++I) { + I->addAttr(::new (Context) UnspecifiedInheritanceAttr( + RD->getSourceRange(), Context)); + } + } + } + } return Context.getMemberPointerType(T, Class.getTypePtr()); } |