]> granicus.if.org Git - clang/commitdiff
Fix a little bug in the handling of enumeration types with a fixed
authorDouglas Gregor <dgregor@apple.com>
Tue, 22 Feb 2011 02:55:24 +0000 (02:55 +0000)
committerDouglas Gregor <dgregor@apple.com>
Tue, 22 Feb 2011 02:55:24 +0000 (02:55 +0000)
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

include/clang/Basic/DiagnosticParseKinds.td
lib/Parse/ParseDecl.cpp
test/SemaCXX/enum-scoped.cpp

index 9d7ec9d4544723316ad300612459e143089366fc..fd64e90d739dc06e744d5c84c10c174936e5d1b2 100644 (file)
@@ -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<GNU>;
index 37d152ed9d8889583e70e9fd690c8f24b932417b..d9c5069f5988a500176aeecc709067795fefef6d 100644 (file)
@@ -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;
index 7fdcf0d573a9463382c15e00e036494352122146..cf579e180f6964d1103f0b19141ab0b2ac6ce96f 100644 (file)
@@ -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}}