]> granicus.if.org Git - clang/commitdiff
In Objective-C++, allow the keyword 'class' to be used as a property
authorDouglas Gregor <dgregor@apple.com>
Thu, 16 Feb 2012 18:19:22 +0000 (18:19 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 16 Feb 2012 18:19:22 +0000 (18:19 +0000)
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

lib/Parse/ParseExpr.cpp
test/SemaObjCXX/properties.mm

index b5e4a5f620cfb42f30bf7bfc8abe03eee29a6a0b..642fc2ac650d5e47d66904727e15293c9e8cc9d8 100644 (file)
@@ -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())
index ac780c023bf5bf2bc02a7c4ae562103d9e71583c..0264f463adafce1f645ee742d74bda37583d6323 100644 (file)
@@ -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*);