[cfe-commits] r46768 - in /cfe/trunk: Parse/ParseObjc.cpp Parse/ParseStmt.cpp include/clang/Parse/Parser.h test/Parser/objc-try-catch-1.m

Steve Naroff snaroff at apple.com
Tue Feb 5 13:27:35 PST 2008


Author: snaroff
Date: Tue Feb  5 15:27:35 2008
New Revision: 46768

URL: http://llvm.org/viewvc/llvm-project?rev=46768&view=rev
Log:

Fix Parser::ParseObjCTryStmt() to allow for trailing @-keyword statements/expressions.

This bug fix is the result of not having 2-token lookahead to recognize specific @-keywords.


Modified:
    cfe/trunk/Parse/ParseObjc.cpp
    cfe/trunk/Parse/ParseStmt.cpp
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/test/Parser/objc-try-catch-1.m

Modified: cfe/trunk/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseObjc.cpp?rev=46768&r1=46767&r2=46768&view=diff

==============================================================================
--- cfe/trunk/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/Parse/ParseObjc.cpp Tue Feb  5 15:27:35 2008
@@ -1150,8 +1150,11 @@
 ///     parameter-declaration
 ///     '...' [OBJC2]
 ///
-Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) {
+Parser::StmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc, 
+                                            bool &processAtKeyword) {
   bool catch_or_finally_seen = false;
+  processAtKeyword = false;
+  
   ConsumeToken(); // consume try
   if (Tok.isNot(tok::l_brace)) {
     Diag (Tok, diag::err_expected_lbrace);
@@ -1180,8 +1183,7 @@
                                                            DeclaratorInfo, 0);
           StmtResult stmtResult = Actions.ActOnDeclStmt(aBlockVarDecl);
           FirstPart = stmtResult.isInvalid ? 0 : stmtResult.Val;
-        }
-        else
+        } else
           ConsumeToken(); // consume '...'
         SourceLocation RParenLoc = ConsumeParen();
         StmtResult CatchBody = ParseCompoundStatementBody();
@@ -1190,16 +1192,14 @@
         CatchStmts = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc, RParenLoc, 
           FirstPart, CatchBody.Val, CatchStmts.Val);
         ExitScope();
-      }
-      else {
+      } else {
         Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after, 
              "@catch clause");
         return true;
       }
       catch_or_finally_seen = true;
-    }
-    else if (Tok.isObjCAtKeyword(tok::objc_finally)) {
-       ConsumeToken(); // consume finally
+    } else if (Tok.isObjCAtKeyword(tok::objc_finally)) {
+      ConsumeToken(); // consume finally
       StmtResult FinallyBody = ParseCompoundStatementBody();
       if (FinallyBody.isInvalid)
         FinallyBody = Actions.ActOnNullStmt(Tok.getLocation());
@@ -1207,6 +1207,9 @@
                                                    FinallyBody.Val);
       catch_or_finally_seen = true;
       break;
+    } else {
+      processAtKeyword = true;
+      break;
     }
   }
   if (!catch_or_finally_seen) {
@@ -1259,6 +1262,31 @@
   return MDecl;
 }
 
+Parser::StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) {
+  if (Tok.isObjCAtKeyword(tok::objc_try)) {
+    bool parsedAtSign;
+    
+    StmtResult Res = ParseObjCTryStmt(AtLoc, parsedAtSign);
+    if (!Res.isInvalid && parsedAtSign)
+      return ParseObjCAtStatement(AtLoc);
+    return Res;
+  } else if (Tok.isObjCAtKeyword(tok::objc_throw))
+    return ParseObjCThrowStmt(AtLoc);
+  else if (Tok.isObjCAtKeyword(tok::objc_synchronized))
+    return ParseObjCSynchronizedStmt(AtLoc);
+  ExprResult Res = ParseExpressionWithLeadingAt(AtLoc);
+  if (Res.isInvalid) {
+    // If the expression is invalid, skip ahead to the next semicolon. Not
+    // doing this opens us up to the possibility of infinite loops if
+    // ParseExpression does not consume any tokens.
+    SkipUntil(tok::semi);
+    return true;
+  }
+  // Otherwise, eat the semicolon.
+  ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
+  return Actions.ActOnExprStmt(Res.Val);
+}
+
 Parser::ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
 
   switch (Tok.getKind()) {

Modified: cfe/trunk/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseStmt.cpp?rev=46768&r1=46767&r2=46768&view=diff

==============================================================================
--- cfe/trunk/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/Parse/ParseStmt.cpp Tue Feb  5 15:27:35 2008
@@ -87,23 +87,7 @@
   case tok::at: // May be a @try or @throw statement
     {
       AtLoc = ConsumeToken();  // consume @
-      if (Tok.isObjCAtKeyword(tok::objc_try))
-        return ParseObjCTryStmt(AtLoc);
-      else if (Tok.isObjCAtKeyword(tok::objc_throw))
-        return ParseObjCThrowStmt(AtLoc);
-      else if (Tok.isObjCAtKeyword(tok::objc_synchronized))
-        return ParseObjCSynchronizedStmt(AtLoc);
-      ExprResult Res = ParseExpressionWithLeadingAt(AtLoc);
-      if (Res.isInvalid) {
-        // If the expression is invalid, skip ahead to the next semicolon. Not
-        // doing this opens us up to the possibility of infinite loops if
-        // ParseExpression does not consume any tokens.
-        SkipUntil(tok::semi);
-        return true;
-      }
-      // Otherwise, eat the semicolon.
-      ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr);
-      return Actions.ActOnExprStmt(Res.Val);
+      return ParseObjCAtStatement(AtLoc);
     }
 
   default:

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=46768&r1=46767&r2=46768&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Tue Feb  5 15:27:35 2008
@@ -403,7 +403,8 @@
   StmtResult ParseBreakStatement();
   StmtResult ParseReturnStatement();
   StmtResult ParseAsmStatement();
-  StmtResult ParseObjCTryStmt(SourceLocation atLoc);
+  StmtResult ParseObjCAtStatement(SourceLocation atLoc);
+  StmtResult ParseObjCTryStmt(SourceLocation atLoc, bool &processAtKeyword);
   StmtResult ParseObjCThrowStmt(SourceLocation atLoc);
   StmtResult ParseObjCSynchronizedStmt(SourceLocation atLoc);
   void ParseAsmOperandsOpt(llvm::SmallVectorImpl<std::string> &Names,

Modified: cfe/trunk/test/Parser/objc-try-catch-1.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/objc-try-catch-1.m?rev=46768&r1=46767&r2=46768&view=diff

==============================================================================
--- cfe/trunk/test/Parser/objc-try-catch-1.m (original)
+++ cfe/trunk/test/Parser/objc-try-catch-1.m Tue Feb  5 15:27:35 2008
@@ -50,3 +50,13 @@
   @finally {}
 }
 
+void noTwoTokenLookAheadRequiresABitOfFancyFootworkInTheParser() {
+    @try {
+        // Do something
+    } @catch (...) {}
+    @try {
+        // Do something
+    } @catch (...) {}
+    return 0;
+}
+





More information about the cfe-commits mailing list