]> granicus.if.org Git - clang/commitdiff
When we see the a '[' in a postfix expression in Objective-C, perform
authorDouglas Gregor <dgregor@apple.com>
Mon, 31 May 2010 14:40:22 +0000 (14:40 +0000)
committerDouglas Gregor <dgregor@apple.com>
Mon, 31 May 2010 14:40:22 +0000 (14:40 +0000)
a simple, quick check to determine whether the expression starting
with '[' can only be an Objective-C message send. If so, don't parse
it as an array subscript expression. This improves recovery for, e.g.,

  [a method1]
  [a method2]

so that we now produce

  t.m:10:13: error: expected ';' after expression
  [a method]
            ^

instead of some mess about expecting ']'.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105221 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Parse/Parser.h
lib/Parse/ParseExpr.cpp
lib/Parse/ParseObjc.cpp
test/FixIt/typo.m

index 8081c2492b2f82f9ce913505212927ad722b538a..233ed1c0b83b45539a6eb840171a1b83e0119895 100644 (file)
@@ -1059,6 +1059,7 @@ private:
   OwningExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
   OwningExprResult ParseObjCSelectorExpression(SourceLocation AtLoc);
   OwningExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);
+  bool isSimpleObjCMessageExpression();
   OwningExprResult ParseObjCMessageExpression();
   OwningExprResult ParseObjCMessageExpressionBody(SourceLocation LBracloc,
                                                   SourceLocation SuperLoc,
index 8fb71c3ff64495128890b6f357731c6b5c346ee8..093f9738ca9ba9d1b2aa0a8fc72ef5b1dceb7171 100644 (file)
@@ -961,6 +961,9 @@ Parser::ParsePostfixExpressionSuffix(OwningExprResult LHS) {
     default:  // Not a postfix-expression suffix.
       return move(LHS);
     case tok::l_square: {  // postfix-expression: p-e '[' expression ']'
+      if (getLang().ObjC1 && isSimpleObjCMessageExpression())
+        return move(LHS);
+          
       Loc = ConsumeBracket();
       OwningExprResult Idx(ParseExpression());
 
index b76b677af0b76497aba853e24e98d25bd5633700..34b8187be5121e474733f04da7a9626d67624a30 100644 (file)
@@ -1794,6 +1794,21 @@ bool Parser::ParseObjCXXMessageReceiver(bool &IsExpr, void *&TypeOrExpr) {
   return false;
 }
 
+/// \brief Determine whether the parser is currently referring to a an
+/// Objective-C message send, using a simplified heuristic to avoid overhead.
+///
+/// This routine will only return true for a subset of valid message-send
+/// expressions.
+bool Parser::isSimpleObjCMessageExpression() {
+  assert(Tok.is(tok::l_square) && 
+         "Incorrect start for isSimpleObjCMessageExpression");
+  if (!getLang().ObjC1)
+    return false;
+  
+  return GetLookAheadToken(1).is(tok::identifier) &&
+         GetLookAheadToken(2).is(tok::identifier);
+}
+
 ///   objc-message-expr:
 ///     '[' objc-receiver objc-message-args ']'
 ///
index 7197bc746d127022be9e717046898065c4539725..8a9b4c804caac14d251323501a7df1543158dd24 100644 (file)
@@ -24,7 +24,8 @@ void test() {
   int his_ivar; // expected-note 2{{'his_ivar' declared here}}
   float wibble;
 }
-
+- (void)method;
++ (void)method;
 @property int his_prop; // expected-note{{'his_prop' declared here}}
 @end
 
@@ -145,4 +146,9 @@ double *isupper(int);
 @end
 #endif
 
+void f(A *a) {
+  f(a) // expected-error{{expected ';' after expression}}
+  [a method] // expected-error{{expected ';' after expression}}
+  [A method] // expected-error{{expected ';' after expression}}
+}