]> granicus.if.org Git - clang/commitdiff
Improve the diagnostic and recovery for missing colons after 'case'
authorDouglas Gregor <dgregor@apple.com>
Thu, 23 Dec 2010 22:56:40 +0000 (22:56 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 23 Dec 2010 22:56:40 +0000 (22:56 +0000)
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
test/Parser/switch-recovery.cpp

index 29779070bee34c5b0cbfd302b6e6caa8cf3c038e..437a950cd94a7bf6864007e0e85741a3c54254cb 100644 (file)
@@ -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);
index 8eb4cff4fbe1f1c7c84db03b1bfe095bec222304..7b6323a405c01040d682d25e53234a71ba439ae9 100644 (file)
@@ -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;
+    }
   }
 };