[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