diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-01-12 16:11:24 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-01-12 16:11:24 +0000 |
commit | 1d7049a6eddcc1a4bd33c6a595d4ad2ae8c1cece (patch) | |
tree | 9ce770958fea31cd9dc8f2893d421d9e922ab68c | |
parent | 28058d179ae40edc66135458849f1073c841bc74 (diff) |
In Objective-C++, actually compute the base type of a member access
expression for an Objective-C object or pointer type, so that we don't
attempt to treat the member name as a template. Fixes
<rdar://problem/10672501>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148028 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 29 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 6 | ||||
-rw-r--r-- | test/SemaObjCXX/properties.mm | 21 |
3 files changed, 38 insertions, 18 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index da7ba1a2b3..ee25591529 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -4294,21 +4294,26 @@ Sema::ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc, } } - if (BaseType->isPointerType()) + if (BaseType->isPointerType() || BaseType->isObjCObjectPointerType()) BaseType = BaseType->getPointeeType(); } - // We could end up with various non-record types here, such as extended - // vector types or Objective-C interfaces. Just return early and let - // ActOnMemberReferenceExpr do the work. - if (!BaseType->isRecordType()) { - // C++ [basic.lookup.classref]p2: - // [...] If the type of the object expression is of pointer to scalar - // type, the unqualified-id is looked up in the context of the complete - // postfix-expression. - // - // This also indicates that we should be parsing a - // pseudo-destructor-name. + // Objective-C properties allow "." access on Objective-C pointer types, + // so adjust the base type to the object type itself. + if (BaseType->isObjCObjectPointerType()) + BaseType = BaseType->getPointeeType(); + + // C++ [basic.lookup.classref]p2: + // [...] If the type of the object expression is of pointer to scalar + // type, the unqualified-id is looked up in the context of the complete + // postfix-expression. + // + // This also indicates that we could be parsing a pseudo-destructor-name. + // Note that Objective-C class and object types can be pseudo-destructor + // expressions or normal member (ivar or property) access expressions. + if (BaseType->isObjCObjectOrInterfaceType()) { + MayBePseudoDestructor = true; + } else if (!BaseType->isRecordType()) { ObjectType = ParsedType(); MayBePseudoDestructor = true; return Owned(Base); diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index bcdf32b5bc..6c2a94aa9c 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -249,6 +249,12 @@ void Sema::LookupTemplateName(LookupResult &Found, isDependent = ObjectType->isDependentType(); assert((isDependent || !ObjectType->isIncompleteType()) && "Caller should have completed object type"); + + // Template names cannot appear inside an Objective-C class or object type. + if (ObjectType->isObjCObjectOrInterfaceType()) { + Found.clear(); + return; + } } else if (SS.isSet()) { // This nested-name-specifier occurs after another nested-name-specifier, // so long into the context associated with the prior nested-name-specifier. diff --git a/test/SemaObjCXX/properties.mm b/test/SemaObjCXX/properties.mm index 62fddc9b7c..7ea8a48e4b 100644 --- a/test/SemaObjCXX/properties.mm +++ b/test/SemaObjCXX/properties.mm @@ -41,11 +41,20 @@ void test3(Test3 *t) { char *heaparray = new char[t.length]; } -@interface Test4 -- (X&) prop; +// <rdar://problem/10672501> +namespace std { + template<typename T> void count(); +} + +@interface Test4 { +@public + int count; +} +@property int count; @end -void test4(Test4 *t) { - (void)const_cast<const X&>(t.prop); - (void)dynamic_cast<X&>(t.prop); - (void)reinterpret_cast<int&>(t.prop); + +void test4(Test4* t4) { + if (t4.count < 2) { } + if (t4->count < 2) { } } + |