Fix five more cases of tokens which can legally follow a type specifier.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172886 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Richard Smith 2013-01-19 03:48:05 +00:00
Родитель dc1088f620
Коммит ba65f505b7
3 изменённых файлов: 51 добавлений и 3 удалений

Просмотреть файл

@ -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;
}

Просмотреть файл

@ -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

Просмотреть файл

@ -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;
}