[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-26 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

Still need release notes!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-26 Thread Liming Liu via Phabricator via cfe-commits
lime updated this revision to Diff 470779.
lime added a comment.

The previous update for conflicts lacks a comma, and the comma was added.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Sema/SemaConcept.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
  clang/test/SemaTemplate/concepts.cpp
  clang/www/cxx_status.html
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D134128
Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -912,11 +912,7 @@
 

 https://wg21.link/p0857r0;>P0857R0
-
-  Partial
-Constraining template template parameters is not yet supported.
-  
-
+Clang 16
   

 https://wg21.link/p1084r2;>P1084R2
Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -61,9 +61,9 @@
 
   // FIXME: This is valid under P0857R0.
   template concept C = true;
-  template requires C typename U> struct X {}; // expected-error {{requires 'class'}} expected-error 0+{{}}
+  template requires C typename U> struct X {};
   template requires C struct Y {};
-  X xy; // expected-error {{no template named 'X'}}
+  X xy;
 }
 
 namespace PR50306 {
Index: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
===
--- clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
+++ clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
@@ -1,22 +1,27 @@
 // RUN:  %clang_cc1 -std=c++2a -frelaxed-template-template-args -verify %s
 
-template concept C = T::f();
-// expected-note@-1{{similar constraint}}
+template concept C = T::f(); // #C
 template concept D = C && T::g();
-template concept F = T::f();
-// expected-note@-1{{similar constraint expressions not considered equivalent}}
-template class P> struct S1 { }; // expected-note 2{{'P' declared here}}
+template concept F = T::f(); // #F
+template class P> struct S1 { }; // #S1
 
 template struct X { };
 
-template struct Y { }; // expected-note{{'Y' declared here}}
+template struct Y { }; // #Y
 template struct Z { };
-template struct W { }; // expected-note{{'W' declared here}}
-
+template struct W { }; // #W
 S1 s11;
-S1 s12; // expected-error{{template template argument 'Y' is more constrained than template template parameter 'P'}}
+S1 s12;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
 S1 s13;
-S1 s14; // expected-error{{template template argument 'W' is more constrained than template template parameter 'P'}}
+S1 s14;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+// expected-note@#F 1-2{{similar constraint expressions not considered equivalent}}
+// expected-note@#C 1-2{{similar constraint}}
 
 template class P> struct S2 { };
 
@@ -32,3 +37,25 @@
 
 using s31 = S3;
 using s32 = S3;
+
+template requires C class P> struct S4 { }; // #S4
+
+S4 s41;
+S4 s42;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
+S4 s43;
+S4 s44;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+
+template requires C typename U> struct S5 {
+  template static U V;
+};
+
+struct Nothing {};
+
+// FIXME: Wait the standard to clarify the intent.
+template<> template<> Z S5::V;
Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4098,8 +4098,10 @@
 
 TemplateParameterList *
 Sema::SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner,
-  const MultiLevelTemplateArgumentList ) {
+  const MultiLevelTemplateArgumentList ,
+  bool EvaluateConstraints) {
   

[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-26 Thread Liming Liu via Phabricator via cfe-commits
lime updated this revision to Diff 470746.
lime added a comment.

Solve the conflicts.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Sema/SemaConcept.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
  clang/test/SemaTemplate/concepts.cpp
  clang/www/cxx_status.html
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D134128
Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -912,11 +912,7 @@
 

 https://wg21.link/p0857r0;>P0857R0
-
-  Partial
-Constraining template template parameters is not yet supported.
-  
-
+Clang 16
   

 https://wg21.link/p1084r2;>P1084R2
Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -61,9 +61,9 @@
 
   // FIXME: This is valid under P0857R0.
   template concept C = true;
-  template requires C typename U> struct X {}; // expected-error {{requires 'class'}} expected-error 0+{{}}
+  template requires C typename U> struct X {};
   template requires C struct Y {};
-  X xy; // expected-error {{no template named 'X'}}
+  X xy;
 }
 
 namespace PR50306 {
Index: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
===
--- clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
+++ clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
@@ -1,22 +1,27 @@
 // RUN:  %clang_cc1 -std=c++2a -frelaxed-template-template-args -verify %s
 
-template concept C = T::f();
-// expected-note@-1{{similar constraint}}
+template concept C = T::f(); // #C
 template concept D = C && T::g();
-template concept F = T::f();
-// expected-note@-1{{similar constraint expressions not considered equivalent}}
-template class P> struct S1 { }; // expected-note 2{{'P' declared here}}
+template concept F = T::f(); // #F
+template class P> struct S1 { }; // #S1
 
 template struct X { };
 
-template struct Y { }; // expected-note{{'Y' declared here}}
+template struct Y { }; // #Y
 template struct Z { };
-template struct W { }; // expected-note{{'W' declared here}}
-
+template struct W { }; // #W
 S1 s11;
-S1 s12; // expected-error{{template template argument 'Y' is more constrained than template template parameter 'P'}}
+S1 s12;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
 S1 s13;
-S1 s14; // expected-error{{template template argument 'W' is more constrained than template template parameter 'P'}}
+S1 s14;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+// expected-note@#F 1-2{{similar constraint expressions not considered equivalent}}
+// expected-note@#C 1-2{{similar constraint}}
 
 template class P> struct S2 { };
 
@@ -32,3 +37,25 @@
 
 using s31 = S3;
 using s32 = S3;
+
+template requires C class P> struct S4 { }; // #S4
+
+S4 s41;
+S4 s42;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
+S4 s43;
+S4 s44;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+
+template requires C typename U> struct S5 {
+  template static U V;
+};
+
+struct Nothing {};
+
+// FIXME: Wait the standard to clarify the intent.
+template<> template<> Z S5::V;
Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4098,8 +4098,10 @@
 
 TemplateParameterList *
 Sema::SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner,
-  const MultiLevelTemplateArgumentList ) {
+  const MultiLevelTemplateArgumentList ,
+  bool EvaluateConstraints) {
   TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs);
+  

[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-26 Thread Liming Liu via Phabricator via cfe-commits
lime updated this revision to Diff 470739.
lime added a comment.

Solve the format issue further.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Sema/SemaConcept.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
  clang/test/SemaTemplate/concepts.cpp
  clang/www/cxx_status.html
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D134128
Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -912,11 +912,7 @@
 

 https://wg21.link/p0857r0;>P0857R0
-
-  Partial
-Constraining template template parameters is not yet supported.
-  
-
+Clang 16
   

 https://wg21.link/p1084r2;>P1084R2
Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -61,9 +61,9 @@
 
   // FIXME: This is valid under P0857R0.
   template concept C = true;
-  template requires C typename U> struct X {}; // expected-error {{requires 'class'}} expected-error 0+{{}}
+  template requires C typename U> struct X {};
   template requires C struct Y {};
-  X xy; // expected-error {{no template named 'X'}}
+  X xy;
 }
 
 namespace PR50306 {
Index: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
===
--- clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
+++ clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
@@ -1,22 +1,27 @@
 // RUN:  %clang_cc1 -std=c++2a -frelaxed-template-template-args -verify %s
 
-template concept C = T::f();
-// expected-note@-1{{similar constraint}}
+template concept C = T::f(); // #C
 template concept D = C && T::g();
-template concept F = T::f();
-// expected-note@-1{{similar constraint expressions not considered equivalent}}
-template class P> struct S1 { }; // expected-note 2{{'P' declared here}}
+template concept F = T::f(); // #F
+template class P> struct S1 { }; // #S1
 
 template struct X { };
 
-template struct Y { }; // expected-note{{'Y' declared here}}
+template struct Y { }; // #Y
 template struct Z { };
-template struct W { }; // expected-note{{'W' declared here}}
-
+template struct W { }; // #W
 S1 s11;
-S1 s12; // expected-error{{template template argument 'Y' is more constrained than template template parameter 'P'}}
+S1 s12;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
 S1 s13;
-S1 s14; // expected-error{{template template argument 'W' is more constrained than template template parameter 'P'}}
+S1 s14;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+// expected-note@#F 1-2{{similar constraint expressions not considered equivalent}}
+// expected-note@#C 1-2{{similar constraint}}
 
 template class P> struct S2 { };
 
@@ -32,3 +37,25 @@
 
 using s31 = S3;
 using s32 = S3;
+
+template requires C class P> struct S4 { }; // #S4
+
+S4 s41;
+S4 s42;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
+S4 s43;
+S4 s44;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+
+template requires C typename U> struct S5 {
+  template static U V;
+};
+
+struct Nothing {};
+
+// FIXME: Wait the standard to clarify the intent.
+template<> template<> Z S5::V;
Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4097,8 +4097,10 @@
 
 TemplateParameterList *
 Sema::SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner,
-  const MultiLevelTemplateArgumentList ) {
+  const MultiLevelTemplateArgumentList ,
+  bool EvaluateConstraints) {
   TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs);
+  

[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-25 Thread Liming Liu via Phabricator via cfe-commits
lime updated this revision to Diff 470702.
lime added a comment.

Update for the format check.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Sema/SemaConcept.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
  clang/test/SemaTemplate/concepts.cpp
  clang/www/cxx_status.html
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D134128
Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -912,11 +912,7 @@
 

 https://wg21.link/p0857r0;>P0857R0
-
-  Partial
-Constraining template template parameters is not yet supported.
-  
-
+Clang 16
   

 https://wg21.link/p1084r2;>P1084R2
Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -61,9 +61,9 @@
 
   // FIXME: This is valid under P0857R0.
   template concept C = true;
-  template requires C typename U> struct X {}; // expected-error {{requires 'class'}} expected-error 0+{{}}
+  template requires C typename U> struct X {};
   template requires C struct Y {};
-  X xy; // expected-error {{no template named 'X'}}
+  X xy;
 }
 
 namespace PR50306 {
Index: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
===
--- clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
+++ clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
@@ -1,22 +1,27 @@
 // RUN:  %clang_cc1 -std=c++2a -frelaxed-template-template-args -verify %s
 
-template concept C = T::f();
-// expected-note@-1{{similar constraint}}
+template concept C = T::f(); // #C
 template concept D = C && T::g();
-template concept F = T::f();
-// expected-note@-1{{similar constraint expressions not considered equivalent}}
-template class P> struct S1 { }; // expected-note 2{{'P' declared here}}
+template concept F = T::f(); // #F
+template class P> struct S1 { }; // #S1
 
 template struct X { };
 
-template struct Y { }; // expected-note{{'Y' declared here}}
+template struct Y { }; // #Y
 template struct Z { };
-template struct W { }; // expected-note{{'W' declared here}}
-
+template struct W { }; // #W
 S1 s11;
-S1 s12; // expected-error{{template template argument 'Y' is more constrained than template template parameter 'P'}}
+S1 s12;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
 S1 s13;
-S1 s14; // expected-error{{template template argument 'W' is more constrained than template template parameter 'P'}}
+S1 s14;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+// expected-note@#F 1-2{{similar constraint expressions not considered equivalent}}
+// expected-note@#C 1-2{{similar constraint}}
 
 template class P> struct S2 { };
 
@@ -32,3 +37,25 @@
 
 using s31 = S3;
 using s32 = S3;
+
+template requires C class P> struct S4 { }; // #S4
+
+S4 s41;
+S4 s42;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
+S4 s43;
+S4 s44;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+
+template requires C typename U> struct S5 {
+  template static U V;
+};
+
+struct Nothing {};
+
+// FIXME: Wait the standard to clarify the intent.
+template<> template<> Z S5::V;
Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4097,8 +4097,10 @@
 
 TemplateParameterList *
 Sema::SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner,
-  const MultiLevelTemplateArgumentList ) {
+  const MultiLevelTemplateArgumentList ,
+  bool EvaluateConstraints) {
   TemplateDeclInstantiator Instantiator(*this, Owner, 

[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-25 Thread Liming Liu via Phabricator via cfe-commits
lime updated this revision to Diff 470686.
lime added a comment.

Solve the conflicts, and the issue about `CMakeLists.txt` had been solved by 
upstream.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Sema/SemaConcept.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
  clang/test/SemaTemplate/concepts.cpp
  clang/www/cxx_status.html
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D134128
Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -912,11 +912,7 @@
 

 https://wg21.link/p0857r0;>P0857R0
-
-  Partial
-Constraining template template parameters is not yet supported.
-  
-
+Clang 16
   

 https://wg21.link/p1084r2;>P1084R2
Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -61,9 +61,9 @@
 
   // FIXME: This is valid under P0857R0.
   template concept C = true;
-  template requires C typename U> struct X {}; // expected-error {{requires 'class'}} expected-error 0+{{}}
+  template requires C typename U> struct X {};
   template requires C struct Y {};
-  X xy; // expected-error {{no template named 'X'}}
+  X xy;
 }
 
 namespace PR50306 {
Index: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
===
--- clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
+++ clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
@@ -1,22 +1,27 @@
 // RUN:  %clang_cc1 -std=c++2a -frelaxed-template-template-args -verify %s
 
-template concept C = T::f();
-// expected-note@-1{{similar constraint}}
+template concept C = T::f(); // #C
 template concept D = C && T::g();
-template concept F = T::f();
-// expected-note@-1{{similar constraint expressions not considered equivalent}}
-template class P> struct S1 { }; // expected-note 2{{'P' declared here}}
+template concept F = T::f(); // #F
+template class P> struct S1 { }; // #S1
 
 template struct X { };
 
-template struct Y { }; // expected-note{{'Y' declared here}}
+template struct Y { }; // #Y
 template struct Z { };
-template struct W { }; // expected-note{{'W' declared here}}
-
+template struct W { }; // #W
 S1 s11;
-S1 s12; // expected-error{{template template argument 'Y' is more constrained than template template parameter 'P'}}
+S1 s12;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
 S1 s13;
-S1 s14; // expected-error{{template template argument 'W' is more constrained than template template parameter 'P'}}
+S1 s14;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+// expected-note@#F 1-2{{similar constraint expressions not considered equivalent}}
+// expected-note@#C 1-2{{similar constraint}}
 
 template class P> struct S2 { };
 
@@ -32,3 +37,25 @@
 
 using s31 = S3;
 using s32 = S3;
+
+template requires C class P> struct S4 { }; // #S4
+
+S4 s41;
+S4 s42;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
+S4 s43;
+S4 s44;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+
+template requires C typename U> struct S5 {
+  template static U V;
+};
+
+struct Nothing {};
+
+// FIXME: Wait the standard to clarify the intent.
+template<> template<> Z S5::V;
Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4097,8 +4097,10 @@
 
 TemplateParameterList *
 Sema::SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner,
-  const MultiLevelTemplateArgumentList ) {
+  const MultiLevelTemplateArgumentList ,
+  bool EvaluateConstraints) {
   

[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-25 Thread Liming Liu via Phabricator via cfe-commits
lime updated this revision to Diff 470679.
lime added a comment.
Herald added a project: libc++.
Herald added a subscriber: libcxx-commits.
Herald added a reviewer: libc++.

Update as required. Also, I need the following modification to complete `ninja 
check-all`. Maybe, I should submit another patch.

  diff --git a/clang/unittests/Support/CMakeLists.txt 
b/clang/unittests/Support/CMakeLists.txt
  index 956b3a7561..2413088a2b 100644
  --- a/clang/unittests/Support/CMakeLists.txt
  +++ b/clang/unittests/Support/CMakeLists.txt
  @@ -9,4 +9,7 @@ add_clang_unittest(ClangSupportTests
   clang_target_link_libraries(ClangSupportTests
 PRIVATE
 clangFrontend
  +  clangAST
  +  clangSerialization
  +  clangBasic
 )


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Sema/SemaConcept.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
  clang/test/SemaTemplate/concepts.cpp
  clang/www/cxx_status.html
  libcxx/DELETE.ME

Index: libcxx/DELETE.ME
===
--- /dev/null
+++ libcxx/DELETE.ME
@@ -0,0 +1 @@
+D134128
Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -912,11 +912,7 @@
 

 https://wg21.link/p0857r0;>P0857R0
-
-  Partial
-Constraining template template parameters is not yet supported.
-  
-
+Clang 16
   

 https://wg21.link/p1084r2;>P1084R2
Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -61,9 +61,9 @@
 
   // FIXME: This is valid under P0857R0.
   template concept C = true;
-  template requires C typename U> struct X {}; // expected-error {{requires 'class'}} expected-error 0+{{}}
+  template requires C typename U> struct X {};
   template requires C struct Y {};
-  X xy; // expected-error {{no template named 'X'}}
+  X xy;
 }
 
 namespace PR50306 {
Index: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
===
--- clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
+++ clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
@@ -1,22 +1,27 @@
 // RUN:  %clang_cc1 -std=c++2a -frelaxed-template-template-args -verify %s
 
-template concept C = T::f();
-// expected-note@-1{{similar constraint}}
+template concept C = T::f(); // #C
 template concept D = C && T::g();
-template concept F = T::f();
-// expected-note@-1{{similar constraint expressions not considered equivalent}}
-template class P> struct S1 { }; // expected-note 2{{'P' declared here}}
+template concept F = T::f(); // #F
+template class P> struct S1 { }; // #S1
 
 template struct X { };
 
-template struct Y { }; // expected-note{{'Y' declared here}}
+template struct Y { }; // #Y
 template struct Z { };
-template struct W { }; // expected-note{{'W' declared here}}
-
+template struct W { }; // #W
 S1 s11;
-S1 s12; // expected-error{{template template argument 'Y' is more constrained than template template parameter 'P'}}
+S1 s12;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
 S1 s13;
-S1 s14; // expected-error{{template template argument 'W' is more constrained than template template parameter 'P'}}
+S1 s14;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+// expected-note@#F 1-2{{similar constraint expressions not considered equivalent}}
+// expected-note@#C 1-2{{similar constraint}}
 
 template class P> struct S2 { };
 
@@ -32,3 +37,25 @@
 
 using s31 = S3;
 using s32 = S3;
+
+template requires C class P> struct S4 { }; // #S4
+
+S4 s41;
+S4 s42;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
+S4 s43;
+S4 s44;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+
+template requires C typename U> struct S5 {
+  template static U V;
+};
+
+struct Nothing {};
+
+// FIXME: Wait the standard to clarify the intent.

[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-24 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

In D134128#3879295 , @erichkeane 
wrote:

> I'm reasonably OK with this, I'm disappointed the 'skip for specialization' 
> is what was required, but I don't think I know of a better way.  I'll hold 
> off approving this until I've confirmed that libcxx tests + 
> libcxx-modules-tests are properly passing as a result of this.

I wnated to test this config locally, but it doesnt seem to be working for me?  
But you can modify this patch modify the DELETEME file in libcxx (see how he 
did it here: https://reviews.llvm.org/D127695 put it in the review but didnt 
commit it), it will cause libcxx pre-commit, which I think we shoudl do.  Just 
don't commit the DELETEME file obviously.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-24 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

ALSO; this is missing the cxx_status.html and release-notes, so please re-add 
those!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-24 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

I'm reasonably OK with this, I'm disappointed the 'skip for specialization' is 
what was required, but I don't think I know of a better way.  I'll hold off 
approving this until I've confirmed that libcxx tests + libcxx-modules-tests 
are properly passing as a result of this.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-23 Thread Liming Liu via Phabricator via cfe-commits
lime updated this revision to Diff 469982.
lime added a comment.

Update for the format check.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Sema/SemaConcept.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
  clang/test/SemaTemplate/concepts.cpp

Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -61,9 +61,9 @@
 
   // FIXME: This is valid under P0857R0.
   template concept C = true;
-  template requires C typename U> struct X {}; // expected-error {{requires 'class'}} expected-error 0+{{}}
+  template requires C typename U> struct X {};
   template requires C struct Y {};
-  X xy; // expected-error {{no template named 'X'}}
+  X xy;
 }
 
 namespace PR50306 {
Index: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
===
--- clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
+++ clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
@@ -1,22 +1,27 @@
 // RUN:  %clang_cc1 -std=c++2a -frelaxed-template-template-args -verify %s
 
-template concept C = T::f();
-// expected-note@-1{{similar constraint}}
+template concept C = T::f(); // #C
 template concept D = C && T::g();
-template concept F = T::f();
-// expected-note@-1{{similar constraint expressions not considered equivalent}}
-template class P> struct S1 { }; // expected-note 2{{'P' declared here}}
+template concept F = T::f(); // #F
+template class P> struct S1 { }; // #S1
 
 template struct X { };
 
-template struct Y { }; // expected-note{{'Y' declared here}}
+template struct Y { }; // #Y
 template struct Z { };
-template struct W { }; // expected-note{{'W' declared here}}
-
+template struct W { }; // #W
 S1 s11;
-S1 s12; // expected-error{{template template argument 'Y' is more constrained than template template parameter 'P'}}
+S1 s12;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
 S1 s13;
-S1 s14; // expected-error{{template template argument 'W' is more constrained than template template parameter 'P'}}
+S1 s14;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+// expected-note@#F 1-2{{similar constraint expressions not considered equivalent}}
+// expected-note@#C 1-2{{similar constraint}}
 
 template class P> struct S2 { };
 
@@ -32,3 +37,25 @@
 
 using s31 = S3;
 using s32 = S3;
+
+template requires C class P> struct S4 { }; // #S4
+
+S4 s41;
+S4 s42;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
+S4 s43;
+S4 s44;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+
+template requires C typename U> struct S5 {
+  template static U V;
+};
+
+struct Nothing {};
+
+// FIXME: Wait the standard to clarify the intent.
+template<> template<> Z S5::V;
Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4093,8 +4093,10 @@
 
 TemplateParameterList *
 Sema::SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner,
-  const MultiLevelTemplateArgumentList ) {
+  const MultiLevelTemplateArgumentList ,
+  bool EvaluateConstraints) {
   TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs);
+  Instantiator.setEvaluateConstraints(EvaluateConstraints);
   return Instantiator.SubstTemplateParams(Params);
 }
 
Index: clang/lib/Sema/SemaTemplateInstantiate.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -75,7 +75,8 @@
 // Add template arguments from a variable template instantiation.
 Response
 HandleVarTemplateSpec(const VarTemplateSpecializationDecl *VarTemplSpec,
-  MultiLevelTemplateArgumentList ) {
+  MultiLevelTemplateArgumentList ,
+  bool 

[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-23 Thread Liming Liu via Phabricator via cfe-commits
lime updated this revision to Diff 469976.
lime added a comment.

I updated the patch based on D136468 . I 
added a change which I think could be a fix to the specialization problem. It 
is just skipping the addition of the level where the specialization specialized 
from, as it seems to effect the calculation of the depth but not the depth in 
the constraint.

Denote that I got a linking error during `ninja check-all`, so I try to upload 
directly and see if it passes all the cases. And the require clauses seem not 
to be instantiated even if `EvaluateConstraints` is true.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Sema/SemaConcept.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
  clang/test/SemaTemplate/concepts.cpp

Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -61,9 +61,9 @@
 
   // FIXME: This is valid under P0857R0.
   template concept C = true;
-  template requires C typename U> struct X {}; // expected-error {{requires 'class'}} expected-error 0+{{}}
+  template requires C typename U> struct X {};
   template requires C struct Y {};
-  X xy; // expected-error {{no template named 'X'}}
+  X xy;
 }
 
 namespace PR50306 {
Index: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
===
--- clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
+++ clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
@@ -1,22 +1,27 @@
 // RUN:  %clang_cc1 -std=c++2a -frelaxed-template-template-args -verify %s
 
-template concept C = T::f();
-// expected-note@-1{{similar constraint}}
+template concept C = T::f(); // #C
 template concept D = C && T::g();
-template concept F = T::f();
-// expected-note@-1{{similar constraint expressions not considered equivalent}}
-template class P> struct S1 { }; // expected-note 2{{'P' declared here}}
+template concept F = T::f(); // #F
+template class P> struct S1 { }; // #S1
 
 template struct X { };
 
-template struct Y { }; // expected-note{{'Y' declared here}}
+template struct Y { }; // #Y
 template struct Z { };
-template struct W { }; // expected-note{{'W' declared here}}
-
+template struct W { }; // #W
 S1 s11;
-S1 s12; // expected-error{{template template argument 'Y' is more constrained than template template parameter 'P'}}
+S1 s12;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
 S1 s13;
-S1 s14; // expected-error{{template template argument 'W' is more constrained than template template parameter 'P'}}
+S1 s14;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+// expected-note@#F 1-2{{similar constraint expressions not considered equivalent}}
+// expected-note@#C 1-2{{similar constraint}}
 
 template class P> struct S2 { };
 
@@ -32,3 +37,25 @@
 
 using s31 = S3;
 using s32 = S3;
+
+template requires C class P> struct S4 { }; // #S4
+
+S4 s41;
+S4 s42;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
+S4 s43;
+S4 s44;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+
+template requires C typename U> struct S5 {
+  template static U V;
+};
+
+struct Nothing {};
+
+// FIXME: Wait the standard to clarify the intent.
+template<> template<> Z S5::V;
Index: clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4093,8 +4093,10 @@
 
 TemplateParameterList *
 Sema::SubstTemplateParams(TemplateParameterList *Params, DeclContext *Owner,
-  const MultiLevelTemplateArgumentList ) {
+  const MultiLevelTemplateArgumentList ,
+  bool EvaluateConstraints) {
   TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs);
+  Instantiator.setEvaluateConstraints(EvaluateConstraints);
   return Instantiator.SubstTemplateParams(Params);
 }
 

[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-21 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

So I've been messing around with this a bit, and am somewhat confident that 
IsAtLeastAsConstrainedAs should just contain:

  unsigned Depth1 = CalculateTemplateDepthForConstraints(*this, D1);
  unsigned Depth2 = CalculateTemplateDepthForConstraints(*this, D2);

  for (size_t I = 0; I != AC1.size() && I != AC2.size(); ++I) {
if (Depth2 > Depth1) {
  AC1[I] = AdjustConstraintDepth(*this, Depth2 - Depth1).
TransformExpr(const_cast(AC1[I])).
get();
} else if (Depth1 > Depth2) {
  AC2[I] = AdjustConstraintDepth(*this, Depth1 - Depth2).
TransformExpr(const_cast(AC2[I])).
get();
}
  }

However, I see in the example:

  template concept C = T::f();
  template struct X{};
  
  template class P> struct S1 { }; // #S1
  S1 s11;

That this fails because the type-constraint has already been instantiated 
during the SubstTemplateParams call ~5735 in SemaTemplate.cpp.  I believe that 
to be an error, and the type-constraint on the TemplateTypeParmDecl should NOT 
be instantiated.

That line seems to change:

  TemplateTypeParmDecl 0x149b2d20  col:20 Concept 0x149b2740 
'C' depth 1 index 0
  `-ConceptSpecializationExpr 0x149b2e58  'bool' Concept 0x149b2740 'C'
`-TemplateArgument  type 'type-parameter-1-0'
  `-TemplateTypeParmType 0x149b2df0 'type-parameter-1-0' dependent depth 1 
index 0
`-TemplateTypeParm 0x149b2d20 ''

To

  TemplateTypeParmDecl 0x149d1550  col:20 Concept 0x149b2740 
'C' depth 0 index 0
  `-ConceptSpecializationExpr 0x149d1668  'bool' Concept 0x149b2740 'C'
`-TemplateArgument  type 'type-parameter-0-0'
  `-TemplateTypeParmType 0x149d15f0 'type-parameter-0-0' dependent depth 0 
index 0
`-TemplateTypeParm 0x149d1550 ''

While the `TemplateTypeParmDecl` is CORRECT to be changed like this, the 
`ConceptSpecializationExpr` should NOT have its arguments changed, thats the 
whole point of the deferred concepts implementation.

IN LOOKING, it seems that the problem is that the instantiator set up by 
`SubstTemplateParams` doesn't set the "EvaluateConstraints" to false, as it 
should be.

I did a test-patch here: https://reviews.llvm.org/D136468 (for you to look at, 
not for review!).  However, I am getting 4 test failures that I suspect are a 
result of needing to stop evaluating constraints early elsewhere as well.  I'm 
about done with being able to look at this today, so if you get a chance, you 
might find that useful to look into.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-18 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

In D134128#3865063 , @lime wrote:

>> which isn't clear to me what you mean
>
> - In the function `Sema::CheckTemplateArgument` at line 5725, `Params` has 
> been substituted in a way all `TemplateTypeParmDecl`s are instantiated with a 
> smaller depth, and so are constraints of them at 
> SemaTemplateInstantiateDecl.cpp:2769, while the requires clause remains the 
> same.
> - Then `CheckTemplateArgument` calls `CheckTemplateTemplateArgument` which 
> calls `IsAtLeastAsConstrained` with the original declaration and the 
> constraints collected from `Params`. Thus, in `IsAtLeastAsConstrained`, a 
> depth calculated from the declaration will not reflect the depth in the 
> constraint.
> - It should be fine to not adjust the depths between two constraints passed 
> to `IsAtLeastAsConstrained` if the requires clause is not parsed, as they are 
> already the same. But it is not the case when the constraint is from a 
> requires clause, as requires clauses are not substituted. However, 
> calculating from declarations will break the original case.

It sounds like perhaps we've instantiated constraints we shouldn't have in the 
case of template-template parameters.  Based on what you're saying, I'm 
concerned then that perhaps the deferred concept instantiation didn't work 
right for template-template constraints? That might require more work on that 
then before anything could happen here.

Otherwise, I would expect calculating from the Template Template Decl to work, 
(though its likely it doesn't actually 'add' a layer yet, since I don't think 
we've needed that yet, so an extra bit of work there would need to be done).

>> I wouldn't expect the requires clause (nor any other concept related AST 
>> node) to be instantiated at all until it is going through 'checking'
>
> The function `TemplateDeclInstantiator::SubstTemplateParams` instantiates 
> constraints like `template  class>`, so it is already happened.

If that is happening outside of a constraint evaluation, that is likely 
incorrect, and perhaps part of the problem.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-18 Thread Liming Liu via Phabricator via cfe-commits
lime added a comment.

> which isn't clear to me what you mean

- In the function `Sema::CheckTemplateArgument` at line 5725, `Params` has been 
substituted in a way all `TemplateTypeParmDecl`s are instantiated with a 
smaller depth, and so are constraints of them at 
SemaTemplateInstantiateDecl.cpp:2769, while the requires clause remains the 
same.
- Then `CheckTemplateArgument` calls `CheckTemplateTemplateArgument` which 
calls `IsAtLeastAsConstrained` with the original declaration and the 
constraints collected from `Params`. Thus, in `IsAtLeastAsConstrained`, a depth 
calculated from the declaration will not reflect the depth in the constraint.
- It should be fine to not adjust the depths between two constraints passed to 
`IsAtLeastAsConstrained` if the requires clause is not parsed, as they are 
already the same. But it is not the case when the constraint is from a requires 
clause, as requires clauses are not substituted. However, calculating from 
declarations will break the original case.

> I wouldn't expect the requires clause (nor any other concept related AST 
> node) to be instantiated at all until it is going through 'checking'

The function `TemplateDeclInstantiator::SubstTemplateParams` instantiates 
constraints like `template  class>`, so it is already happened.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-17 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

In D134128#3860993 , @lime wrote:

> I think I located the problem. In the line 4014 of the file 
> `SemaTemplateInstantiateDecl.cpp`, the requires clause is not instantiated as 
> the parameters of the template parameter list, and these parameters have been 
> instantiated with a shallower depth. So that's the reason why the depths are 
> not confirm between the `T` in `template  class>` and the 
> constraints on the instantiated parameters. I guess adjusting depths should 
> be unnecessary in `IsAtLeastAsConstrained`, if the requires clause was 
> correctly instantiated, so should changes related to `SemaConcept.cpp`. I 
> will work on this later.

I wouldn't expect the requires clause (nor any other concept related AST node) 
to be instantiated at all until it is going through 'checking', which is the 
purpose of the deferred concepts patch. That said, 
SemaTemplateInstantiateDecl.cpp:4014 is in the middle of adjustForRewrite, 
which isn't clear to me what you mean.

That said, I'm not sure what the


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-16 Thread Liming Liu via Phabricator via cfe-commits
lime added a comment.

I think I located the problem. In the line 1014 of the file 
`SemaTemplateInstantiateDecl.cpp`, the requires clause is not instantiated as 
the parameters of the template parameter list, and these parameters have been 
instantiated with a shallower depth. So that's the reason why the depths are 
not confirm between the `T` in `template  class>` and the 
constraints on the instantiated parameters. I guess adjusting depths should be 
unnecessary in `IsAtLeastAsConstrained`, if the requires clause was correctly 
instantiated, so are changes related to `SemaConcept.cpp`. I will work on this 
later.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-13 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added inline comments.



Comment at: clang/lib/Sema/SemaConcept.cpp:590
 
+// FIXME: may be incomplete
+static unsigned CalculateTemplateDepthForConstraints(const Expr *Constr) {

lime wrote:
> erichkeane wrote:
> > I'd like some sort of assert in the case where you don't know what to do 
> > here.  We need to collect all of these cases best we can in advance.
> > 
> > I'd suggest ALSO running libcxx tests against this once you have the assert 
> > in place, which should help.
> I'm afraid that assertions would abort Clang on many code. This function 
> serves as a check for `AdjustConstraintDepth`, and this class looks like just 
> handling `TemplateTypeParmType`. The function has already handled 
> `TemplateTypeParmType`. And determining cases that should trigger the 
> assertions also involves the subsumption of atomic constraints. It is needed 
> to check the depth according to `TemplateTypeParmType`, because the identity 
> of `QualType` involves the depth, and then effects the subsumption. There 
> will be some works to determine which cases are the same, and leave 
> assertions for the cases. This kind of works is highly related to the depth 
> and the subsumption, while I think it is less related to template template 
> parameters.
The point of an assertion would be to do just that!  We WANT to make sure we 
get all those assertions.  That said, I'm unconvinced that this code here is 
necessary.



Comment at: clang/lib/Sema/SemaConcept.cpp:706
+  std::tie(OldConstr, NewConstr) =
+  AdjustConstraintDepth::UnifyConstraintDepthFromDecl(*this, Old, 
OldConstr,
+  New, NewConstr);

lime wrote:
> erichkeane wrote:
> > lime wrote:
> > > erichkeane wrote:
> > > > Unless I'm missing something, I don't think this idea of 'unify 
> > > > constraint depth' is correct.  We should be able, from the decl itself, 
> > > > to determine the depths?  What is the difference here that I'm not 
> > > > getting?
> > > 3. I extracted the calls to the original 
> > > `CalculateTemplateDepthForConstraints` as `UnifyConstraintDepthFromDecl`. 
> > > Calculating from a declaration is indeed not accurate, as it returns 1 
> > > for `template class>`, but the depth in the constraint is 
> > > actually 0. This is one reason why a previous version of patch breaks 
> > > some unit tests. But I leaves it to keep the code unchanged functionally.
> > Hmm... SO it seems based on debugging that the issue is exclusive with 
> > template template parameters.  It DOES make sense that the inner-template 
> > is 'deeper', but I think the problem is that `getTemplateInstantiationArgs` 
> > isn't correctly handling a ClassTemplateDecl, so the "D2" in 
> > `IsAtLeastAsConstrainedAs` is returning 0, instead of 1.
> > 
> > The "Depth" of something is the 'number of layers of template arguments'.  
> > So for: 'template class>', the answer SHOULD be 1.
> > 
> > So I think the problem is basically that for X, the answer should ALSO be 1 
> > (since it has template parameters), but we aren't handling it.  So I think 
> > we just need to correctly just call the 
> > `ClassTemplateDecl::getTemplatedDecl` at one point on that one.
> I guess there could be another patch improving the calculation about depth. 
> In this patch, I just adjust the calculation to pass unit tests about 
> template template parameters.
Right, but I'm saying how you're doing it is incorrect and will likely result 
in incorrect compilations


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-12 Thread Liming Liu via Phabricator via cfe-commits
lime added inline comments.



Comment at: clang/lib/Sema/SemaConcept.cpp:590
 
+// FIXME: may be incomplete
+static unsigned CalculateTemplateDepthForConstraints(const Expr *Constr) {

erichkeane wrote:
> I'd like some sort of assert in the case where you don't know what to do 
> here.  We need to collect all of these cases best we can in advance.
> 
> I'd suggest ALSO running libcxx tests against this once you have the assert 
> in place, which should help.
I'm afraid that assertions would abort Clang on many code. This function serves 
as a check for `AdjustConstraintDepth`, and this class looks like just handling 
`TemplateTypeParmType`. The function has already handled 
`TemplateTypeParmType`. And determining cases that should trigger the 
assertions also involves the subsumption of atomic constraints. It is needed to 
check the depth according to `TemplateTypeParmType`, because the identity of 
`QualType` involves the depth, and then effects the subsumption. There will be 
some works to determine which cases are the same, and leave assertions for the 
cases. This kind of works is highly related to the depth and the subsumption, 
while I think it is less related to template template parameters.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-12 Thread Liming Liu via Phabricator via cfe-commits
lime added inline comments.



Comment at: clang/lib/Sema/SemaConcept.cpp:706
+  std::tie(OldConstr, NewConstr) =
+  AdjustConstraintDepth::UnifyConstraintDepthFromDecl(*this, Old, 
OldConstr,
+  New, NewConstr);

erichkeane wrote:
> lime wrote:
> > erichkeane wrote:
> > > Unless I'm missing something, I don't think this idea of 'unify 
> > > constraint depth' is correct.  We should be able, from the decl itself, 
> > > to determine the depths?  What is the difference here that I'm not 
> > > getting?
> > 3. I extracted the calls to the original 
> > `CalculateTemplateDepthForConstraints` as `UnifyConstraintDepthFromDecl`. 
> > Calculating from a declaration is indeed not accurate, as it returns 1 for 
> > `template class>`, but the depth in the constraint is 
> > actually 0. This is one reason why a previous version of patch breaks some 
> > unit tests. But I leaves it to keep the code unchanged functionally.
> Hmm... SO it seems based on debugging that the issue is exclusive with 
> template template parameters.  It DOES make sense that the inner-template is 
> 'deeper', but I think the problem is that `getTemplateInstantiationArgs` 
> isn't correctly handling a ClassTemplateDecl, so the "D2" in 
> `IsAtLeastAsConstrainedAs` is returning 0, instead of 1.
> 
> The "Depth" of something is the 'number of layers of template arguments'.  So 
> for: 'template class>', the answer SHOULD be 1.
> 
> So I think the problem is basically that for X, the answer should ALSO be 1 
> (since it has template parameters), but we aren't handling it.  So I think we 
> just need to correctly just call the `ClassTemplateDecl::getTemplatedDecl` at 
> one point on that one.
I guess there could be another patch improving the calculation about depth. In 
this patch, I just adjust the calculation to pass unit tests about template 
template parameters.



Comment at: clang/lib/Sema/SemaConcept.cpp:1340
+bool Sema::IsAtLeastAsConstrained(NamedDecl *D1,
+  MutableArrayRef AC1,
+  NamedDecl *D2,

erichkeane wrote:
> erichkeane wrote:
> > Can you explain why this is a MutableArrayRef now?  I believe this means 
> > it'll now modify the arrays that are passed into it, which we don't 
> > necessarily want, right?  A new 
> I see your response... I am a bit concerned about the use of this in 
> SemaTemplate, which re-uses the generated array after this however (though 
> for diagnostics?).
> 
> Everywhere else doesn't seem to be using the underlying array after the fact.
The function `MaybeEmitAmbiguousAtomicConstraintDiagnostic` calls `subsume` on 
`AtomicConstraint` without adjusting depths. So, I guess it is fine to reuse 
the unified arrays.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-12 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added inline comments.



Comment at: clang/lib/Sema/SemaConcept.cpp:706
+  std::tie(OldConstr, NewConstr) =
+  AdjustConstraintDepth::UnifyConstraintDepthFromDecl(*this, Old, 
OldConstr,
+  New, NewConstr);

lime wrote:
> erichkeane wrote:
> > Unless I'm missing something, I don't think this idea of 'unify constraint 
> > depth' is correct.  We should be able, from the decl itself, to determine 
> > the depths?  What is the difference here that I'm not getting?
> 3. I extracted the calls to the original 
> `CalculateTemplateDepthForConstraints` as `UnifyConstraintDepthFromDecl`. 
> Calculating from a declaration is indeed not accurate, as it returns 1 for 
> `template class>`, but the depth in the constraint is actually 
> 0. This is one reason why a previous version of patch breaks some unit tests. 
> But I leaves it to keep the code unchanged functionally.
Hmm... SO it seems based on debugging that the issue is exclusive with template 
template parameters.  It DOES make sense that the inner-template is 'deeper', 
but I think the problem is that `getTemplateInstantiationArgs` isn't correctly 
handling a ClassTemplateDecl, so the "D2" in `IsAtLeastAsConstrainedAs` is 
returning 0, instead of 1.

The "Depth" of something is the 'number of layers of template arguments'.  So 
for: 'template class>', the answer SHOULD be 1.

So I think the problem is basically that for X, the answer should ALSO be 1 
(since it has template parameters), but we aren't handling it.  So I think we 
just need to correctly just call the `ClassTemplateDecl::getTemplatedDecl` at 
one point on that one.



Comment at: clang/lib/Sema/SemaConcept.cpp:1340
+bool Sema::IsAtLeastAsConstrained(NamedDecl *D1,
+  MutableArrayRef AC1,
+  NamedDecl *D2,

erichkeane wrote:
> Can you explain why this is a MutableArrayRef now?  I believe this means 
> it'll now modify the arrays that are passed into it, which we don't 
> necessarily want, right?  A new 
I see your response... I am a bit concerned about the use of this in 
SemaTemplate, which re-uses the generated array after this however (though for 
diagnostics?).

Everywhere else doesn't seem to be using the underlying array after the fact.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-12 Thread Liming Liu via Phabricator via cfe-commits
lime added a comment.

> Unless I'm missing something, I don't think this idea of 'unify constraint 
> depth' is correct. We should be able, from the decl itself, to determine the 
> depths? What is the difference here that I'm not getting?

It is explained by the inline comments in sequence.

> Can you explain why this is a MutableArrayRef now? I believe this means it'll 
> now modify the arrays that are passed into it, which we don't necessarily 
> want, right?

In the previous update, I mentioned using ArrayRef is not as efficient as 
MutableArrayRef. And there was no feedback on my comment for several days, so I 
changed as I said. Additionally, I found some code once called 
`IsAtLeastAsConstrained` for two constraints, and then call 
`IsAtLeastAsConstrained` again with the sequence of the two constraints 
switched. So using MutableArrayRef also saves a potential adjustment.
Any way, adjusting depths here might unique to template template parameters. If 
so, parsing the require clause in the unit test with depth equal to 0 should be 
a better solution, and things about CalculateTemplateDepthForConstraints and 
ArrayRef could remain unchanged.




Comment at: clang/lib/Sema/SemaConcept.cpp:581
 // getTemplateDepth, because it includes already instantiated parents.
 static unsigned CalculateTemplateDepthForConstraints(Sema ,
  const NamedDecl *ND) {

1. The orignal `CalculateTemplateDepthForConstraints` calculates the depth from 
`NamedDecl`.



Comment at: clang/lib/Sema/SemaConcept.cpp:621
-  if (Old && New && Old != New) {
-unsigned Depth1 = CalculateTemplateDepthForConstraints(
-*this, Old);

2. And it was only called in `AreConstraintExpressionsEqual`.



Comment at: clang/lib/Sema/SemaConcept.cpp:706
+  std::tie(OldConstr, NewConstr) =
+  AdjustConstraintDepth::UnifyConstraintDepthFromDecl(*this, Old, 
OldConstr,
+  New, NewConstr);

erichkeane wrote:
> Unless I'm missing something, I don't think this idea of 'unify constraint 
> depth' is correct.  We should be able, from the decl itself, to determine the 
> depths?  What is the difference here that I'm not getting?
3. I extracted the calls to the original `CalculateTemplateDepthForConstraints` 
as `UnifyConstraintDepthFromDecl`. Calculating from a declaration is indeed not 
accurate, as it returns 1 for `template class>`, but the depth 
in the constraint is actually 0. This is one reason why a previous version of 
patch breaks some unit tests. But I leaves it to keep the code unchanged 
functionally.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-12 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added inline comments.



Comment at: clang/lib/Sema/SemaConcept.cpp:590
 
+// FIXME: may be incomplete
+static unsigned CalculateTemplateDepthForConstraints(const Expr *Constr) {

I'd like some sort of assert in the case where you don't know what to do here.  
We need to collect all of these cases best we can in advance.

I'd suggest ALSO running libcxx tests against this once you have the assert in 
place, which should help.



Comment at: clang/lib/Sema/SemaConcept.cpp:706
+  std::tie(OldConstr, NewConstr) =
+  AdjustConstraintDepth::UnifyConstraintDepthFromDecl(*this, Old, 
OldConstr,
+  New, NewConstr);

Unless I'm missing something, I don't think this idea of 'unify constraint 
depth' is correct.  We should be able, from the decl itself, to determine the 
depths?  What is the difference here that I'm not getting?



Comment at: clang/lib/Sema/SemaConcept.cpp:1340
+bool Sema::IsAtLeastAsConstrained(NamedDecl *D1,
+  MutableArrayRef AC1,
+  NamedDecl *D2,

Can you explain why this is a MutableArrayRef now?  I believe this means it'll 
now modify the arrays that are passed into it, which we don't necessarily want, 
right?  A new 


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-12 Thread Liming Liu via Phabricator via cfe-commits
lime updated this revision to Diff 467039.
lime added a comment.

I updated the patch as I said, while kept the key of `NormalizationCache` 
relatively heavy. That means I:

- changed the parameter of `IsAtLeastAsConstrained` to `MutableArrayRef`,
- and let the new `CalculateTemplateDepthForConstraints` handle 
`BinaryOperator` and `ParenExpr`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Sema/SemaConcept.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
  clang/test/SemaTemplate/concepts.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -912,11 +912,7 @@
 

 https://wg21.link/p0857r0;>P0857R0
-
-  Partial
-Constraining template template parameters is not yet supported.
-  
-
+Clang 16
   

 https://wg21.link/p1084r2;>P1084R2
Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -59,11 +59,10 @@
 x.operator()(); // expected-error {{no matching member function}}
   }
 
-  // FIXME: This is valid under P0857R0.
   template concept C = true;
-  template requires C typename U> struct X {}; // expected-error {{requires 'class'}} expected-error 0+{{}}
+  template requires C typename U> struct X {};
   template requires C struct Y {};
-  X xy; // expected-error {{no template named 'X'}}
+  X xy;
 }
 
 namespace PR50306 {
Index: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
===
--- clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
+++ clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
@@ -1,22 +1,27 @@
 // RUN:  %clang_cc1 -std=c++2a -frelaxed-template-template-args -verify %s
 
-template concept C = T::f();
-// expected-note@-1{{similar constraint}}
+template concept C = T::f(); // #C
 template concept D = C && T::g();
-template concept F = T::f();
-// expected-note@-1{{similar constraint expressions not considered equivalent}}
-template class P> struct S1 { }; // expected-note 2{{'P' declared here}}
+template concept F = T::f(); // #F
+template class P> struct S1 { }; // #S1
 
 template struct X { };
-
-template struct Y { }; // expected-note{{'Y' declared here}}
+template struct Y { }; // #Y
 template struct Z { };
-template struct W { }; // expected-note{{'W' declared here}}
+template struct W { }; // #W
 
 S1 s11;
-S1 s12; // expected-error{{template template argument 'Y' is more constrained than template template parameter 'P'}}
+S1 s12;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
 S1 s13;
-S1 s14; // expected-error{{template template argument 'W' is more constrained than template template parameter 'P'}}
+S1 s14;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+// expected-note@#F 1-2{{similar constraint expressions not considered equivalent}}
+// expected-note@#C 1-2{{similar constraint}}
 
 template class P> struct S2 { };
 
@@ -32,3 +37,25 @@
 
 using s31 = S3;
 using s32 = S3;
+
+template requires C class P> struct S4 { }; // #S4
+
+S4 s41;
+S4 s42;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
+S4 s43;
+S4 s44;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+
+template requires C typename U> struct S5 {
+  template static U V;
+};
+
+struct Nothing {};
+
+// FIXME: Wait the standard to clarify the intent.
+template<> template<> Z S5::V;
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -6429,7 +6429,7 @@
   NamedDecl *ND = Function;
   if (auto *SpecInfo = Function->getTemplateSpecializationInfo())
 ND = SpecInfo->getTemplate();
-  
+
   if (ND->getFormalLinkage() == Linkage::InternalLinkage) {
 Candidate.Viable = false;
 Candidate.FailureKind = ovl_fail_module_mismatched;
@@ -9700,7 +9700,7 @@
 

[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-07 Thread Liming Liu via Phabricator via cfe-commits
lime updated this revision to Diff 466056.
lime added a comment.

> The changes in Sema.h and the changes of CalculateTemplateDepthForConstraints

I think it might be fine now. The above changes are related to 
`NormalizationCache`. This cache used to take `NamedDecl` as its key. However, 
as constrains need to be adjusted to different depths, and `p3-2a.cpp` can 
reproduce the case. Thus, `NameDecl` is not enough, and a heavier key is used. 
But the needs to adjust the depth seem unique to template-template parameter, 
so I'm not sure whether there is a better solution. And 
`IsAtLeastAsConstrained` takes `ArrayRef` as its argument, which leads to new 
spaces for potentially adjusted constrains. I think `MutableArryRef` could be 
used here.

BTW, this comment includes an update that involves `git clang-format`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Sema/SemaConcept.cpp
  clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
  clang/test/SemaTemplate/concepts.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -912,11 +912,7 @@
 

 https://wg21.link/p0857r0;>P0857R0
-
-  Partial
-Constraining template template parameters is not yet supported.
-  
-
+Clang 16
   

 https://wg21.link/p1084r2;>P1084R2
Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -59,11 +59,10 @@
 x.operator()(); // expected-error {{no matching member function}}
   }
 
-  // FIXME: This is valid under P0857R0.
   template concept C = true;
-  template requires C typename U> struct X {}; // expected-error {{requires 'class'}} expected-error 0+{{}}
+  template requires C typename U> struct X {};
   template requires C struct Y {};
-  X xy; // expected-error {{no template named 'X'}}
+  X xy;
 }
 
 namespace PR50306 {
Index: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
===
--- clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
+++ clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
@@ -1,22 +1,27 @@
 // RUN:  %clang_cc1 -std=c++2a -frelaxed-template-template-args -verify %s
 
-template concept C = T::f();
-// expected-note@-1{{similar constraint}}
+template concept C = T::f(); // #C
 template concept D = C && T::g();
-template concept F = T::f();
-// expected-note@-1{{similar constraint expressions not considered equivalent}}
-template class P> struct S1 { }; // expected-note 2{{'P' declared here}}
+template concept F = T::f(); // #F
+template class P> struct S1 { }; // #S1
 
 template struct X { };
-
-template struct Y { }; // expected-note{{'Y' declared here}}
+template struct Y { }; // #Y
 template struct Z { };
-template struct W { }; // expected-note{{'W' declared here}}
+template struct W { }; // #W
 
 S1 s11;
-S1 s12; // expected-error{{template template argument 'Y' is more constrained than template template parameter 'P'}}
+S1 s12;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
 S1 s13;
-S1 s14; // expected-error{{template template argument 'W' is more constrained than template template parameter 'P'}}
+S1 s14;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+// expected-note@#F 1-2{{similar constraint expressions not considered equivalent}}
+// expected-note@#C 1-2{{similar constraint}}
 
 template class P> struct S2 { };
 
@@ -32,3 +37,25 @@
 
 using s31 = S3;
 using s32 = S3;
+
+template requires C class P> struct S4 { }; // #S4
+
+S4 s41;
+S4 s42;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
+S4 s43;
+S4 s44;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+
+template requires C typename U> struct S5 {
+  template static U V;
+};
+
+struct Nothing {};
+
+// FIXME: Wait the standard to clarify the intent.
+template<> template<> Z S5::V;
Index: clang/lib/Sema/SemaConcept.cpp
===
--- 

[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-06 Thread Erich Keane via Phabricator via cfe-commits
erichkeane requested changes to this revision.
erichkeane added a comment.
This revision now requires changes to proceed.

In D134128#3840232 , @lime wrote:

> I updated patch to fix the previous problem that failed to pass unit tests. 
> And, isn't this patch accepted a little quickly? BTW, `NormalizationCache` 
> becomes heavier than before.

Huh, woah, Phab didn't show me 1/2 this patch the last time.  The changes in 
Sema.h and the changes of CalculateTemplateDepthForConstraints just weren't 
there...

So yeah, I guess, spend more time on this?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-06 Thread Liming Liu via Phabricator via cfe-commits
lime updated this revision to Diff 465750.
lime added a comment.

I updated patch to fix the previous problem that failed to pass unit tests. 
And, isn't this patch accepted a little quickly? BTW, `NormalizationCache` 
becomes heavier than before.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Sema/SemaConcept.cpp
  clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
  clang/test/SemaTemplate/concepts.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -912,11 +912,7 @@
 

 https://wg21.link/p0857r0;>P0857R0
-
-  Partial
-Constraining template template parameters is not yet supported.
-  
-
+Clang 16
   

 https://wg21.link/p1084r2;>P1084R2
Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -59,11 +59,10 @@
 x.operator()(); // expected-error {{no matching member function}}
   }
 
-  // FIXME: This is valid under P0857R0.
   template concept C = true;
-  template requires C typename U> struct X {}; // expected-error {{requires 'class'}} expected-error 0+{{}}
+  template requires C typename U> struct X {};
   template requires C struct Y {};
-  X xy; // expected-error {{no template named 'X'}}
+  X xy;
 }
 
 namespace PR50306 {
Index: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
===
--- clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
+++ clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
@@ -1,22 +1,27 @@
 // RUN:  %clang_cc1 -std=c++2a -frelaxed-template-template-args -verify %s
 
-template concept C = T::f();
-// expected-note@-1{{similar constraint}}
+template concept C = T::f(); // #C
 template concept D = C && T::g();
-template concept F = T::f();
-// expected-note@-1{{similar constraint expressions not considered equivalent}}
-template class P> struct S1 { }; // expected-note 2{{'P' declared here}}
+template concept F = T::f(); // #F
+template class P> struct S1 { }; // #S1
 
 template struct X { };
-
-template struct Y { }; // expected-note{{'Y' declared here}}
+template struct Y { }; // #Y
 template struct Z { };
-template struct W { }; // expected-note{{'W' declared here}}
+template struct W { }; // #W
 
 S1 s11;
-S1 s12; // expected-error{{template template argument 'Y' is more constrained than template template parameter 'P'}}
+S1 s12;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
 S1 s13;
-S1 s14; // expected-error{{template template argument 'W' is more constrained than template template parameter 'P'}}
+S1 s14;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+// expected-note@#F 1-2{{similar constraint expressions not considered equivalent}}
+// expected-note@#C 1-2{{similar constraint}}
 
 template class P> struct S2 { };
 
@@ -32,3 +37,25 @@
 
 using s31 = S3;
 using s32 = S3;
+
+template requires C class P> struct S4 { }; // #S4
+
+S4 s41;
+S4 s42;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
+S4 s43;
+S4 s44;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+
+template requires C typename U> struct S5 {
+  template static U V;
+};
+
+struct Nothing {};
+
+// FIXME: Wait the standard to clarify the intent.
+template<> template<> Z S5::V;
Index: clang/lib/Sema/SemaConcept.cpp
===
--- clang/lib/Sema/SemaConcept.cpp
+++ clang/lib/Sema/SemaConcept.cpp
@@ -587,6 +587,42 @@
   return MLTAL.getNumSubstitutedLevels();
 }
 
+// FIXME: may be incomplete
+static unsigned CalculateTemplateDepthForConstraints(const Expr *Constr) {
+  unsigned Depth = 0;
+  if (isa(Constr)) {
+for (auto  :
+ cast(Constr)->getTemplateArguments()) {
+  unsigned ArgDepth = 0;
+  switch (Arg.getKind()) {
+  case TemplateArgument::Type:
+if (isa(Arg.getAsType())) {
+  ArgDepth = cast(Arg.getAsType())->getDepth();
+}
+break;
+  case 

[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-06 Thread Erich Keane via Phabricator via cfe-commits
erichkeane accepted this revision.
erichkeane added inline comments.
This revision is now accepted and ready to land.



Comment at: clang/lib/Sema/SemaConcept.cpp:614
+
+  static auto UnifyConstraintDepth(Sema ,
+  const NamedDecl *Old,

`SemaRef` or `S` is our common nomenclature.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-05 Thread Liming Liu via Phabricator via cfe-commits
lime updated this revision to Diff 465652.
lime added a comment.

Thanks for the advice. I used `AdjustConstraintDepth` before `subsume`. The 
adjusted constraints are assigned to new addresses, but I think 
`MutableArrayRef` could be used here.

> what do you mean by 'tailing' here?

I wanted to express the require clauses, as they are stored in `TrailingObject`.

> What exactly is going on here? I would expect the 'AdjustConstraintDepth' 
> work to have already made these basically equal.

`AdjustConstraintDepth` works here, but I missed it before you mentioned it.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

Files:
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Sema/SemaConcept.cpp
  clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
  clang/test/SemaTemplate/concepts.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -912,11 +912,7 @@
 

 https://wg21.link/p0857r0;>P0857R0
-
-  Partial
-Constraining template template parameters is not yet supported.
-  
-
+Clang 16
   

 https://wg21.link/p1084r2;>P1084R2
Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -59,11 +59,10 @@
 x.operator()(); // expected-error {{no matching member function}}
   }
 
-  // FIXME: This is valid under P0857R0.
   template concept C = true;
-  template requires C typename U> struct X {}; // expected-error {{requires 'class'}} expected-error 0+{{}}
+  template requires C typename U> struct X {};
   template requires C struct Y {};
-  X xy; // expected-error {{no template named 'X'}}
+  X xy;
 }
 
 namespace PR50306 {
Index: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
===
--- clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
+++ clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
@@ -1,22 +1,27 @@
 // RUN:  %clang_cc1 -std=c++2a -frelaxed-template-template-args -verify %s
 
-template concept C = T::f();
-// expected-note@-1{{similar constraint}}
+template concept C = T::f(); // #C
 template concept D = C && T::g();
-template concept F = T::f();
-// expected-note@-1{{similar constraint expressions not considered equivalent}}
-template class P> struct S1 { }; // expected-note 2{{'P' declared here}}
+template concept F = T::f(); // #F
+template class P> struct S1 { }; // #S1
 
 template struct X { };
-
-template struct Y { }; // expected-note{{'Y' declared here}}
+template struct Y { }; // #Y
 template struct Z { };
-template struct W { }; // expected-note{{'W' declared here}}
+template struct W { }; // #W
 
 S1 s11;
-S1 s12; // expected-error{{template template argument 'Y' is more constrained than template template parameter 'P'}}
+S1 s12;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
 S1 s13;
-S1 s14; // expected-error{{template template argument 'W' is more constrained than template template parameter 'P'}}
+S1 s14;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+// expected-note@#F {{similar constraint expressions not considered equivalent}}
+// expected-note@#C {{similar constraint}}
 
 template class P> struct S2 { };
 
@@ -32,3 +37,27 @@
 
 using s31 = S3;
 using s32 = S3;
+
+template requires C class P> struct S4 { }; // #S4
+
+S4 s41;
+S4 s42;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
+S4 s43;
+S4 s44;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+// expected-note@#F {{similar constraint expressions not considered equivalent}}
+// expected-note@#C {{similar constraint}}
+
+template requires C typename U> struct S5 {
+  template static U V;
+};
+
+struct Nothing {};
+
+// FIXME: Wait the standard to clarify the intent.
+template<> template<> Z S5::V;
Index: clang/lib/Sema/SemaConcept.cpp
===
--- clang/lib/Sema/SemaConcept.cpp
+++ clang/lib/Sema/SemaConcept.cpp
@@ -610,6 +610,30 @@
 NewTL.setNameLoc(TL.getNameLoc());
 return Result;
   }
+
+  static auto 

[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-05 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added inline comments.



Comment at: clang/include/clang/Sema/SemaConcept.h:51
+  // QualType of constrained template template parameter is not the same as
+  // its tailing version, so give it a pass here.
+  if (LHS.getKind() == TemplateArgument::Type &&

what do you mean by 'tailing' here?



Comment at: clang/include/clang/Sema/SemaConcept.h:58
+cast(RHS.getAsType())->getIndex())
+  continue;
+  }

What exactly is going on here?  I would expect the 'AdjustConstraintDepth' work 
to have already made these basically equal.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-05 Thread Liming Liu via Phabricator via cfe-commits
lime updated this revision to Diff 465395.
lime added a comment.

I provided a solution for the problem I mentioned above, although it may look 
ugly. Then, I will take a look at `friend` related stuffs.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

Files:
  clang/include/clang/Sema/SemaConcept.h
  clang/lib/Parse/ParseTemplate.cpp
  clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
  clang/test/SemaTemplate/concepts.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -912,11 +912,7 @@
 

 https://wg21.link/p0857r0;>P0857R0
-
-  Partial
-Constraining template template parameters is not yet supported.
-  
-
+Clang 16
   

 https://wg21.link/p1084r2;>P1084R2
Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -59,11 +59,10 @@
 x.operator()(); // expected-error {{no matching member function}}
   }
 
-  // FIXME: This is valid under P0857R0.
   template concept C = true;
-  template requires C typename U> struct X {}; // expected-error {{requires 'class'}} expected-error 0+{{}}
+  template requires C typename U> struct X {};
   template requires C struct Y {};
-  X xy; // expected-error {{no template named 'X'}}
+  X xy;
 }
 
 namespace PR50306 {
Index: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
===
--- clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
+++ clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
@@ -1,22 +1,27 @@
 // RUN:  %clang_cc1 -std=c++2a -frelaxed-template-template-args -verify %s
 
-template concept C = T::f();
-// expected-note@-1{{similar constraint}}
+template concept C = T::f(); // #C
 template concept D = C && T::g();
-template concept F = T::f();
-// expected-note@-1{{similar constraint expressions not considered equivalent}}
-template class P> struct S1 { }; // expected-note 2{{'P' declared here}}
+template concept F = T::f(); // #F
+template class P> struct S1 { }; // #S1
 
 template struct X { };
-
-template struct Y { }; // expected-note{{'Y' declared here}}
+template struct Y { }; // #Y
 template struct Z { };
-template struct W { }; // expected-note{{'W' declared here}}
+template struct W { }; // #W
 
 S1 s11;
-S1 s12; // expected-error{{template template argument 'Y' is more constrained than template template parameter 'P'}}
+S1 s12;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
 S1 s13;
-S1 s14; // expected-error{{template template argument 'W' is more constrained than template template parameter 'P'}}
+S1 s14;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+// expected-note@#F {{similar constraint expressions not considered equivalent}}
+// expected-note@#C {{similar constraint}}
 
 template class P> struct S2 { };
 
@@ -32,3 +37,27 @@
 
 using s31 = S3;
 using s32 = S3;
+
+template requires C class P> struct S4 { }; // #S4
+
+S4 s41;
+S4 s42;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
+S4 s43;
+S4 s44;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+// expected-note@#F {{similar constraint expressions not considered equivalent}}
+// expected-note@#C {{similar constraint}}
+
+template requires C typename U> struct S5 {
+  template static U V;
+};
+
+struct Nothing {};
+
+// FIXME: Wait the standard to clarify the intent.
+template<> template<> Z S5::V;
Index: clang/lib/Parse/ParseTemplate.cpp
===
--- clang/lib/Parse/ParseTemplate.cpp
+++ clang/lib/Parse/ParseTemplate.cpp
@@ -874,27 +874,39 @@
 /// template parameters.
 ///
 ///   type-parameter:[C++ temp.param]
-/// 'template' '<' template-parameter-list '>' type-parameter-key
-///  ...[opt] identifier[opt]
-/// 'template' '<' template-parameter-list '>' type-parameter-key
-///  identifier[opt] = id-expression
+/// template-head type-parameter-key ...[opt] identifier[opt]
+/// template-head type-parameter-key 

[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-10-03 Thread Liming Liu via Phabricator via cfe-commits
lime added a comment.

I'm wondering whether classes like `TemplateArgumentLoc` could refer to the 
template head of the `TemplateArgument`, so the comparison of parameter 
mappings could be modified, and then the refered variable could be accepted.




Comment at: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp:43
+
+S4 s41;
+S4 s42;

This variable was rejected after rebasing the patch on D126907. The reason is 
that the atomic constraint generated from `S4` is not considered to subsume the 
one generated from `X`. And the difference between two atomic constraints is 
mainly the template arguments. If the concept `C` was like `template  
concept C = true`, this variable would be accepted.

A reasonable behavior might be either accepting the variable regardless of 
whether the constraint expression depends on template arguments, or rejecting 
the variable as the template heads of `S4` and `X` are not equivalent. Both GCC 
and MSVC accept the variable.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-09-30 Thread Liming Liu via Phabricator via cfe-commits
lime updated this revision to Diff 464465.
lime added a comment.

I rearranged the error messages. But after I rebased this patch on D126907 
, the file `p3-2a.cpp` no longer passed. So I 
did some investigations there . The 
problem has not been solved yet.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

Files:
  clang/lib/Parse/ParseTemplate.cpp
  clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
  clang/test/SemaTemplate/concepts.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -912,11 +912,7 @@
 

 https://wg21.link/p0857r0;>P0857R0
-
-  Partial
-Constraining template template parameters is not yet supported.
-  
-
+Clang 16
   

 https://wg21.link/p1084r2;>P1084R2
Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -59,11 +59,10 @@
 x.operator()(); // expected-error {{no matching member function}}
   }
 
-  // FIXME: This is valid under P0857R0.
   template concept C = true;
-  template requires C typename U> struct X {}; // expected-error {{requires 'class'}} expected-error 0+{{}}
+  template requires C typename U> struct X {};
   template requires C struct Y {};
-  X xy; // expected-error {{no template named 'X'}}
+  X xy;
 }
 
 namespace PR50306 {
Index: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
===
--- clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
+++ clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
@@ -1,22 +1,27 @@
 // RUN:  %clang_cc1 -std=c++2a -frelaxed-template-template-args -verify %s
 
-template concept C = T::f();
-// expected-note@-1{{similar constraint}}
+template concept C = T::f(); // #C
 template concept D = C && T::g();
-template concept F = T::f();
-// expected-note@-1{{similar constraint expressions not considered equivalent}}
-template class P> struct S1 { }; // expected-note 2{{'P' declared here}}
+template concept F = T::f(); // #F
+template class P> struct S1 { }; // #S1
 
 template struct X { };
-
-template struct Y { }; // expected-note{{'Y' declared here}}
+template struct Y { }; // #Y
 template struct Z { };
-template struct W { }; // expected-note{{'W' declared here}}
+template struct W { }; // #W
 
 S1 s11;
-S1 s12; // expected-error{{template template argument 'Y' is more constrained than template template parameter 'P'}}
+S1 s12;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
 S1 s13;
-S1 s14; // expected-error{{template template argument 'W' is more constrained than template template parameter 'P'}}
+S1 s14;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S1 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+// expected-note@#F {{similar constraint expressions not considered equivalent}}
+// expected-note@#C {{similar constraint}}
 
 template class P> struct S2 { };
 
@@ -32,3 +37,27 @@
 
 using s31 = S3;
 using s32 = S3;
+
+template requires C class P> struct S4 { }; // #S4
+
+S4 s41;
+S4 s42;
+// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#Y {{'Y' declared here}}
+S4 s43;
+S4 s44;
+// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
+// expected-note@#S4 {{'P' declared here}}
+// expected-note@#W {{'W' declared here}}
+// expected-note@#F {{similar constraint expressions not considered equivalent}}
+// expected-note@#C {{similar constraint}}
+
+template requires C typename U> struct S5 {
+  template static U V;
+};
+
+struct Nothing {};
+
+// FIXME: Wait the standard to clarify the intent.
+template<> template<> Z S5::V;
Index: clang/lib/Parse/ParseTemplate.cpp
===
--- clang/lib/Parse/ParseTemplate.cpp
+++ clang/lib/Parse/ParseTemplate.cpp
@@ -874,27 +874,39 @@
 /// template parameters.
 ///
 ///   type-parameter:[C++ temp.param]
-/// 'template' '<' template-parameter-list '>' type-parameter-key
-///  ...[opt] identifier[opt]
-/// 'template' '<' template-parameter-list '>' type-parameter-key
-///  identifier[opt] = id-expression
+/// template-head 

[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-09-29 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

In D134128#3813708 , @lime wrote:

> Well, Something happened after rebasing this patch on D126907 
> . `s41` below was rejected as the constrain 
> generated from `template ` was no longer considered to subsume the 
> constrain generated from `template  requires C` in the template 
> template argument, which is not the case  in 
> both GCC and MSVC. However, GCC and MSVC also accept the redeclaration for 
> `S`, which might be ill-formed because of this rule 
> . If this kind of 
> redeclaration happens on `X`, GCC and MSVC will reject it. Rebasing this 
> patch on D126907  will also not make the 
> both redeclaration valid.
>
> Personally, I decided to make `s41` valid for Clang, a clue might be making 
> the `QualType`s the same in the parameters of two generated constrains.
>
>   template  concept C = T::f();
>   
>   template  concept C1 = T::f();
>   
>   template  struct X {};
>   
>   template  requires C struct X; // ill-formed for sure
>   
>   template  struct Y {};
>   
>   template  requires C class> struct S {};
>   
>   template  class> struct S; // GCC and MSVC accept this
>   
>   S sx; // my target
>   S sy; // ill-formed for sure

I'm not sure I get the issue here, there are some identifiers you're using that 
don't make sense to me.  I don't see that test in the lit tests either, could 
you make sure it is reflected there and commented?  ALso, can you re-arrange 
the error messages as I requested?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-09-25 Thread Liming Liu via Phabricator via cfe-commits
lime added a comment.

Well, Something happened after rebasing this patch on D126907 
. `s41` below was rejected as the constrain 
generated from `template ` was no longer considered to subsume the constrain 
generated from `template  requires C` in the template template 
argument, which is not the case  in both GCC 
and MSVC. However, GCC and MSVC also accept the redeclaration for `S`, which 
might be ill-formed because of this rule 
. If this kind of 
redeclaration happens on `X`, GCC and MSVC will reject it. Rebasing this patch 
on D126907  will also not make the both 
redeclaration valid.

Personally, I decided to make `s41` valid for Clang, a clue might be making the 
`QualType`s the same in the parameters of two generated constrains.

  template  concept C = T::f();
  
  template  concept C1 = T::f();
  
  template  struct X {};
  
  template  requires C struct X; // ill-formed for sure
  
  template  struct Y {};
  
  template  requires C class> struct S {};
  
  template  class> struct S; // GCC and MSVC accept this
  
  S sx; // my target
  S sy; // ill-formed for sure


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-09-21 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

In D134128#3805675 , @lime wrote:

> I have not looked deep into D126907 , but 
> the rule it referred seems related to something as follows:
>
>   template  concept C = true;
>   
>   template 
>   struct S1 {
>   template  U> typename> friend void foo() {}
>   };
>   
>   // Does the rule say these two functions are not the same?
>   template 
>   struct S2 {
>   template  U> typename> friend void foo() {}
>   };
>
> BTW, I could not image a non-template friend declaration with a 
> requires-clause...

You edited while I was answering, but I believe the answer is the same: those 
are not the same thanks to temp.friend p9.

That D126907  is actually NOT just the 
friends, this is an entire omnibus "fix the deferred concepts implementation".  
The original concepts implementation used a greedy instantiation mechanism, 
which is unfortunately not permitted by the standard.  This patch is delaying 
the concept instantiation until it is required for checking.  Along the way 
that 'friend' example was run across.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-09-21 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

In D134128#3805675 , @lime wrote:

> I have not looked deep into D126907 , but 
> the rule it referred seems related to something as follows:

You shouldn't have to look 'deep' into it, just rebase and see what happens.  
Note that it has not been committed yet, so you'll have to manually apply it.

>   template  concept C = true;
>   
>   template 
>   struct S {
>   template  U> typename> friend void foo(S) {}
>   };
>   
>   // Does the rule say these two are not the same?
>   template  T> typename> S foo(S s) { return s; }

Right, those are not the same because of: https://eel.is/c++draft/temp.friend#9


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-09-21 Thread Liming Liu via Phabricator via cfe-commits
lime added a comment.

I have not looked deep into D126907 , but the 
rule it referred seems related to something as follows:

  template  concept C = true;
  
  template 
  struct S {
  template  U> typename> friend void foo(S) {}
  };
  
  // Does the rule say these two are not the same?
  template  T> typename> S foo(S s) { return s; }


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-09-19 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

One test that i need to have (that might actually end up conflicting with the 
above mentioned), is a reproducer that has a `ClassTemplateDecl` that is its 
own friend.  So something like:

  template class C requires ...>
  struct S {
  template class C requires ...>
  friend struct S;
  };

And make sure that an instantiation still checks those correctly (that is, I 
don't expect any diagnostics).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-09-19 Thread Erich Keane via Phabricator via cfe-commits
erichkeane added a comment.

Thanks for taking this over!  FIRST, please make sure you re-submit this with 
the entire 'context' (see context-not-available), by making sure you use 
-U99 on your patch before uploading it.

It DOES appear from the tests that we're already checking everything we're 
supposed to?

ALSO, could you please try rebasing this on top of 
"https://reviews.llvm.org/D126907; to see if it causes any further issues for 
that?  I'm nearing a solution to my last problem on that, and would love to get 
that submitted in the next week or two, and knowing if this/these tests are 
going to break it would be an appreciated heads-up.




Comment at: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp:39
+S4 s41;
+S4 s42; // expected-error{{template template argument 'Y' is more 
constrained than template template parameter 'P'}}
+S4 s43;

I realize the rest of the test does a poor job of this, but can you better 
arrange the new diagnostics for me, rather thanputting the 'note's on teh 
individual lines?  

I prefer to have them in 'emitted order' next to the error/warning that caused 
the notes. You can do an "@" on 'expected-note' that refers to a different line 
by putting a `// #SOME_BOOKMARK_NAME` on the line that has the note, and 
`expected-note@#SOME_BOOKMARK_NAME` here.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-09-18 Thread Liming Liu via Phabricator via cfe-commits
lime added a comment.

In D134128#3798127 , @cor3ntin wrote:

> Thanks for working on this.
> I'll be honest though, I still have absolutely no understanding what the use 
> cases or intents of this features are. I think we were waiting for core to 
> clarify and I'm not sure they did.
> This does seem to implement the wording though...

Perhaps, the intents of this feature are a little confusing, so I add `S5` in 
the file `p3-2a.cpp`. If it was necessary to check the constains on the 
template template parameter, we could expect an error there.

But one intent might be a mend of the tailing syntax about constains, as a 
template parameter like `template  typename` is already accepted by Clang.




Comment at: clang/lib/Parse/ParseTemplate.cpp:882
 /// 'typename'   [C++1z]
-NamedDecl *
-Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
+///   template-head: [C++2a]
+/// 'template' '<' template-parameter-list '>'

This is copied from `Parser::ParseTemplateDeclarationOrSpecialization`.



Comment at: clang/lib/Parse/ParseTemplate.cpp:909
+  }
+}
   }

It is fine to skip the check for the language option of C++20. The parser will 
emit an error here and complain the lack of `class` or `typename`, if the 
option is not provided.



Comment at: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp:36
+
+template requires C class P> struct S4 { }; // 
expected-note 2{{'P' declared here}}
+

Test whether Clang behaves the same here as it is on `S1`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-09-18 Thread Corentin Jabot via Phabricator via cfe-commits
cor3ntin added a comment.

Thanks for working on this.
I'll be honest though, I still have absolutely no understanding what the use 
cases or intents of this features are. I think we were waiting for core to 
clarify and I'm not sure they did.
This does seem to implement the wording though...


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134128/new/

https://reviews.llvm.org/D134128

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D134128: Resubmit an implemention for constrained template template parameters [P0857R0 Part B]

2022-09-18 Thread Liming Liu via Phabricator via cfe-commits
lime created this revision.
lime added reviewers: aaron.ballman, h-vetinari, erichkeane, cor3ntin, 
tahonermann.
lime added a project: clang.
Herald added a project: All.
lime requested review of this revision.
Herald added a subscriber: cfe-commits.

This function had been submitted by @erichkeane long time ago 
. However, he has not been 

 working on it. So I submit a new patch with some minor differences.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D134128

Files:
  clang/lib/Parse/ParseTemplate.cpp
  clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
  clang/test/SemaTemplate/concepts.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -912,11 +912,7 @@
 

 https://wg21.link/p0857r0;>P0857R0
-
-  Partial
-Constraining template template parameters is not yet supported.
-  
-
+Clang 16
   

 https://wg21.link/p1084r2;>P1084R2
Index: clang/test/SemaTemplate/concepts.cpp
===
--- clang/test/SemaTemplate/concepts.cpp
+++ clang/test/SemaTemplate/concepts.cpp
@@ -59,11 +59,10 @@
 x.operator()(); // expected-error {{no matching member function}}
   }
 
-  // FIXME: This is valid under P0857R0.
   template concept C = true;
-  template requires C typename U> struct X {}; // expected-error {{requires 'class'}} expected-error 0+{{}}
+  template requires C typename U> struct X {};
   template requires C struct Y {};
-  X xy; // expected-error {{no template named 'X'}}
+  X xy;
 }
 
 namespace PR50306 {
Index: clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
===
--- clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
+++ clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
@@ -1,17 +1,17 @@
 // RUN:  %clang_cc1 -std=c++2a -frelaxed-template-template-args -verify %s
 
 template concept C = T::f();
-// expected-note@-1{{similar constraint}}
+// expected-note@-1 2{{similar constraint}}
 template concept D = C && T::g();
 template concept F = T::f();
-// expected-note@-1{{similar constraint expressions not considered equivalent}}
+// expected-note@-1 2{{similar constraint expressions not considered equivalent}}
 template class P> struct S1 { }; // expected-note 2{{'P' declared here}}
 
 template struct X { };
 
-template struct Y { }; // expected-note{{'Y' declared here}}
+template struct Y { }; // expected-note 2{{'Y' declared here}}
 template struct Z { };
-template struct W { }; // expected-note{{'W' declared here}}
+template struct W { }; // expected-note 2{{'W' declared here}}
 
 S1 s11;
 S1 s12; // expected-error{{template template argument 'Y' is more constrained than template template parameter 'P'}}
@@ -32,3 +32,19 @@
 
 using s31 = S3;
 using s32 = S3;
+
+template requires C class P> struct S4 { }; // expected-note 2{{'P' declared here}}
+
+S4 s41;
+S4 s42; // expected-error{{template template argument 'Y' is more constrained than template template parameter 'P'}}
+S4 s43;
+S4 s44; // expected-error{{template template argument 'W' is more constrained than template template parameter 'P'}}
+
+template requires C typename U> struct S5 {
+  template static U V;
+};
+
+struct Nothing {};
+
+// FIXME: Wait the standard to clarify the intent.
+template<> template<> Z S5::V;
Index: clang/lib/Parse/ParseTemplate.cpp
===
--- clang/lib/Parse/ParseTemplate.cpp
+++ clang/lib/Parse/ParseTemplate.cpp
@@ -874,27 +874,39 @@
 /// template parameters.
 ///
 ///   type-parameter:[C++ temp.param]
-/// 'template' '<' template-parameter-list '>' type-parameter-key
-///  ...[opt] identifier[opt]
-/// 'template' '<' template-parameter-list '>' type-parameter-key
-///  identifier[opt] = id-expression
+/// template-head type-parameter-key ...[opt] identifier[opt]
+/// template-head type-parameter-key identifier[opt] = id-expression
 ///   type-parameter-key:
 /// 'class'
 /// 'typename'   [C++1z]
-NamedDecl *
-Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) {
+///   template-head: [C++2a]
+/// 'template' '<' template-parameter-list '>'
+/// requires-clause[opt]
+NamedDecl *Parser::ParseTemplateTemplateParameter(unsigned Depth,
+  unsigned Position) {
   assert(Tok.is(tok::kw_template) && "Expected 'template' keyword");
 
   // Handle the template <...> part.
   SourceLocation TemplateLoc = ConsumeToken();
   SmallVector TemplateParams;