[cfe-commits] r159549 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseDecl.cpp lib/Parse/ParseDeclCXX.cpp test/Parser/declarators.c
Richard Smith
richard-llvm at metafoo.co.uk
Mon Jul 2 12:14:01 PDT 2012
Author: rsmith
Date: Mon Jul 2 14:14:01 2012
New Revision: 159549
URL: http://llvm.org/viewvc/llvm-project?rev=159549&view=rev
Log:
A ':' after an enum-specifier at class scope is a bitfield, not a typo for a ';'.
Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/test/Parser/declarators.c
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=159549&r1=159548&r2=159549&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon Jul 2 14:14:01 2012
@@ -1949,7 +1949,7 @@
//===--------------------------------------------------------------------===//
// C++ 9: classes [class] and C structs/unions.
- bool isValidAfterTypeSpecifier();
+ bool isValidAfterTypeSpecifier(bool CouldBeBitfield);
void ParseClassSpecifier(tok::TokenKind TagTokKind, SourceLocation TagLoc,
DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo,
AccessSpecifier AS, bool EnteringContext,
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=159549&r1=159548&r2=159549&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Jul 2 14:14:01 2012
@@ -3067,9 +3067,10 @@
TypeResult BaseType;
// Parse the fixed underlying type.
+ bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
if (AllowFixedUnderlyingType && Tok.is(tok::colon)) {
bool PossibleBitfield = false;
- if (getCurScope()->getFlags() & Scope::ClassScope) {
+ if (CanBeBitfield) {
// If we're in class scope, this can either be an enum declaration with
// an underlying type, or a declaration of a bitfield member. We try to
// use a simple disambiguation scheme first to catch the common cases
@@ -3158,7 +3159,8 @@
}
} else if (DSC != DSC_type_specifier &&
(Tok.is(tok::semi) ||
- (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier()))) {
+ (Tok.isAtStartOfLine() &&
+ !isValidAfterTypeSpecifier(CanBeBitfield)))) {
TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
if (Tok.isNot(tok::semi)) {
// A semicolon was missing after this declaration. Diagnose and recover.
@@ -3366,7 +3368,8 @@
// The next token must be valid after an enum definition. If not, a ';'
// was probably forgotten.
- if (!isValidAfterTypeSpecifier()) {
+ bool CanBeBitfield = getCurScope()->getFlags() & Scope::ClassScope;
+ if (!isValidAfterTypeSpecifier(CanBeBitfield)) {
ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl, "enum");
// Push this token back into the preprocessor and change our current token
// to ';' so that the rest of the code recovers as though there were an
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=159549&r1=159548&r2=159549&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Mon Jul 2 14:14:01 2012
@@ -929,7 +929,7 @@
/// Determine whether the following tokens are valid after a type-specifier
/// which could be a standalone declaration. This will conservatively return
/// true if there's any doubt, and is appropriate for insert-';' fixits.
-bool Parser::isValidAfterTypeSpecifier() {
+bool Parser::isValidAfterTypeSpecifier(bool CouldBeBitfield) {
// This switch enumerates the valid "follow" set for type-specifiers.
switch (Tok.getKind()) {
default: break;
@@ -944,6 +944,8 @@
case tok::l_paren: // struct foo {...} ( x);
case tok::comma: // __builtin_offsetof(struct foo{...} ,
return true;
+ case tok::colon:
+ return CouldBeBitfield; // enum E { ... } : 2;
// Type qualifiers
case tok::kw_const: // struct foo {...} const x;
case tok::kw_volatile: // struct foo {...} volatile x;
@@ -1236,7 +1238,7 @@
}
} else if (DSC != DSC_type_specifier &&
(Tok.is(tok::semi) ||
- (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier()))) {
+ (Tok.isAtStartOfLine() && !isValidAfterTypeSpecifier(false)))) {
TUK = DS.isFriendSpecified() ? Sema::TUK_Friend : Sema::TUK_Declaration;
if (Tok.isNot(tok::semi)) {
// A semicolon was missing after this declaration. Diagnose and recover.
@@ -1466,7 +1468,7 @@
// In a template-declaration which defines a class, no declarator
// is permitted.
if (TUK == Sema::TUK_Definition &&
- (TemplateInfo.Kind || !isValidAfterTypeSpecifier())) {
+ (TemplateInfo.Kind || !isValidAfterTypeSpecifier(false))) {
ExpectAndConsume(tok::semi, diag::err_expected_semi_after_tagdecl,
TagType == DeclSpec::TST_class ? "class" :
TagType == DeclSpec::TST_struct ? "struct" : "union");
Modified: cfe/trunk/test/Parser/declarators.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/declarators.c?rev=159549&r1=159548&r2=159549&view=diff
==============================================================================
--- cfe/trunk/test/Parser/declarators.c (original)
+++ cfe/trunk/test/Parser/declarators.c Mon Jul 2 14:14:01 2012
@@ -107,3 +107,8 @@
int x = 4+(5-12)); // expected-error {{extraneous ')' before ';'}}
}
+enum E1 { e1 }: // expected-error {{expected ';'}}
+struct EnumBitfield {
+ enum E2 { e2 } : 4; // ok
+ struct S { int n; }: // expected-error {{expected ';'}}
+};
More information about the cfe-commits
mailing list