Re: [clang] b7ce85a - [Concepts] Fix isDeclarationSpecifier to detect type-constraints correctly

2020-01-31 Thread Richard Smith via cfe-commits
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 auto b,
> - ns::D auto c,
> - ns::D auto d,
> - const C auto e,
> - const C auto f,
> - const ns::D auto g,
> - const ns::D auto h);
> \ No newline at end of file
> +void foo1(C auto a,
> +  C auto b,
> +  ns::D auto c,
> +  ns::D auto d,
> +  const C auto e,
> +  const C auto f,
> +  const ns::D auto g,
> +  const ns::D auto h);
> +void foo2(C auto a);
> +void foo3(C auto b);
> +void foo4(ns::D auto c);
> +void foo5(ns::D auto d);
> +void foo6(const C auto e);
> +void foo7(const C auto f);
> +void foo8(const ns::D auto g);
> +void foo9(const ns::D auto h);
> +
> +struct S1 { S1(C auto a,
> +   C auto b,
> +   ns::D auto c,
> +   ns::D auto d,
> +   const C auto e,
> +   const C auto f,
> +   const ns::D auto g,
> +   const ns::D auto h); };
> +struct S2 { S2(C auto a); };
> +struct S3 { S3(C auto b); };
> +struct S4 { S4(ns::D auto c); };
> +struct S5 { S5(ns::D auto d); };
> +struct S6 { S6(const C auto e); };
> +struct S7 { S7(const C auto f); };
> +struct S8 { S8(const ns::D auto g); };
> +struct S9 { S9(const ns::D 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


[clang] b7ce85a - [Concepts] Fix isDeclarationSpecifier to detect type-constraints correctly

2020-01-31 Thread Saar Raz via cfe-commits

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 auto b,
- ns::D auto c,
- ns::D auto d,
- const C auto e,
- const C auto f,
- const ns::D auto g,
- const ns::D auto h);
\ No newline at end of file
+void foo1(C auto a,
+  C auto b,
+  ns::D auto c,
+  ns::D auto d,
+  const C auto e,
+  const C auto f,
+  const ns::D auto g,
+  const ns::D auto h);
+void foo2(C auto a);
+void foo3(C auto b);
+void foo4(ns::D auto c);
+void foo5(ns::D auto d);
+void foo6(const C auto e);
+void foo7(const C auto f);
+void foo8(const ns::D auto g);
+void foo9(const ns::D auto h);
+
+struct S1 { S1(C auto a,
+   C auto b,
+   ns::D auto c,
+   ns::D auto d,
+   const C auto e,
+   const C auto f,
+   const ns::D auto g,
+   const ns::D auto h); };
+struct S2 { S2(C auto a); };
+struct S3 { S3(C auto b); };
+struct S4 { S4(ns::D auto c); };
+struct S5 { S5(ns::D auto d); };
+struct S6 { S6(const C auto e); };
+struct S7 { S7(const C auto f); };
+struct S8 { S8(const ns::D auto g); };
+struct S9 { S9(const ns::D 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