diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 5a657dea9b..2a6a0494e5 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -1,4 +1,3 @@ - //===--- ParseDecl.cpp - Declaration Parsing ------------------------------===// // // The LLVM Compiler Infrastructure @@ -1545,8 +1544,11 @@ ParseStructDeclaration(DeclSpec &DS, FieldCallback &Fields) { /// struct-declarator: declarator /// struct-declarator: declarator[opt] ':' constant-expression - if (Tok.isNot(tok::colon)) + if (Tok.isNot(tok::colon)) { + // Don't parse FOO:BAR as if it were a typo for FOO::BAR. + ColonProtectionRAIIObject X(*this); ParseDeclarator(DeclaratorInfo.D); + } if (Tok.is(tok::colon)) { ConsumeToken(); diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index d9c8d7da76..34ea9c7d9b 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -1090,11 +1090,13 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, return ParseCXXClassMemberDeclaration(AS, TemplateInfo); } + // Don't parse FOO:BAR as if it were a typo for FOO::BAR. + ColonProtectionRAIIObject X(*this); + CXX0XAttributeList AttrList; // Optional C++0x attribute-specifier - if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) { + if (getLang().CPlusPlus0x && isCXX0XAttributeSpecifier()) AttrList = ParseCXX0XAttributes(); - } if (Tok.is(tok::kw_using)) { // FIXME: Check for template aliases @@ -1138,6 +1140,9 @@ void Parser::ParseCXXClassMemberDeclaration(AccessSpecifier AS, ParsingDeclarator DeclaratorInfo(*this, DS, Declarator::MemberContext); if (Tok.isNot(tok::colon)) { + // Don't parse FOO:BAR as if it were a typo for FOO::BAR. + ColonProtectionRAIIObject X(*this); + // Parse the first declarator. ParseDeclarator(DeclaratorInfo); // Error parsing the declarator? diff --git a/test/Parser/cxx-decl.cpp b/test/Parser/cxx-decl.cpp index 308700e50d..4453c4c3d0 100644 --- a/test/Parser/cxx-decl.cpp +++ b/test/Parser/cxx-decl.cpp @@ -2,6 +2,8 @@ int x(*g); // expected-error {{use of undeclared identifier 'g'}} +struct Type { }; + // PR4451 - We should recover well from the typo of '::' as ':' in a2. namespace y { @@ -31,3 +33,10 @@ class someclass { return 1 ? P->x : P->y; } }; + +enum { fooenum = 1 }; + +struct a { + int Type : fooenum; +}; +