aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-12-23 22:56:40 +0000
committerDouglas Gregor <dgregor@apple.com>2010-12-23 22:56:40 +0000
commit662a4822ee7c8696434b054303c5076a606ab175 (patch)
treeb8610ed895bb1530766b3c9f964aa53771b0953c
parenta8bc8c9e9ba5bffebde00340786fe8542469c435 (diff)
Improve the diagnostic and recovery for missing colons after 'case'
and 'default' statements, including a Fix-It to add the colon: test/Parser/switch-recovery.cpp:13:12: error: expected ':' after 'case' case 17 // expected-error{{expected ':' after 'case'}} ^ : test/Parser/switch-recovery.cpp:16:12: error: expected ':' after 'default' default // expected-error{{expected ':' after 'default'}} ^ : git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@122522 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Parse/ParseStmt.cpp28
-rw-r--r--test/Parser/switch-recovery.cpp10
2 files changed, 25 insertions, 13 deletions
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp
index 29779070be..437a950cd9 100644
--- a/lib/Parse/ParseStmt.cpp
+++ b/lib/Parse/ParseStmt.cpp
@@ -315,14 +315,16 @@ StmtResult Parser::ParseCaseStatement(AttributeList *Attr) {
ColonProtection.restore();
+ SourceLocation ColonLoc;
if (Tok.isNot(tok::colon)) {
- Diag(Tok, diag::err_expected_colon_after) << "'case'";
- SkipUntil(tok::colon);
- return StmtError();
+ SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
+ Diag(ExpectedLoc, diag::err_expected_colon_after) << "'case'"
+ << FixItHint::CreateInsertion(ExpectedLoc, ":");
+ ColonLoc = ExpectedLoc;
+ } else {
+ ColonLoc = ConsumeToken();
}
-
- SourceLocation ColonLoc = ConsumeToken();
-
+
StmtResult Case =
Actions.ActOnCaseStmt(CaseLoc, LHS.get(), DotDotDotLoc,
RHS.get(), ColonLoc);
@@ -384,14 +386,16 @@ StmtResult Parser::ParseDefaultStatement(AttributeList *Attr) {
assert(Tok.is(tok::kw_default) && "Not a default stmt!");
SourceLocation DefaultLoc = ConsumeToken(); // eat the 'default'.
+ SourceLocation ColonLoc;
if (Tok.isNot(tok::colon)) {
- Diag(Tok, diag::err_expected_colon_after) << "'default'";
- SkipUntil(tok::colon);
- return StmtError();
+ SourceLocation ExpectedLoc = PP.getLocForEndOfToken(PrevTokLocation);
+ Diag(ExpectedLoc, diag::err_expected_colon_after) << "'default'"
+ << FixItHint::CreateInsertion(ExpectedLoc, ":");
+ ColonLoc = ExpectedLoc;
+ } else {
+ ColonLoc = ConsumeToken();
}
-
- SourceLocation ColonLoc = ConsumeToken();
-
+
// Diagnose the common error "switch (X) {... default: }", which is not valid.
if (Tok.is(tok::r_brace)) {
Diag(Tok, diag::err_label_end_of_compound_statement);
diff --git a/test/Parser/switch-recovery.cpp b/test/Parser/switch-recovery.cpp
index 8eb4cff4fb..7b6323a405 100644
--- a/test/Parser/switch-recovery.cpp
+++ b/test/Parser/switch-recovery.cpp
@@ -3,10 +3,18 @@
// <rdar://problem/7971948>
struct A {};
struct B {
- void foo() {
+ void foo(int b) {
switch (a) { // expected-error{{use of undeclared identifier 'a'}}
default:
return;
}
+
+ switch (b) {
+ case 17 // expected-error{{expected ':' after 'case'}}
+ break;
+
+ default // expected-error{{expected ':' after 'default'}}
+ return;
+ }
}
};