eandrews updated this revision to Diff 527382. eandrews added a comment. Thanks for the review! I added a couple more tests.
CHANGES SINCE LAST ACTION https://reviews.llvm.org/D151837/new/ https://reviews.llvm.org/D151837 Files: clang/lib/Parse/ParseTemplate.cpp clang/test/Parser/attr-order.cpp Index: clang/test/Parser/attr-order.cpp =================================================================== --- clang/test/Parser/attr-order.cpp +++ clang/test/Parser/attr-order.cpp @@ -13,12 +13,21 @@ [[noreturn]] __declspec(dllexport) __attribute__((cdecl)) void b(); // ok [[]] [[noreturn]] __attribute__((cdecl)) __declspec(dllexport) void c(); // ok -// [[]] attributes before a declaration must be at the start of the line. __declspec(dllexport) [[noreturn]] __attribute__((cdecl)) void d(); // expected-error {{an attribute list cannot appear here}} __declspec(dllexport) __attribute__((cdecl)) [[noreturn]] void e(); // expected-error {{an attribute list cannot appear here}} __attribute__((cdecl)) __declspec(dllexport) [[noreturn]] void f(); // expected-error {{an attribute list cannot appear here}} -__attribute__((cdecl)) [[noreturn]] __declspec(dllexport) void g(); + +__attribute__((cdecl)) [[noreturn]] __declspec(dllexport) void g(); // ok [[noreturn]] __attribute__((cdecl)) [[]] __declspec(dllexport) void h(); + +template <int a> +__attribute__((cdecl)) [[noreturn]] __declspec(dllexport) void i(); // ok + +template <int a> +[[]] [[noreturn]] __attribute__((cdecl)) __declspec(dllexport) void j(); // ok + +template <int a> +[[noreturn]] __declspec(dllexport) __attribute__((cdecl)) void k(); // ok Index: clang/lib/Parse/ParseTemplate.cpp =================================================================== --- clang/lib/Parse/ParseTemplate.cpp +++ clang/lib/Parse/ParseTemplate.cpp @@ -210,7 +210,15 @@ } ParsedAttributes prefixAttrs(AttrFactory); - MaybeParseCXX11Attributes(prefixAttrs); + ParsedAttributes DeclSpecAttrs(AttrFactory); + + // GNU attributes are applied to the declaration specification while the + // standard attributes are applied to the declaration. We parse the two + // attribute sets into different containters so we can apply them during + // the regular parsing process. + while (MaybeParseCXX11Attributes(prefixAttrs) || + MaybeParseGNUAttributes(DeclSpecAttrs)) + ; if (Tok.is(tok::kw_using)) { auto usingDeclPtr = ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd, @@ -223,6 +231,9 @@ // Parse the declaration specifiers, stealing any diagnostics from // the template parameters. ParsingDeclSpec DS(*this, &DiagsFromTParams); + DS.SetRangeStart(DeclSpecAttrs.Range.getBegin()); + DS.SetRangeEnd(DeclSpecAttrs.Range.getEnd()); + DS.takeAttributesFrom(DeclSpecAttrs); ParseDeclarationSpecifiers(DS, TemplateInfo, AS, getDeclSpecContextFromDeclaratorContext(Context));
Index: clang/test/Parser/attr-order.cpp =================================================================== --- clang/test/Parser/attr-order.cpp +++ clang/test/Parser/attr-order.cpp @@ -13,12 +13,21 @@ [[noreturn]] __declspec(dllexport) __attribute__((cdecl)) void b(); // ok [[]] [[noreturn]] __attribute__((cdecl)) __declspec(dllexport) void c(); // ok -// [[]] attributes before a declaration must be at the start of the line. __declspec(dllexport) [[noreturn]] __attribute__((cdecl)) void d(); // expected-error {{an attribute list cannot appear here}} __declspec(dllexport) __attribute__((cdecl)) [[noreturn]] void e(); // expected-error {{an attribute list cannot appear here}} __attribute__((cdecl)) __declspec(dllexport) [[noreturn]] void f(); // expected-error {{an attribute list cannot appear here}} -__attribute__((cdecl)) [[noreturn]] __declspec(dllexport) void g(); + +__attribute__((cdecl)) [[noreturn]] __declspec(dllexport) void g(); // ok [[noreturn]] __attribute__((cdecl)) [[]] __declspec(dllexport) void h(); + +template <int a> +__attribute__((cdecl)) [[noreturn]] __declspec(dllexport) void i(); // ok + +template <int a> +[[]] [[noreturn]] __attribute__((cdecl)) __declspec(dllexport) void j(); // ok + +template <int a> +[[noreturn]] __declspec(dllexport) __attribute__((cdecl)) void k(); // ok Index: clang/lib/Parse/ParseTemplate.cpp =================================================================== --- clang/lib/Parse/ParseTemplate.cpp +++ clang/lib/Parse/ParseTemplate.cpp @@ -210,7 +210,15 @@ } ParsedAttributes prefixAttrs(AttrFactory); - MaybeParseCXX11Attributes(prefixAttrs); + ParsedAttributes DeclSpecAttrs(AttrFactory); + + // GNU attributes are applied to the declaration specification while the + // standard attributes are applied to the declaration. We parse the two + // attribute sets into different containters so we can apply them during + // the regular parsing process. + while (MaybeParseCXX11Attributes(prefixAttrs) || + MaybeParseGNUAttributes(DeclSpecAttrs)) + ; if (Tok.is(tok::kw_using)) { auto usingDeclPtr = ParseUsingDirectiveOrDeclaration(Context, TemplateInfo, DeclEnd, @@ -223,6 +231,9 @@ // Parse the declaration specifiers, stealing any diagnostics from // the template parameters. ParsingDeclSpec DS(*this, &DiagsFromTParams); + DS.SetRangeStart(DeclSpecAttrs.Range.getBegin()); + DS.SetRangeEnd(DeclSpecAttrs.Range.getEnd()); + DS.takeAttributesFrom(DeclSpecAttrs); ParseDeclarationSpecifiers(DS, TemplateInfo, AS, getDeclSpecContextFromDeclaratorContext(Context));
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits