summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-01-12 16:11:24 +0000
committerDouglas Gregor <dgregor@apple.com>2012-01-12 16:11:24 +0000
commitbf3a826f2cf7975cf6d92de325e00e50ede04cba (patch)
treed4b6655c22cf32518b55ae197c2f8a995243fe69 /clang
parent0a0a829beaf5d1030f56bd3290df593a9f6f4a76 (diff)
downloadbcm5719-llvm-bf3a826f2cf7975cf6d92de325e00e50ede04cba.tar.gz
bcm5719-llvm-bf3a826f2cf7975cf6d92de325e00e50ede04cba.zip
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>. llvm-svn: 148028
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp29
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp6
-rw-r--r--clang/test/SemaObjCXX/properties.mm21
3 files changed, 38 insertions, 18 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index da7ba1a2b38..ee25591529d 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/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/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index bcdf32b5bc4..6c2a94aa9c5 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/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/clang/test/SemaObjCXX/properties.mm b/clang/test/SemaObjCXX/properties.mm
index 62fddc9b7cd..7ea8a48e4b6 100644
--- a/clang/test/SemaObjCXX/properties.mm
+++ b/clang/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) { }
}
+
OpenPOWER on IntegriCloud