r218468 - Suggest fix-it for missing '{' after base-clause

Ismail Pazarbasi ismail.pazarbasi at gmail.com
Thu Sep 25 14:13:02 PDT 2014


Author: ismailp
Date: Thu Sep 25 16:13:02 2014
New Revision: 218468

URL: http://llvm.org/viewvc/llvm-project?rev=218468&view=rev
Log:
Suggest fix-it for missing '{' after base-clause

Modified:
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/test/FixIt/fixit.cpp
    cfe/trunk/test/Parser/cxx-template-decl.cpp

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=218468&r1=218467&r2=218468&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Thu Sep 25 16:13:02 2014
@@ -2670,13 +2670,43 @@ void Parser::ParseCXXMemberSpecification
 
   if (Tok.is(tok::colon)) {
     ParseBaseClause(TagDecl);
-
     if (!Tok.is(tok::l_brace)) {
-      Diag(Tok, diag::err_expected_lbrace_after_base_specifiers);
-
-      if (TagDecl)
-        Actions.ActOnTagDefinitionError(getCurScope(), TagDecl);
-      return;
+      bool SuggestFixIt = false;
+      SourceLocation BraceLoc = PP.getLocForEndOfToken(PrevTokLocation);
+      if (Tok.isAtStartOfLine()) {
+        switch (Tok.getKind()) {
+        case tok::kw_private:
+        case tok::kw_protected:
+        case tok::kw_public:
+          SuggestFixIt = NextToken().getKind() == tok::colon;
+          break;
+        case tok::kw_static_assert:
+        case tok::r_brace:
+        case tok::kw_using:
+        // base-clause can have simple-template-id; 'template' can't be there
+        case tok::kw_template:
+          SuggestFixIt = true;
+          break;
+        case tok::identifier:
+          SuggestFixIt = isConstructorDeclarator(true);
+          break;
+        default:
+          SuggestFixIt = isCXXSimpleDeclaration(/*AllowForRangeDecl=*/false);
+          break;
+        }
+      }
+      DiagnosticBuilder LBraceDiag =
+          Diag(BraceLoc, diag::err_expected_lbrace_after_base_specifiers);
+      if (SuggestFixIt) {
+        LBraceDiag << FixItHint::CreateInsertion(BraceLoc, " {");
+        // Try recovering from missing { after base-clause.
+        PP.EnterToken(Tok);
+        Tok.setKind(tok::l_brace);
+      } else {
+        if (TagDecl)
+          Actions.ActOnTagDefinitionError(getCurScope(), TagDecl);
+        return;
+      }
     }
   }
 

Modified: cfe/trunk/test/FixIt/fixit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit.cpp?rev=218468&r1=218467&r2=218468&view=diff
==============================================================================
--- cfe/trunk/test/FixIt/fixit.cpp (original)
+++ cfe/trunk/test/FixIt/fixit.cpp Thu Sep 25 16:13:02 2014
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -pedantic -Wall -Wno-comment -verify -fcxx-exceptions -x c++ %s
-// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -x c++ %s 2>&1 | FileCheck %s
+// RUN: not %clang_cc1 -fsyntax-only -fdiagnostics-parseable-fixits -x c++ -std=c++11 %s 2>&1 | FileCheck %s
 // RUN: cp %s %t
 // RUN: not %clang_cc1 -pedantic -Wall -Wno-comment -fcxx-exceptions -fixit -x c++ %t
 // RUN: %clang_cc1 -fsyntax-only -pedantic -Wall -Werror -Wno-comment -fcxx-exceptions -x c++ %t
@@ -347,3 +347,37 @@ namespace PR15045 {
     return c->a;  // expected-error {{member reference type 'PR15045::Cl0' is not a pointer; maybe you meant to use '.'?}}
   }
 }
+
+namespace curly_after_base_clause {
+struct A { void f(); };
+struct B : A // expected-error{{expected '{' after base class list}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:13-[[@LINE-1]]:13}:" {"
+  int i;
+};
+struct C : A // expected-error{{expected '{' after base class list}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:13-[[@LINE-1]]:13}:" {"
+  using A::f;
+};
+struct D : A // expected-error{{expected '{' after base class list}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:13-[[@LINE-1]]:13}:" {"
+    protected:
+};
+struct E : A  // expected-error{{expected '{' after base class list}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:13-[[@LINE-1]]:13}:" {"
+  template<typename T> struct inner { };
+};
+struct F : A  // expected-error{{expected '{' after base class list}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:13-[[@LINE-1]]:13}:" {"
+  F() { }
+};
+#if __cplusplus >= 201103L
+struct G : A  // expected-error{{expected '{' after base class list}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:13-[[@LINE-1]]:13}:" {"
+  constexpr G(int) { }
+};
+struct H : A  // expected-error{{expected '{' after base class list}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:13-[[@LINE-1]]:13}:" {"
+  static_assert(true, "");
+};
+#endif
+}

Modified: cfe/trunk/test/Parser/cxx-template-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-template-decl.cpp?rev=218468&r1=218467&r2=218468&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx-template-decl.cpp (original)
+++ cfe/trunk/test/Parser/cxx-template-decl.cpp Thu Sep 25 16:13:02 2014
@@ -210,3 +210,18 @@ void Instantiate() {
 }
 
 }
+
+namespace broken_baseclause {
+template<typename T>
+struct base { };
+
+struct t1 : base<int,
+  public:  // expected-error {{expected expression}}
+};  // expected-error {{expected class name}}
+// expected-error at -1 {{expected '{' after base class list}}
+struct t2 : base<int,
+  public  // expected-error {{expected expression}}
+};  // expected-error {{expected class name}}
+// expected-error at -1 {{expected '{' after base class list}}
+
+}





More information about the cfe-commits mailing list