[cfe-commits] r147808 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp test/FixIt/fixit-cxx0x.cpp test/FixIt/fixit.cpp

Richard Smith richard-llvm at metafoo.co.uk
Mon Jan 9 14:31:45 PST 2012


Author: rsmith
Date: Mon Jan  9 16:31:44 2012
New Revision: 147808

URL: http://llvm.org/viewvc/llvm-project?rev=147808&view=rev
Log:
Extend the diagnostic for a ',' at the end of a declaration where a ';' was
intended to cover C++ class definitions.

Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Parse/ParseDeclCXX.cpp
    cfe/trunk/test/FixIt/fixit-cxx0x.cpp
    cfe/trunk/test/FixIt/fixit.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=147808&r1=147807&r2=147808&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon Jan  9 16:31:44 2012
@@ -1924,7 +1924,10 @@
   void ParseAlignmentSpecifier(ParsedAttributes &Attrs,
                                SourceLocation *endLoc = 0);
 
-  VirtSpecifiers::Specifier isCXX0XVirtSpecifier() const;
+  VirtSpecifiers::Specifier isCXX0XVirtSpecifier(const Token &Tok) const;
+  VirtSpecifiers::Specifier isCXX0XVirtSpecifier() const {
+    return isCXX0XVirtSpecifier(Tok);
+  }
   void ParseOptionalCXX0XVirtSpecifierSeq(VirtSpecifiers &VS);
 
   bool isCXX0XFinalKeyword() const;

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=147808&r1=147807&r2=147808&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Jan  9 16:31:44 2012
@@ -994,9 +994,15 @@
 
   case tok::amp:
   case tok::ampamp:
-  case tok::colon: // Might be a typo for '::'.
     return getLang().CPlusPlus;
 
+  case tok::l_square: // Might be an attribute on an unnamed bit-field.
+    return Context == Declarator::MemberContext && getLang().CPlusPlus0x &&
+           NextToken().is(tok::l_square);
+
+  case tok::colon: // Might be a typo for '::' or an unnamed bit-field.
+    return Context == Declarator::MemberContext || getLang().CPlusPlus;
+
   case tok::identifier:
     switch (NextToken().getKind()) {
     case tok::code_completion:
@@ -1019,8 +1025,13 @@
 
     case tok::colon:
       // At namespace scope, 'identifier:' is probably a typo for 'identifier::'
-      // and in block scope it's probably a label.
-      return getLang().CPlusPlus && Context == Declarator::FileContext;
+      // and in block scope it's probably a label. Inside a class definition,
+      // this is a bit-field.
+      return Context == Declarator::MemberContext ||
+             (getLang().CPlusPlus && Context == Declarator::FileContext);
+
+    case tok::identifier: // Possible virt-specifier.
+      return getLang().CPlusPlus0x && isCXX0XVirtSpecifier(NextToken());
 
     default:
       return false;

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=147808&r1=147807&r2=147808&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon Jan  9 16:31:44 2012
@@ -1548,13 +1548,13 @@
   }
 }
 
-/// isCXX0XVirtSpecifier - Determine whether the next token is a C++0x
+/// isCXX0XVirtSpecifier - Determine whether the given token is a C++0x
 /// virt-specifier.
 ///
 ///       virt-specifier:
 ///         override
 ///         final
-VirtSpecifiers::Specifier Parser::isCXX0XVirtSpecifier() const {
+VirtSpecifiers::Specifier Parser::isCXX0XVirtSpecifier(const Token &Tok) const {
   if (!getLang().CPlusPlus)
     return VirtSpecifiers::VS_None;
 
@@ -1896,6 +1896,7 @@
 
   SmallVector<Decl *, 8> DeclsInGroup;
   ExprResult BitfieldSize;
+  bool ExpectSemi = true;
 
   while (1) {
     // member-declarator:
@@ -2023,7 +2024,18 @@
       break;
 
     // Consume the comma.
-    ConsumeToken();
+    SourceLocation CommaLoc = ConsumeToken();
+
+    if (Tok.isAtStartOfLine() &&
+        !MightBeDeclarator(Declarator::MemberContext)) {
+      // This comma was followed by a line-break and something which can't be
+      // the start of a declarator. The comma was probably a typo for a
+      // semicolon.
+      Diag(CommaLoc, diag::err_expected_semi_declaration)
+        << FixItHint::CreateReplacement(CommaLoc, ";");
+      ExpectSemi = false;
+      break;
+    }
 
     // Parse the next declarator.
     DeclaratorInfo.clear();
@@ -2039,7 +2051,8 @@
       ParseDeclarator(DeclaratorInfo);
   }
 
-  if (ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {
+  if (ExpectSemi &&
+      ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list)) {
     // Skip to end of block or statement.
     SkipUntil(tok::r_brace, true, true);
     // If we stopped at a ';', eat it.

Modified: cfe/trunk/test/FixIt/fixit-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-cxx0x.cpp?rev=147808&r1=147807&r2=147808&view=diff
==============================================================================
--- cfe/trunk/test/FixIt/fixit-cxx0x.cpp (original)
+++ cfe/trunk/test/FixIt/fixit-cxx0x.cpp Mon Jan  9 16:31:44 2012
@@ -22,4 +22,18 @@
   int m {},
   n [[]], // expected-error {{expected ';' at end of declaration}}
   int o;
+
+  struct Base {
+    virtual void f2(), f3();
+  };
+  struct MemberDeclarator : Base {
+    int k : 4,
+        //[[]] : 1, FIXME: test this once we support attributes here
+        : 9, // expected-error {{expected ';' at end of declaration}}
+    char c, // expected-error {{expected ';' at end of declaration}}
+    typedef void F(), // expected-error {{expected ';' at end of declaration}}
+    F f1,
+      f2 final,
+      f3 override, // expected-error {{expected ';' at end of declaration}}
+  };
 }

Modified: cfe/trunk/test/FixIt/fixit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit.cpp?rev=147808&r1=147807&r2=147808&view=diff
==============================================================================
--- cfe/trunk/test/FixIt/fixit.cpp (original)
+++ cfe/trunk/test/FixIt/fixit.cpp Mon Jan  9 16:31:44 2012
@@ -125,6 +125,19 @@
   AD ad, // expected-error {{expected ';' at end of declaration}}
   return ad;
 }
+struct MoreAccidentalCommas {
+  int a : 5,
+      b : 7,
+        : 4, // expected-error {{expected ';' at end of declaration}}
+  char c, // expected-error {{expected ';' at end of declaration}}
+  double d, // expected-error {{expected ';' at end of declaration}}
+  MoreAccidentalCommas *next, // expected-error {{expected ';' at end of declaration}}
+public:
+  int k, // expected-error {{expected ';' at end of declaration}}
+  friend void f(MoreAccidentalCommas) {}
+  int k2, // expected-error {{expected ';' at end of declaration}}
+  virtual void g(), // expected-error {{expected ';' at end of declaration}}
+};
 
 template<class T> struct Mystery;
 template<class T> typedef Mystery<T>::type getMysteriousThing() { // \





More information about the cfe-commits mailing list