diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index 155d333fa84c7a7b5ac7198b02a48cad319417e6..d7ae24960c1036a21b0c698f0cab24ace82b4266 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -240,27 +240,6 @@ Parser::ParseSingleDeclarationAfterTemplate( if (DeclaratorInfo.isFunctionDeclarator()) MaybeParseGNUAttributes(DeclaratorInfo, &LateParsedAttrs); - // If we have a declaration or declarator list, handle it. - if (isDeclarationAfterDeclarator()) { - // Parse this declaration. - Decl *ThisDecl = ParseDeclarationAfterDeclarator(DeclaratorInfo, - TemplateInfo); - - if (Tok.is(tok::comma)) { - Diag(Tok, diag::err_multiple_template_declarators) - << (int)TemplateInfo.Kind; - SkipUntil(tok::semi, true, false); - return ThisDecl; - } - - // Eat the semi colon after the declaration. - ExpectAndConsumeSemi(diag::err_expected_semi_declaration); - if (LateParsedAttrs.size() > 0) - ParseLexedAttributeList(LateParsedAttrs, ThisDecl, true, false); - DeclaratorInfo.complete(ThisDecl); - return ThisDecl; - } - if (DeclaratorInfo.isFunctionDeclarator() && isStartOfFunctionDefinition(DeclaratorInfo)) { if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef) { @@ -275,12 +254,23 @@ Parser::ParseSingleDeclarationAfterTemplate( &LateParsedAttrs); } - if (DeclaratorInfo.isFunctionDeclarator()) - Diag(Tok, diag::err_expected_fn_body); - else - Diag(Tok, diag::err_invalid_token_after_toplevel_declarator); - SkipUntil(tok::semi); - return 0; + // Parse this declaration. + Decl *ThisDecl = ParseDeclarationAfterDeclarator(DeclaratorInfo, + TemplateInfo); + + if (Tok.is(tok::comma)) { + Diag(Tok, diag::err_multiple_template_declarators) + << (int)TemplateInfo.Kind; + SkipUntil(tok::semi, true, false); + return ThisDecl; + } + + // Eat the semi colon after the declaration. + ExpectAndConsumeSemi(diag::err_expected_semi_declaration); + if (LateParsedAttrs.size() > 0) + ParseLexedAttributeList(LateParsedAttrs, ThisDecl, true, false); + DeclaratorInfo.complete(ThisDecl); + return ThisDecl; } /// ParseTemplateParameters - Parses a template-parameter-list enclosed in diff --git a/test/Parser/cxx11-brace-initializers.cpp b/test/Parser/cxx11-brace-initializers.cpp index a2102056bc1af2f965f0c8ba6634f6c6807ecf13..7926320fd021eaac0257fea14215cf490f456892 100644 --- a/test/Parser/cxx11-brace-initializers.cpp +++ b/test/Parser/cxx11-brace-initializers.cpp @@ -14,3 +14,14 @@ void test1() f(0, {1, 1}, 0); } + +namespace PR14948 { + template<typename T> struct Q { static T x; }; + + struct X {}; + template<> X Q<X>::x {}; + template<> int Q<int[]>::x[] { 1, 2, 3 }; + template<> int Q<int>::x { 1 }; + + template<typename T> T Q<T>::x {}; +}