]> granicus.if.org Git - clang/commitdiff
Fix five more cases of tokens which can legally follow a type specifier.
authorRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 19 Jan 2013 03:48:05 +0000 (03:48 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 19 Jan 2013 03:48:05 +0000 (03:48 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172886 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseDeclCXX.cpp
test/Parser/cxx-decl.cpp
test/Parser/cxx0x-decl.cpp

index 9aa3a8b2afcf3769a34882c2d22162b65d25beb5..2c5d142fd7fb9d97980ee6bed3ba75dde994b343 100644 (file)
@@ -957,6 +957,7 @@ bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {
   case tok::semi:               // struct foo {...} ;
   case tok::star:               // struct foo {...} *         P;
   case tok::amp:                // struct foo {...} &         R = ...
+  case tok::ampamp:             // struct foo {...} &&        R = ...
   case tok::identifier:         // struct foo {...} V         ;
   case tok::r_paren:            //(struct foo {...} )         {4}
   case tok::annot_cxxscope:     // struct foo {...} a::       b;
@@ -964,7 +965,7 @@ bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {
   case tok::annot_template_id:  // struct foo {...} a<int>    ::b;
   case tok::l_paren:            // struct foo {...} (         x);
   case tok::comma:              // __builtin_offsetof(struct foo{...} ,
-  case tok::kw_operator:        // struct foo operator++() {...}
+  case tok::kw_operator:        // struct foo       operator  ++() {...}
     return true;
   case tok::colon:
     return CouldBeBitfield;     // enum E { ... }   :         2;
@@ -972,7 +973,12 @@ bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {
   case tok::kw_const:           // struct foo {...} const     x;
   case tok::kw_volatile:        // struct foo {...} volatile  x;
   case tok::kw_restrict:        // struct foo {...} restrict  x;
-  case tok::kw_inline:          // struct foo {...} inline    foo() {};
+  // Function specifiers
+  // Note, no 'explicit'. An explicit function must be either a conversion
+  // operator or a constructor. Either way, it can't have a return type.
+  case tok::kw_inline:          // struct foo       inline    f();
+  case tok::kw_virtual:         // struct foo       virtual   f();
+  case tok::kw_friend:          // struct foo       friend    f();
   // Storage-class specifiers
   case tok::kw_static:          // struct foo {...} static    x;
   case tok::kw_extern:          // struct foo {...} extern    x;
@@ -980,6 +986,7 @@ bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {
   case tok::kw_register:        // struct foo {...} register  x;
   case tok::kw_auto:            // struct foo {...} auto      x;
   case tok::kw_mutable:         // struct foo {...} mutable   x;
+  case tok::kw_thread_local:    // struct foo {...} thread_local x;
   case tok::kw_constexpr:       // struct foo {...} constexpr x;
     // As shown above, type qualifiers and storage class specifiers absolutely
     // can occur after class specifiers according to the grammar.  However,
@@ -1004,6 +1011,10 @@ bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {
     if (!getLangOpts().CPlusPlus)
       return true;
     break;
+    // C++11 attributes
+  case tok::l_square: // enum E [[]] x
+    // Note, no tok::kw_alignas here; alignas cannot appertain to a type.
+    return getLangOpts().CPlusPlus11 && NextToken().is(tok::l_square);
   }
   return false;
 }
index aa775c8c76274569af6d57e563e65c9866173833..ee292fdae0f7da85846edb5f9655e2268c9f2814 100644 (file)
@@ -134,7 +134,7 @@ struct S {
 
 
 namespace TestIsValidAfterTypeSpecifier {
-struct s {};
+struct s {} v;
 
 namespace a {
 struct s operator++(struct s a)
@@ -148,6 +148,18 @@ operator++(struct s a)
 { return a; }
 }
 
+struct X {
+  struct s
+  friend f();
+  struct s
+  virtual f();
+};
+
+struct s
+&r0 = v;
+struct s
+bitand r2 = v;
+
 }
 
 // PR8380
index 1da7dd28331148b24034261afdd3c99cda6e5410..b9441fd6813cb3e2581aa0b5d5b67ed67904ced4 100644 (file)
@@ -49,3 +49,28 @@ struct ConstexprTrailingReturn {
   constexpr auto f() -> decltype((n));
 };
 constexpr const int &ConstexprTrailingReturn::f() const { return n; }
+
+namespace TestIsValidAfterTypeSpecifier {
+struct s {} v;
+
+// FIXME: We should accept this once we support thread_local.
+struct s
+thread_local tl; // expected-error {{expected unqualified-id}}
+
+struct s
+&r0 = v;
+
+struct s
+&&r1 = s();
+
+struct s
+bitand r2 = v;
+
+struct s
+and r3 = s();
+
+enum E {};
+enum E
+[[]] e;
+
+}