On Fri, 31 Jan 2020, 10:08 Saar Raz via cfe-commits, < cfe-commits@lists.llvm.org> wrote:
> > 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; > Our behaviour here (on invalid code) depends on whether we've already annotated the type constraint (if not, we don't require the next token to be auto/decltype). It'd be good to be consistent here. Incidentally, if we see any kind of (possibly-qualified) identifier or template-id followed by auto/decltype, I think we should classify it as a decl-specifier to improve error recovery when there's a typo in a concept name. + 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 >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits