Author: Saar Raz Date: 2020-01-31T20:08:13+02:00 New Revision: b7ce85a130789d23c69156f4b899962458d1f05d
URL: https://github.com/llvm/llvm-project/commit/b7ce85a130789d23c69156f4b899962458d1f05d DIFF: https://github.com/llvm/llvm-project/commit/b7ce85a130789d23c69156f4b899962458d1f05d.diff LOG: [Concepts] Fix isDeclarationSpecifier to detect type-constraints correctly isDeclarationSpecifiers did not handle some cases of placeholder-type-specifiers with type-constraints, causing parsing bugs in abbreviated constructor templates. Add comprehensive handling of type-constraints to isDeclarationSpecifier. Added: Modified: clang/lib/Parse/ParseDecl.cpp clang/test/Parser/cxx2a-abbreviated-templates.cpp Removed: ################################################################################ diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 871ca2512598..af6e105ca61f 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -5061,6 +5061,8 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { // recurse to handle whatever we get. if (TryAnnotateTypeOrScopeToken()) return true; + if (TryAnnotateTypeConstraint()) + return true; if (Tok.is(tok::identifier)) return false; @@ -5193,11 +5195,14 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) { // placeholder-type-specifier case tok::annot_template_id: { - TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok); - return TemplateId->Kind == TNK_Concept_template && + return isTypeConstraintAnnotation() && (NextToken().is(tok::kw_auto) || NextToken().is(tok::kw_decltype)); } - + case tok::annot_cxxscope: + if (NextToken().is(tok::identifier) && TryAnnotateTypeConstraint()) + return true; + return isTypeConstraintAnnotation() && + GetLookAheadToken(2).isOneOf(tok::kw_auto, tok::kw_decltype); case tok::kw___declspec: case tok::kw___cdecl: case tok::kw___stdcall: diff --git a/clang/test/Parser/cxx2a-abbreviated-templates.cpp b/clang/test/Parser/cxx2a-abbreviated-templates.cpp index e2b3803c807e..6562389f7676 100644 --- a/clang/test/Parser/cxx2a-abbreviated-templates.cpp +++ b/clang/test/Parser/cxx2a-abbreviated-templates.cpp @@ -9,11 +9,36 @@ namespace ns { concept D = true; } -void foo(C auto a, - C<int> auto b, - ns::D auto c, - ns::D<int> auto d, - const C auto e, - const C<int> auto f, - const ns::D auto g, - const ns::D<int> auto h); \ No newline at end of file +void foo1(C auto a, + C<int> auto b, + ns::D auto c, + ns::D<int> auto d, + const C auto e, + const C<int> auto f, + const ns::D auto g, + const ns::D<int> auto h); +void foo2(C auto a); +void foo3(C<int> auto b); +void foo4(ns::D auto c); +void foo5(ns::D<int> auto d); +void foo6(const C auto e); +void foo7(const C<int> auto f); +void foo8(const ns::D auto g); +void foo9(const ns::D<int> auto h); + +struct S1 { S1(C auto a, + C<int> auto b, + ns::D auto c, + ns::D<int> auto d, + const C auto e, + const C<int> auto f, + const ns::D auto g, + const ns::D<int> auto h); }; +struct S2 { S2(C auto a); }; +struct S3 { S3(C<int> auto b); }; +struct S4 { S4(ns::D auto c); }; +struct S5 { S5(ns::D<int> auto d); }; +struct S6 { S6(const C auto e); }; +struct S7 { S7(const C<int> auto f); }; +struct S8 { S8(const ns::D auto g); }; +struct S9 { S9(const ns::D<int> auto h); }; \ No newline at end of file _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits