From 57c13008c634f47d8ca1b6aa9d7965d82a05c502 Mon Sep 17 00:00:00 2001 From: John McCall Date: Wed, 6 Jul 2011 05:58:41 +0000 Subject: [PATCH] Properly protect colons when parsing a nested-name-specifier as part 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 | 27 ++++++++++++++++----------- test/SemaCXX/enum-scoped.cpp | 11 +++++++++++ 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 022fe36157..f2588c875f 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -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))) { diff --git a/test/SemaCXX/enum-scoped.cpp b/test/SemaCXX/enum-scoped.cpp index fc871cf379..2c3537e163 100644 --- a/test/SemaCXX/enum-scoped.cpp +++ b/test/SemaCXX/enum-scoped.cpp @@ -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 + }; +} -- 2.40.0