aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaType.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2013-03-28 20:02:56 +0000
committerReid Kleckner <reid@kleckner.net>2013-03-28 20:02:56 +0000
commit84e9ab44af3a16f66d62590505db2036ef0aa03b (patch)
tree00b6c47547bf981887f9ba8fecb25f918c601f44 /lib/Sema/SemaType.cpp
parentec8deba768e7ba93ad9974763dc3902896924a3c (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.cpp30
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());
}