diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-09-07 15:23:11 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-09-07 15:23:11 +0000 |
commit | 9ba23b4ceacd77cd264501690a7a9e94184ef71b (patch) | |
tree | 23ee137e57a88233ebd96e1c631e834ee9a3b08b /lib/Parse | |
parent | 751f6922376dfe9432795b65a3649179e4ef5cf5 (diff) |
Improve recovery when there is a stray ']' or ')' before the ';' at
the end of a statement. Fixes <rdar://problem/6896493>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113202 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse')
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 7 | ||||
-rw-r--r-- | lib/Parse/ParseObjc.cpp | 2 | ||||
-rw-r--r-- | lib/Parse/ParseStmt.cpp | 4 | ||||
-rw-r--r-- | lib/Parse/Parser.cpp | 19 |
4 files changed, 26 insertions, 6 deletions
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 67d4985239..8bb898591e 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -313,8 +313,9 @@ Decl *Parser::ParseUsingDirective(unsigned Context, // Eat ';'. DeclEnd = Tok.getLocation(); ExpectAndConsume(tok::semi, - GNUAttr ? diag::err_expected_semi_after_attribute_list : - diag::err_expected_semi_after_namespace_name, "", tok::semi); + GNUAttr ? diag::err_expected_semi_after_attribute_list + : diag::err_expected_semi_after_namespace_name, + "", tok::semi); return Actions.ActOnUsingDirective(getCurScope(), UsingLoc, NamespcLoc, SS, IdentLoc, NamespcName, Attr); @@ -422,7 +423,7 @@ Decl *Parser::ParseStaticAssertDeclaration(SourceLocation &DeclEnd){ MatchRHSPunctuation(tok::r_paren, LParenLoc); DeclEnd = Tok.getLocation(); - ExpectAndConsume(tok::semi, diag::err_expected_semi_after_static_assert); + ExpectAndConsumeSemi(diag::err_expected_semi_after_static_assert); return Actions.ActOnStaticAssertDeclaration(StaticAssertLoc, AssertExpr.take(), diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 6861ce940f..5f5b716a61 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -1731,7 +1731,7 @@ StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) { } // Otherwise, eat the semicolon. - ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr); + ExpectAndConsumeSemi(diag::err_expected_semi_after_expr); return Actions.ActOnExprStmt(Actions.MakeFullExpr(Res.take())); } diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 6c240e608c..3ff940faf9 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -137,7 +137,7 @@ Parser::ParseStatementOrDeclaration(bool OnlyStatement) { return StmtError(); } // Otherwise, eat the semicolon. - ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr); + ExpectAndConsumeSemi(diag::err_expected_semi_after_expr); return Actions.ActOnExprStmt(Actions.MakeFullExpr(Expr.get())); } @@ -507,7 +507,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { // FIXME: Use attributes? // Eat the semicolon at the end of stmt and convert the expr into a // statement. - ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr); + ExpectAndConsumeSemi(diag::err_expected_semi_after_expr); R = Actions.ActOnExprStmt(Actions.MakeFullExpr(Res.get())); } } diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 44bd0fbc0c..ca06ba72f6 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -162,6 +162,25 @@ bool Parser::ExpectAndConsume(tok::TokenKind ExpectedTok, unsigned DiagID, return true; } +bool Parser::ExpectAndConsumeSemi(unsigned DiagID) { + if (Tok.is(tok::semi) || Tok.is(tok::code_completion)) { + ConsumeAnyToken(); + return false; + } + + if ((Tok.is(tok::r_paren) || Tok.is(tok::r_square)) && + NextToken().is(tok::semi)) { + Diag(Tok, diag::err_extraneous_token_before_semi) + << PP.getSpelling(Tok) + << FixItHint::CreateRemoval(Tok.getLocation()); + ConsumeAnyToken(); // The ')' or ']'. + ConsumeToken(); // The ';'. + return false; + } + + return ExpectAndConsume(tok::semi, DiagID); +} + //===----------------------------------------------------------------------===// // Error recovery. //===----------------------------------------------------------------------===// |