summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2008-11-13 18:52:53 +0000
committerChris Lattner <sabre@nondot.org>2008-11-13 18:52:53 +0000
commit0046de17e545aa5442ee4a151249008c3043d4a7 (patch)
tree1e471c83d24200ba9a8322e8dc4ff23fb12543b6 /clang/lib
parentf3e388d1bf3f6305b6e8282f8c84dd87b051d24c (diff)
downloadbcm5719-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.cpp19
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;
}
OpenPOWER on IntegriCloud