diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-02-16 18:19:22 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-02-16 18:19:22 +0000 |
commit | 8f70bda5ec44417bdc4130df23b11ce4aaf70b3b (patch) | |
tree | 11da681984e8d4c00b38ccdf736459a29e04a8ba | |
parent | f11641a2c651e4e9733c5f5011993554d7c635e5 (diff) |
In Objective-C++, allow the keyword 'class' to be used as a property
name for dot syntax, e.g., NSObject.class or foo.class. For other
C++-keywords-as-method-names, use message send syntax. Fixes
<rdar://problem/10794452>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150710 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Parse/ParseExpr.cpp | 26 | ||||
-rw-r--r-- | test/SemaObjCXX/properties.mm | 17 |
2 files changed, 37 insertions, 6 deletions
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index b5e4a5f620..642fc2ac65 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -726,7 +726,9 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression, (&II == Ident_super && getCurScope()->isInObjcMethodScope()))) { ConsumeToken(); - if (Tok.isNot(tok::identifier)) { + // Allow either an identifier or the keyword 'class' (in C++). + if (Tok.isNot(tok::identifier) && + !(getLang().CPlusPlus && Tok.is(tok::kw_class))) { Diag(Tok, diag::err_expected_property_name); return ExprError(); } @@ -1406,11 +1408,23 @@ Parser::ParsePostfixExpressionSuffix(ExprResult LHS) { // FIXME: Add support for explicit call of template constructor. SourceLocation TemplateKWLoc; UnqualifiedId Name; - if (ParseUnqualifiedId(SS, - /*EnteringContext=*/false, - /*AllowDestructorName=*/true, - /*AllowConstructorName=*/ getLang().MicrosoftExt, - ObjectType, TemplateKWLoc, Name)) + if (getLang().ObjC2 && OpKind == tok::period && Tok.is(tok::kw_class)) { + // Objective-C++: + // After a '.' in a member access expression, treat the keyword + // 'class' as if it were an identifier. + // + // This hack allows property access to the 'class' method because it is + // such a common method name. For other C++ keywords that are + // Objective-C method names, one must use the message send syntax. + IdentifierInfo *Id = Tok.getIdentifierInfo(); + SourceLocation Loc = ConsumeToken(); + Name.setIdentifier(Id, Loc); + } else if (ParseUnqualifiedId(SS, + /*EnteringContext=*/false, + /*AllowDestructorName=*/true, + /*AllowConstructorName=*/ + getLang().MicrosoftExt, + ObjectType, TemplateKWLoc, Name)) LHS = ExprError(); if (!LHS.isInvalid()) diff --git a/test/SemaObjCXX/properties.mm b/test/SemaObjCXX/properties.mm index ac780c023b..0264f463ad 100644 --- a/test/SemaObjCXX/properties.mm +++ b/test/SemaObjCXX/properties.mm @@ -68,3 +68,20 @@ void test5(Test5* t5) { if (t5->count < 2) { } } + +@interface Test6 ++ (Class)class; +- (Class)class; +@end + +void test6(Test6 *t6) { + Class x = t6.class; + Class x2 = Test6.class; +} + +template<typename T> +void test6_template(T *t6) { + Class x = t6.class; +} + +template void test6_template(Test6*); |