From: Douglas Gregor Date: Tue, 22 Feb 2011 02:55:24 +0000 (+0000) Subject: Fix a little bug in the handling of enumeration types with a fixed X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b9075601840893a8f7a21918ac4c7e28dcb67f1a;p=clang Fix a little bug in the handling of enumeration types with a fixed underlying type: we weren't parsing unnamed enumeration types with a fixed underlying type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126184 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 9d7ec9d454..fd64e90d73 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -57,6 +57,8 @@ def ext_enumerator_list_comma : Extension< "feature">; def err_enumerator_list_missing_comma : Error< "missing ',' between enumerators">; +def err_enumerator_unnamed_no_def : Error< + "unnamed enumeration must be a definition">; def ext_gnu_indirect_goto : Extension< "use of GNU indirect-goto extension">, InGroup; diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 37d152ed9d..d9c5069f59 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -1975,6 +1975,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, } } + bool AllowFixedUnderlyingType = getLang().CPlusPlus0x; bool IsScopedEnum = false; bool IsScopedUsingClassTag = false; @@ -1986,7 +1987,8 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, } // Must have either 'enum name' or 'enum {...}'. - if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace)) { + if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) && + (AllowFixedUnderlyingType && Tok.isNot(tok::colon))) { Diag(Tok, diag::err_expected_ident_lbrace); // Skip the rest of this declarator, up until the comma or semicolon. @@ -2013,7 +2015,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, TypeResult BaseType; // Parse the fixed underlying type. - if (getLang().CPlusPlus0x && Tok.is(tok::colon)) { + if (AllowFixedUnderlyingType && Tok.is(tok::colon)) { bool PossibleBitfield = false; if (getCurScope()->getFlags() & Scope::ClassScope) { // If we're in class scope, this can either be an enum declaration with @@ -2092,6 +2094,14 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS, return; } + if (!Name && TUK != Sema::TUK_Definition) { + Diag(Tok, diag::err_enumerator_unnamed_no_def); + + // Skip the rest of this declarator, up until the comma or semicolon. + SkipUntil(tok::comma, true); + return; + } + bool Owned = false; bool IsDependent = false; SourceLocation TSTLoc = NameLoc.isValid()? NameLoc : StartLoc; diff --git a/test/SemaCXX/enum-scoped.cpp b/test/SemaCXX/enum-scoped.cpp index 7fdcf0d573..cf579e180f 100644 --- a/test/SemaCXX/enum-scoped.cpp +++ b/test/SemaCXX/enum-scoped.cpp @@ -96,3 +96,10 @@ enum Redeclare6 : short; // expected-error{{redeclared with different underlying enum class Redeclare7; // expected-note{{previous use is here}} expected-note{{previous use is here}} enum class Redeclare7 : short; // expected-error{{redeclared with different underlying type}} enum class Redeclare7 : short; // expected-error{{redeclared with different underlying type}} + +enum : long { + long_enum_val = 10000 +}; + +enum : long x; // expected-error{{unnamed enumeration must be a definition}} \ +// expected-warning{{declaration does not declare anything}}