From 662a4822ee7c8696434b054303c5076a606ab175 Mon Sep 17 00:00:00 2001 From: Douglas Gregor <dgregor@apple.com> Date: Thu, 23 Dec 2010 22:56:40 +0000 Subject: [PATCH] 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 --- lib/Parse/ParseStmt.cpp | 28 ++++++++++++++++------------ test/Parser/switch-recovery.cpp | 10 +++++++++- 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; + } } }; -- 2.40.0