diff options
| author | Chris Lattner <sabre@nondot.org> | 2008-11-13 18:52:53 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2008-11-13 18:52:53 +0000 |
| commit | 0046de17e545aa5442ee4a151249008c3043d4a7 (patch) | |
| tree | 1e471c83d24200ba9a8322e8dc4ff23fb12543b6 /clang/lib | |
| parent | f3e388d1bf3f6305b6e8282f8c84dd87b051d24c (diff) | |
| download | bcm5719-llvm-0046de17e545aa5442ee4a151249008c3043d4a7.tar.gz bcm5719-llvm-0046de17e545aa5442ee4a151249008c3043d4a7.zip | |
Fix a couple of suboptimalities in error recovery.
1. In the top level of ParseStatementOrDeclaration, don't eat a } if we
just parsed a statement if it list there. Also, don't even bother
emitting an error about a missing semicolon if the statement had a
bug (an rbrace is fine).
2. In do/while parsing, don't require a 'while' to be present if the do
body didn't parse.
This allows us to generate a clean diagnostic for this code:
t.c:1:22: error: expected expression
void foo (void) { do . while (0); }
^
Thanks to Neil for pointing this out.
llvm-svn: 59256
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Parse/ParseStmt.cpp | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index f5cdfffba50..30c62e3a3cd 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -170,9 +170,10 @@ Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) { // If we reached this code, the statement must end in a semicolon. if (Tok.is(tok::semi)) { ConsumeToken(); - } else { + } else if (!Res.isInvalid) { Diag(Tok, diag::err_expected_semi_after, SemiError); - SkipUntil(tok::semi); + // Skip until we see a } or ;, but don't eat it. + SkipUntil(tok::r_brace, true, true); } return Res; } @@ -717,8 +718,8 @@ Parser::StmtResult Parser::ParseDoStatement() { // The substatement in an iteration-statement implicitly defines a local scope // which is entered and exited each time through the loop. // - bool NeedsInnerScope = (getLang().C99 || getLang().CPlusPlus) && - Tok.isNot(tok::l_brace); + bool NeedsInnerScope = + (getLang().C99 || getLang().CPlusPlus) && Tok.isNot(tok::l_brace); if (NeedsInnerScope) EnterScope(Scope::DeclScope); // Read the body statement. @@ -729,9 +730,11 @@ Parser::StmtResult Parser::ParseDoStatement() { if (Tok.isNot(tok::kw_while)) { ExitScope(); - Diag(Tok, diag::err_expected_while); - Diag(DoLoc, diag::err_matching, "do"); - SkipUntil(tok::semi); + if (!Body.isInvalid) { + Diag(Tok, diag::err_expected_while); + Diag(DoLoc, diag::err_matching, "do"); + SkipUntil(tok::semi, false, true); + } return true; } SourceLocation WhileLoc = ConsumeToken(); @@ -739,7 +742,7 @@ Parser::StmtResult Parser::ParseDoStatement() { if (Tok.isNot(tok::l_paren)) { ExitScope(); Diag(Tok, diag::err_expected_lparen_after, "do/while"); - SkipUntil(tok::semi); + SkipUntil(tok::semi, false, true); return true; } |

