]> granicus.if.org Git - clang/commitdiff
Properly protect colons when parsing a nested-name-specifier as part
authorJohn McCall <rjmccall@apple.com>
Wed, 6 Jul 2011 05:58:41 +0000 (05:58 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 6 Jul 2011 05:58:41 +0000 (05:58 +0000)
of an enum specifier in dialects which permit fixed underlying types.
Fixes the rejects-valid part of PR10264.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@134468 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseDecl.cpp
test/SemaCXX/enum-scoped.cpp

index 022fe3615789b944e6444e9514621440b4a4b86d..f2588c875f44cc21484f6b0a3ea45c3ee69aa748 100644 (file)
@@ -2450,13 +2450,29 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
     Actions.CodeCompleteTag(getCurScope(), DeclSpec::TST_enum);
     ConsumeCodeCompletionToken();
   }
+
+  bool IsScopedEnum = false;
+  bool IsScopedUsingClassTag = false;
+
+  if (getLang().CPlusPlus0x &&
+      (Tok.is(tok::kw_class) || Tok.is(tok::kw_struct))) {
+    IsScopedEnum = true;
+    IsScopedUsingClassTag = Tok.is(tok::kw_class);
+    ConsumeToken();
+  }
   
   // If attributes exist after tag, parse them.
   ParsedAttributes attrs(AttrFactory);
   MaybeParseGNUAttributes(attrs);
 
+  bool AllowFixedUnderlyingType = getLang().CPlusPlus0x || getLang().Microsoft;
+
   CXXScopeSpec &SS = DS.getTypeSpecScope();
   if (getLang().CPlusPlus) {
+    // "enum foo : bar;" is not a potential typo for "enum foo::bar;"
+    // if a fixed underlying type is allowed.
+    ColonProtectionRAIIObject X(*this, AllowFixedUnderlyingType);
+    
     if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(), false))
       return;
 
@@ -2471,17 +2487,6 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
     }
   }
 
-  bool AllowFixedUnderlyingType = getLang().CPlusPlus0x || getLang().Microsoft;
-  bool IsScopedEnum = false;
-  bool IsScopedUsingClassTag = false;
-
-  if (getLang().CPlusPlus0x &&
-      (Tok.is(tok::kw_class) || Tok.is(tok::kw_struct))) {
-    IsScopedEnum = true;
-    IsScopedUsingClassTag = Tok.is(tok::kw_class);
-    ConsumeToken();
-  }
-
   // Must have either 'enum name' or 'enum {...}'.
   if (Tok.isNot(tok::identifier) && Tok.isNot(tok::l_brace) &&
       (AllowFixedUnderlyingType && Tok.isNot(tok::colon))) {
index fc871cf379206dcc45626c3efb517388eb00bc78..2c3537e163fde980bc99cff00d17bea9f4df5c95 100644 (file)
@@ -119,3 +119,14 @@ namespace rdar9366066 {
     x % 8; // expected-error{{invalid operands to binary expression ('rdar9366066::X' and 'int')}}
   }
 }
+
+// Part of PR10264
+namespace test5 {
+  namespace ns {
+    typedef unsigned Atype;
+    enum A : Atype;
+  }
+  enum ns::A : ns::Atype {
+    x, y, z
+  };
+}