[PATCH] D41284: [Concepts] Associated constraints infrastructure.
rsmith accepted this revision. rsmith added inline comments. This revision is now accepted and ready to land. Comment at: clang/include/clang/Sema/Sema.h:5950 + /// associated constraints of an older declaration of which it is a + /// redeclaration + bool CheckRedeclarationConstraintMatch(TemplateParameterList *Old, Missing period. Comment at: clang/test/CXX/concepts-ts/temp/concept/p4.cpp:1 +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -verify %s + Please move this test and the others to the relevant place under `test/CXX/temp` rather than `test/CXX/concepts-ts` and remove `-fconcepts-ts` from the `RUN:` lines. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D41284/new/ https://reviews.llvm.org/D41284 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
saar.raz updated this revision to Diff 224898. saar.raz marked 15 inline comments as done. saar.raz added a comment. Remove unrelated cleanup Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D41284/new/ https://reviews.llvm.org/D41284 Files: clang/include/clang/AST/ASTNodeTraverser.h clang/include/clang/AST/DeclTemplate.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Sema/Sema.h clang/lib/AST/ASTContext.cpp clang/lib/AST/DeclTemplate.cpp clang/lib/Sema/SemaConcept.cpp clang/lib/Sema/SemaTemplate.cpp clang/lib/Sema/SemaTemplateInstantiateDecl.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTReaderDecl.cpp clang/lib/Serialization/ASTWriter.cpp clang/lib/Serialization/ASTWriterDecl.cpp clang/test/CXX/concepts-ts/temp/concept/p4.cpp clang/test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp clang/test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp clang/test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp Index: clang/test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp === --- /dev/null +++ clang/test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +namespace nodiag { + +struct B { +template requires bool(T()) +static int A; +}; + +template requires bool(U()) +int B::A = int(U()); + +} // end namespace nodiag + +namespace diag { + +struct B { +template requires bool(T()) // expected-note{{previous template declaration is here}} +static int A; +}; + +template requires !bool(U()) // expected-error{{requires clause differs in template redeclaration}} +int B::A = int(U()); + +} // end namespace diag \ No newline at end of file Index: clang/test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp === --- /dev/null +++ clang/test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +namespace nodiag { + +template requires bool(T()) +int A(); +template requires bool(U()) +int A(); + +} // end namespace nodiag + +namespace diag { + +namespace orig { + template requires true + int A(); + template + int B(); + template requires true + int C(); +} + +template +int orig::A(); +// expected-error@-1{{out-of-line declaration of 'A' does not match any declaration in namespace 'diag::orig'}} +template requires true +int orig::B(); +// expected-error@-1{{out-of-line declaration of 'B' does not match any declaration in namespace 'diag::orig'}} +template requires !0 +int orig::C(); +// expected-error@-1{{out-of-line declaration of 'C' does not match any declaration in namespace 'diag::orig'}} + +} // end namespace diag + +namespace nodiag { + +struct AA { + template requires someFunc(T()) + int A(); +}; + +template requires someFunc(T()) +int AA::A() { return sizeof(T); } + +} // end namespace nodiag + +namespace diag { + +template +struct TA { + template class TT> requires TT::happy + int A(); +}; + +template +template class TT> int TA::A() { return sizeof(TT); } +// expected-error@-1{{out-of-line definition of 'A' does not match any declaration in 'TA'}} + +} // end namespace diag Index: clang/test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp === --- clang/test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp +++ clang/test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { @@ -13,15 +13,15 @@ template requires true // expected-note{{previous template declaration is here}} struct A; -template struct A; // expected-error{{associated constraints differ in template redeclaration}} +template struct A; // expected-error{{requires clause differs in template redeclaration}} template struct B; // expected-note{{previous template declaration is here}} -template requires true // expected-error{{associated constraints differ in template redeclaration}} +template requires true // expected-error{{requires clause differs in template redeclaration}} struct B; template requires true // expected-note{{previous template declaration is here}} struct C; -template requires !0 // expected-error{{associated constraints differ in template redeclaration}} +template requires !0 // expected-error{{requires clause differs in template redeclaration}} struct C; } /
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
saar.raz updated this revision to Diff 209688. saar.raz added a comment. Rebase onto trunk. Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D41284/new/ https://reviews.llvm.org/D41284 Files: include/clang/AST/ASTNodeTraverser.h include/clang/AST/DeclTemplate.h include/clang/AST/RecursiveASTVisitor.h include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Sema.h lib/AST/ASTContext.cpp lib/AST/DeclTemplate.cpp lib/Sema/SemaConcept.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp lib/Serialization/ASTWriterDecl.cpp test/CXX/concepts-ts/temp/concept/p4.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp === --- /dev/null +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +namespace nodiag { + +struct B { +template requires bool(T()) +static int A; +}; + +template requires bool(U()) +int B::A = int(U()); + +} // end namespace nodiag + +namespace diag { + +struct B { +template requires bool(T()) // expected-note{{previous template declaration is here}} +static int A; +}; + +template requires !bool(U()) // expected-error{{requires clause differs in template redeclaration}} +int B::A = int(U()); + +} // end namespace diag \ No newline at end of file Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp === --- /dev/null +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +namespace nodiag { + +template requires bool(T()) +int A(); +template requires bool(U()) +int A(); + +} // end namespace nodiag + +namespace diag { + +namespace orig { + template requires true + int A(); + template + int B(); + template requires true + int C(); +} + +template +int orig::A(); +// expected-error@-1{{out-of-line declaration of 'A' does not match any declaration in namespace 'diag::orig'}} +template requires true +int orig::B(); +// expected-error@-1{{out-of-line declaration of 'B' does not match any declaration in namespace 'diag::orig'}} +template requires !0 +int orig::C(); +// expected-error@-1{{out-of-line declaration of 'C' does not match any declaration in namespace 'diag::orig'}} + +} // end namespace diag + +namespace nodiag { + +struct AA { + template requires someFunc(T()) + int A(); +}; + +template requires someFunc(T()) +int AA::A() { return sizeof(T); } + +} // end namespace nodiag + +namespace diag { + +template +struct TA { + template class TT> requires TT::happy + int A(); +}; + +template +template class TT> int TA::A() { return sizeof(TT); } +// expected-error@-1{{out-of-line definition of 'A' does not match any declaration in 'TA'}} + +} // end namespace diag Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp === --- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { @@ -13,15 +13,15 @@ template requires true // expected-note{{previous template declaration is here}} struct A; -template struct A; // expected-error{{associated constraints differ in template redeclaration}} +template struct A; // expected-error{{requires clause differs in template redeclaration}} template struct B; // expected-note{{previous template declaration is here}} -template requires true // expected-error{{associated constraints differ in template redeclaration}} +template requires true // expected-error{{requires clause differs in template redeclaration}} struct B; template requires true // expected-note{{previous template declaration is here}} struct C; -template requires !0 // expected-error{{associated constraints differ in template redeclaration}} +template requires !0 // expected-error{{requires clause differs in template redeclaration}} struct C; } // end namespace diag @@ -33,7 +33,7 @@ struct A; }; -template requires someFunc(T()) +template requires someFunc(U()) struct AA::A { }; struct AAF { @@ -47,18 +47,26 @@ template struct TA { - template
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
saar.raz updated this revision to Diff 196074. saar.raz added a comment. - Address CR comments by rsmith - Remove obsolete TODOs - Fix redeclaration checking - Change getAssociatedConstraints interface - Add requires clause to ASTNodeTraverser Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D41284/new/ https://reviews.llvm.org/D41284 Files: include/clang/AST/ASTNodeTraverser.h include/clang/AST/DeclTemplate.h include/clang/AST/RecursiveASTVisitor.h include/clang/Basic/DiagnosticSemaKinds.td include/clang/Sema/Sema.h lib/AST/ASTContext.cpp lib/AST/DeclTemplate.cpp lib/Sema/SemaConcept.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp lib/Serialization/ASTWriterDecl.cpp test/CXX/concepts-ts/temp/concept/p4.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp === --- /dev/null +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +namespace nodiag { + +struct B { +template requires bool(T()) +static int A; +}; + +template requires bool(U()) +int B::A = int(U()); + +} // end namespace nodiag + +namespace diag { + +struct B { +template requires bool(T()) // expected-note{{previous template declaration is here}} +static int A; +}; + +template requires !bool(U()) // expected-error{{requires clause differs in template redeclaration}} +int B::A = int(U()); + +} // end namespace diag \ No newline at end of file Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp === --- /dev/null +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +namespace nodiag { + +template requires bool(T()) +int A(); +template requires bool(U()) +int A(); + +} // end namespace nodiag + +namespace diag { + +namespace orig { + template requires true + int A(); + template + int B(); + template requires true + int C(); +} + +template +int orig::A(); +// expected-error@-1{{out-of-line declaration of 'A' does not match any declaration in namespace 'diag::orig'}} +template requires true +int orig::B(); +// expected-error@-1{{out-of-line declaration of 'B' does not match any declaration in namespace 'diag::orig'}} +template requires !0 +int orig::C(); +// expected-error@-1{{out-of-line declaration of 'C' does not match any declaration in namespace 'diag::orig'}} + +} // end namespace diag + +namespace nodiag { + +struct AA { + template requires someFunc(T()) + int A(); +}; + +template requires someFunc(T()) +int AA::A() { return sizeof(T); } + +} // end namespace nodiag + +namespace diag { + +template +struct TA { + template class TT> requires TT::happy + int A(); +}; + +template +template class TT> int TA::A() { return sizeof(TT); } +// expected-error@-1{{out-of-line definition of 'A' does not match any declaration in 'TA'}} + +} // end namespace diag Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp === --- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { @@ -13,15 +13,15 @@ template requires true // expected-note{{previous template declaration is here}} struct A; -template struct A; // expected-error{{associated constraints differ in template redeclaration}} +template struct A; // expected-error{{requires clause differs in template redeclaration}} template struct B; // expected-note{{previous template declaration is here}} -template requires true // expected-error{{associated constraints differ in template redeclaration}} +template requires true // expected-error{{requires clause differs in template redeclaration}} struct B; template requires true // expected-note{{previous template declaration is here}} struct C; -template requires !0 // expected-error{{associated constraints differ in template redeclaration}} +template requires !0 // expected-error{{requires clause differs in template redeclaration}} struct C; } // end namespace diag @@ -33,7 +33,7 @@ struct A; }; -t
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
rsmith added inline comments. Comment at: include/clang/AST/DeclTemplate.h:177 + /// conjunction ("and"). + llvm::SmallVector getAssociatedConstraints() const; + Returning a `SmallVector` by value is not idiomatic. If you need to make a copy here, you should take a `SmallVectorImpl` by reference, so the caller can choose the inline size. If not, you should return an `ArrayRef`. Comment at: include/clang/Sema/Sema.h:5772-5776 + /// \brief Check that the associated constraints of a template declaration + /// match the associated constraints of an older declaration of which it is a + /// redeclaration + bool CheckRedeclarationConstraintMatch(ArrayRef OldAC, + ArrayRef NewAC); This is not how redeclaration checking is specified any more. A redeclaration is valid only if its //template-head// is equivalent to that of the prior declaration, not if it has the same associated constraints. You should instead take two `TemplateParameterList`s, profile them, and compare the results. Comment at: lib/Serialization/ASTReaderDecl.cpp:2375 D->ParameterPack = Record.readInt(); +// TODO: Concepts: Constrained parameters if (Record.readInt()) There's no such thing any more. Comment at: lib/Serialization/ASTReaderDecl.cpp:2393 // Rest of TemplateTemplateParmDecl. +// TODO: Concepts: Constrained parameters D->ParameterPack = Record.readInt(); There's no such thing any more. Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D41284/new/ https://reviews.llvm.org/D41284 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
saar.raz updated this revision to Diff 194984. saar.raz added a comment. Rebase onto trunk Repository: rC Clang CHANGES SINCE LAST ACTION https://reviews.llvm.org/D41284/new/ https://reviews.llvm.org/D41284 Files: include/clang/AST/DeclTemplate.h include/clang/AST/RecursiveASTVisitor.h include/clang/Sema/Sema.h lib/AST/ASTContext.cpp lib/AST/DeclTemplate.cpp lib/Sema/SemaConcept.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp lib/Serialization/ASTWriterDecl.cpp test/CXX/concepts-ts/temp/concept/p4.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp === --- /dev/null +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +namespace nodiag { + +struct B { +template requires bool(T()) +static int A; +}; + +template requires bool(U()) +int B::A = int(U()); + +} // end namespace nodiag + +namespace diag { + +struct B { +template requires bool(T()) // expected-note{{previous template declaration is here}} +static int A; +}; + +template requires !bool(U()) // expected-error{{associated constraints differ in template redeclaration}} +int B::A = int(U()); + +} // end namespace diag \ No newline at end of file Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp === --- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp @@ -1,28 +1,28 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { template requires bool(T()) -struct A; +int A(); template requires bool(U()) -struct A; +int A(); } // end namespace nodiag namespace diag { template requires true // expected-note{{previous template declaration is here}} -struct A; -template struct A; // expected-error{{associated constraints differ in template redeclaration}} +int A(); +template int A(); // expected-error{{associated constraints differ in template redeclaration}} -template struct B; // expected-note{{previous template declaration is here}} +template int B(); // expected-note{{previous template declaration is here}} template requires true // expected-error{{associated constraints differ in template redeclaration}} -struct B; +int B(); template requires true // expected-note{{previous template declaration is here}} -struct C; +int C(); template requires !0 // expected-error{{associated constraints differ in template redeclaration}} -struct C; +int C(); } // end namespace diag @@ -30,16 +30,11 @@ struct AA { template requires someFunc(T()) - struct A; + int A(); }; template requires someFunc(T()) -struct AA::A { }; - -struct AAF { - template requires someFunc(T()) - friend struct AA::A; -}; +int AA::A() { return sizeof(T); } } // end namespace nodiag @@ -47,19 +42,11 @@ template struct TA { - template class TT> requires TT::happy // expected-note 2{{previous template declaration is here}} - struct A; - - struct AF; + template class TT> requires TT::happy // expected-note{{previous template declaration is here}} + int A(); }; template -template class TT> struct TA::A { }; // expected-error{{associated constraints differ in template redeclaration}} - -template -struct TA::AF { - template class TT> requires TT::happy // expected-error{{associated constraints differ in template redeclaration}} - friend struct TA::A; -}; +template class TT> int TA::A() { return sizeof(TT); } // expected-error{{associated constraints differ in template redeclaration}} } // end namespace diag Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp === --- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { @@ -33,7 +33,7 @@ struct A; }; -template requires someFunc(T()) +template requires someFunc(U()) struct AA::A { }; struct AAF { @@ -47,18 +47,26 @@ template struct TA { - template class TT> requires TT::happy //
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
Quuxplusone added inline comments. Comment at: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp:10 + +template requires bool(U()) +int B::A = int(U()); saar.raz wrote: > saar.raz wrote: > > Rakete wrote: > > > Quuxplusone wrote: > > > > saar.raz wrote: > > > > > Quuxplusone wrote: > > > > > > For my own edification, could you explain whether, given > > > > > > > > > > > > #define BOOL bool > > > > > > using typedef_for_bool = bool; > > > > > > > > > > > > you'd expect to diagnose a redeclaration of `B::A` with associated > > > > > > constraint > > > > > > > > > > > > requires bool( U() ) // extra whitespace > > > > > > > > > > > > or > > > > > > > > > > > > requires BOOL(U()) // different spelling of `bool` > > > > > > > > > > > > or > > > > > > > > > > > > requires typedef_for_bool(U()) // different spelling of `bool` > > > > > > > > > > > > ? My naive reading of N4762 temp.constr.atomic/2 says that none of > > > > > > these constraints (on line 10) would be "identical" to the > > > > > > constraint on line 6... but then I don't understand what's the > > > > > > salient difference between line 10 (which apparently gives no > > > > > > error) and line 22 (which apparently gives an error). > > > > > Line 22 has a not (!) operator in front of the bool(), I guess you > > > > > missed that? > > > > I saw the `!`... but I don't understand how the compiler "knows" that > > > > `!bool(U())` is "different" from `bool(T())` in a way that doesn't > > > > equally apply to `bool(U())`. > > > > > > > > Or suppose the constraint on line 10 was `requires bool(U())==true`... > > > > would that give a diagnostic? > > > `bool(T())` and `bool(U())` are identical because they have the same > > > parameter mappings. > > > > > > The "identical" requirement applies to the actual grammar composition of > > > the expression, so `bool(T())` would be different to `bool(T()) == true`. > > > > > > At least that's how I understand it. > > OK, I can see where the confusion is coming from. > > > > The way it works (in clang, at least) - is that the compiler pays no > > attention to the name of a template parameter for any purpose other than > > actually finding it in the first place - once it is found, it is 'stored' > > simply as bool(()) where the first 0 is the depth > > of the template parameter list of the parameter in question (in case of a > > template within a template) and the second 0 is the index of the template > > parameter within that list. > > > > I believe this treatment stems from [temp.over.link]p6 "When determining > > whether types or qualified-concept-names are equivalent, the rules above > > are used to compare expressions involving template parameters" > Correction - p5 describes this better (see also the example in p4) Okay, I can see how this matches the apparent intent of http://eel.is/c++draft/temp.over.link#5 . I guess a strict reading of that passage would mean that my `BOOL` and `typedef_for_bool` versions should give diagnostics, and so should ``` #define V(x) U template requires bool(V(x) ()) ``` but no diagnostic is expected for ``` #define V U template requires bool(V ()) ``` Anyway, sounds like this rabbit hole is out-of-scope for this review, anyway, so I'll be quiet now. :) Repository: rC Clang https://reviews.llvm.org/D41284 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
saar.raz added inline comments. Comment at: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp:10 + +template requires bool(U()) +int B::A = int(U()); saar.raz wrote: > Rakete wrote: > > Quuxplusone wrote: > > > saar.raz wrote: > > > > Quuxplusone wrote: > > > > > For my own edification, could you explain whether, given > > > > > > > > > > #define BOOL bool > > > > > using typedef_for_bool = bool; > > > > > > > > > > you'd expect to diagnose a redeclaration of `B::A` with associated > > > > > constraint > > > > > > > > > > requires bool( U() ) // extra whitespace > > > > > > > > > > or > > > > > > > > > > requires BOOL(U()) // different spelling of `bool` > > > > > > > > > > or > > > > > > > > > > requires typedef_for_bool(U()) // different spelling of `bool` > > > > > > > > > > ? My naive reading of N4762 temp.constr.atomic/2 says that none of > > > > > these constraints (on line 10) would be "identical" to the constraint > > > > > on line 6... but then I don't understand what's the salient > > > > > difference between line 10 (which apparently gives no error) and line > > > > > 22 (which apparently gives an error). > > > > Line 22 has a not (!) operator in front of the bool(), I guess you > > > > missed that? > > > I saw the `!`... but I don't understand how the compiler "knows" that > > > `!bool(U())` is "different" from `bool(T())` in a way that doesn't > > > equally apply to `bool(U())`. > > > > > > Or suppose the constraint on line 10 was `requires bool(U())==true`... > > > would that give a diagnostic? > > `bool(T())` and `bool(U())` are identical because they have the same > > parameter mappings. > > > > The "identical" requirement applies to the actual grammar composition of > > the expression, so `bool(T())` would be different to `bool(T()) == true`. > > > > At least that's how I understand it. > OK, I can see where the confusion is coming from. > > The way it works (in clang, at least) - is that the compiler pays no > attention to the name of a template parameter for any purpose other than > actually finding it in the first place - once it is found, it is 'stored' > simply as bool(()) where the first 0 is the depth of > the template parameter list of the parameter in question (in case of a > template within a template) and the second 0 is the index of the template > parameter within that list. > > I believe this treatment stems from [temp.over.link]p6 "When determining > whether types or qualified-concept-names are equivalent, the rules above are > used to compare expressions involving template parameters" Correction - p5 describes this better (see also the example in p4) Repository: rC Clang https://reviews.llvm.org/D41284 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
saar.raz added inline comments. Comment at: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp:10 + +template requires bool(U()) +int B::A = int(U()); Rakete wrote: > Quuxplusone wrote: > > saar.raz wrote: > > > Quuxplusone wrote: > > > > For my own edification, could you explain whether, given > > > > > > > > #define BOOL bool > > > > using typedef_for_bool = bool; > > > > > > > > you'd expect to diagnose a redeclaration of `B::A` with associated > > > > constraint > > > > > > > > requires bool( U() ) // extra whitespace > > > > > > > > or > > > > > > > > requires BOOL(U()) // different spelling of `bool` > > > > > > > > or > > > > > > > > requires typedef_for_bool(U()) // different spelling of `bool` > > > > > > > > ? My naive reading of N4762 temp.constr.atomic/2 says that none of > > > > these constraints (on line 10) would be "identical" to the constraint > > > > on line 6... but then I don't understand what's the salient difference > > > > between line 10 (which apparently gives no error) and line 22 (which > > > > apparently gives an error). > > > Line 22 has a not (!) operator in front of the bool(), I guess you missed > > > that? > > I saw the `!`... but I don't understand how the compiler "knows" that > > `!bool(U())` is "different" from `bool(T())` in a way that doesn't equally > > apply to `bool(U())`. > > > > Or suppose the constraint on line 10 was `requires bool(U())==true`... > > would that give a diagnostic? > `bool(T())` and `bool(U())` are identical because they have the same > parameter mappings. > > The "identical" requirement applies to the actual grammar composition of the > expression, so `bool(T())` would be different to `bool(T()) == true`. > > At least that's how I understand it. OK, I can see where the confusion is coming from. The way it works (in clang, at least) - is that the compiler pays no attention to the name of a template parameter for any purpose other than actually finding it in the first place - once it is found, it is 'stored' simply as bool(()) where the first 0 is the depth of the template parameter list of the parameter in question (in case of a template within a template) and the second 0 is the index of the template parameter within that list. I believe this treatment stems from [temp.over.link]p6 "When determining whether types or qualified-concept-names are equivalent, the rules above are used to compare expressions involving template parameters" Repository: rC Clang https://reviews.llvm.org/D41284 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
Rakete added inline comments. Comment at: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp:10 + +template requires bool(U()) +int B::A = int(U()); Quuxplusone wrote: > saar.raz wrote: > > Quuxplusone wrote: > > > For my own edification, could you explain whether, given > > > > > > #define BOOL bool > > > using typedef_for_bool = bool; > > > > > > you'd expect to diagnose a redeclaration of `B::A` with associated > > > constraint > > > > > > requires bool( U() ) // extra whitespace > > > > > > or > > > > > > requires BOOL(U()) // different spelling of `bool` > > > > > > or > > > > > > requires typedef_for_bool(U()) // different spelling of `bool` > > > > > > ? My naive reading of N4762 temp.constr.atomic/2 says that none of these > > > constraints (on line 10) would be "identical" to the constraint on line > > > 6... but then I don't understand what's the salient difference between > > > line 10 (which apparently gives no error) and line 22 (which apparently > > > gives an error). > > Line 22 has a not (!) operator in front of the bool(), I guess you missed > > that? > I saw the `!`... but I don't understand how the compiler "knows" that > `!bool(U())` is "different" from `bool(T())` in a way that doesn't equally > apply to `bool(U())`. > > Or suppose the constraint on line 10 was `requires bool(U())==true`... would > that give a diagnostic? `bool(T())` and `bool(U())` are identical because they have the same parameter mappings. The "identical" requirement applies to the actual grammar composition of the expression, so `bool(T())` would be different to `bool(T()) == true`. At least that's how I understand it. Repository: rC Clang https://reviews.llvm.org/D41284 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
Quuxplusone added inline comments. Comment at: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp:10 + +template requires bool(U()) +int B::A = int(U()); saar.raz wrote: > Quuxplusone wrote: > > For my own edification, could you explain whether, given > > > > #define BOOL bool > > using typedef_for_bool = bool; > > > > you'd expect to diagnose a redeclaration of `B::A` with associated > > constraint > > > > requires bool( U() ) // extra whitespace > > > > or > > > > requires BOOL(U()) // different spelling of `bool` > > > > or > > > > requires typedef_for_bool(U()) // different spelling of `bool` > > > > ? My naive reading of N4762 temp.constr.atomic/2 says that none of these > > constraints (on line 10) would be "identical" to the constraint on line > > 6... but then I don't understand what's the salient difference between line > > 10 (which apparently gives no error) and line 22 (which apparently gives an > > error). > Line 22 has a not (!) operator in front of the bool(), I guess you missed > that? I saw the `!`... but I don't understand how the compiler "knows" that `!bool(U())` is "different" from `bool(T())` in a way that doesn't equally apply to `bool(U())`. Or suppose the constraint on line 10 was `requires bool(U())==true`... would that give a diagnostic? Repository: rC Clang https://reviews.llvm.org/D41284 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
saar.raz added inline comments. Comment at: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp:10 + +template requires bool(U()) +int B::A = int(U()); Quuxplusone wrote: > For my own edification, could you explain whether, given > > #define BOOL bool > using typedef_for_bool = bool; > > you'd expect to diagnose a redeclaration of `B::A` with associated constraint > > requires bool( U() ) // extra whitespace > > or > > requires BOOL(U()) // different spelling of `bool` > > or > > requires typedef_for_bool(U()) // different spelling of `bool` > > ? My naive reading of N4762 temp.constr.atomic/2 says that none of these > constraints (on line 10) would be "identical" to the constraint on line 6... > but then I don't understand what's the salient difference between line 10 > (which apparently gives no error) and line 22 (which apparently gives an > error). Line 22 has a not (!) operator in front of the bool(), I guess you missed that? Repository: rC Clang https://reviews.llvm.org/D41284 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
Quuxplusone added inline comments. Comment at: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp:10 + +template requires bool(U()) +int B::A = int(U()); For my own edification, could you explain whether, given #define BOOL bool using typedef_for_bool = bool; you'd expect to diagnose a redeclaration of `B::A` with associated constraint requires bool( U() ) // extra whitespace or requires BOOL(U()) // different spelling of `bool` or requires typedef_for_bool(U()) // different spelling of `bool` ? My naive reading of N4762 temp.constr.atomic/2 says that none of these constraints (on line 10) would be "identical" to the constraint on line 6... but then I don't understand what's the salient difference between line 10 (which apparently gives no error) and line 22 (which apparently gives an error). Repository: rC Clang https://reviews.llvm.org/D41284 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
saar.raz updated this revision to Diff 161345. saar.raz added a comment. - Fix bad reference to getRequiresClause on TemplateDecl in assertion Repository: rC Clang https://reviews.llvm.org/D41284 Files: include/clang/AST/DeclTemplate.h include/clang/AST/RecursiveASTVisitor.h include/clang/Sema/Sema.h lib/AST/ASTContext.cpp lib/AST/DeclTemplate.cpp lib/Sema/SemaConcept.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp lib/Serialization/ASTWriterDecl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp === --- /dev/null +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +namespace nodiag { + +struct B { +template requires bool(T()) +static int A; +}; + +template requires bool(U()) +int B::A = int(U()); + +} // end namespace nodiag + +namespace diag { + +struct B { +template requires bool(T()) // expected-note{{previous template declaration is here}} +static int A; +}; + +template requires !bool(U()) // expected-error{{associated constraints differ in template redeclaration}} +int B::A = int(U()); + +} // end namespace diag \ No newline at end of file Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp === --- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp @@ -1,65 +1,52 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { template requires bool(T()) -struct A; +int A(); template requires bool(U()) -struct A; +int A(); } // end namespace nodiag namespace diag { template requires true // expected-note{{previous template declaration is here}} -struct A; -template struct A; // expected-error{{associated constraints differ in template redeclaration}} +int A(); +template int A(); // expected-error{{associated constraints differ in template redeclaration}} -template struct B; // expected-note{{previous template declaration is here}} +template int B(); // expected-note{{previous template declaration is here}} template requires true // expected-error{{associated constraints differ in template redeclaration}} -struct B; +int B(); template requires true // expected-note{{previous template declaration is here}} -struct C; +int C(); template requires !0 // expected-error{{associated constraints differ in template redeclaration}} -struct C; +int C(); } // end namespace diag namespace nodiag { struct AA { template requires someFunc(T()) - struct A; + int A(); }; template requires someFunc(T()) -struct AA::A { }; - -struct AAF { - template requires someFunc(T()) - friend struct AA::A; -}; +int AA::A() { return sizeof(T); } } // end namespace nodiag namespace diag { template struct TA { - template class TT> requires TT::happy // expected-note 2{{previous template declaration is here}} - struct A; - - struct AF; + template class TT> requires TT::happy // expected-note{{previous template declaration is here}} + int A(); }; template -template class TT> struct TA::A { }; // expected-error{{associated constraints differ in template redeclaration}} - -template -struct TA::AF { - template class TT> requires TT::happy // expected-error{{associated constraints differ in template redeclaration}} - friend struct TA::A; -}; +template class TT> int TA::A() { return sizeof(TT); } // expected-error{{associated constraints differ in template redeclaration}} } // end namespace diag Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp === --- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { @@ -33,7 +33,7 @@ struct A; }; -template requires someFunc(T()) +template requires someFunc(U()) struct AA::A { }; struct AAF { @@ -47,18 +47,26 @@ template struct TA { - template class TT> requires TT::happy // expected-note 2{{previous template declaration is here}} +
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
saar.raz updated this revision to Diff 160861. saar.raz added a comment. - Address comments by rsmith, mainly removing associated constraints caching and instead returning a smallvector of constraint expressions from getAssociatedConstraints. Repository: rC Clang https://reviews.llvm.org/D41284 Files: include/clang/AST/DeclTemplate.h include/clang/AST/RecursiveASTVisitor.h include/clang/Sema/Sema.h lib/AST/DeclTemplate.cpp lib/Sema/SemaConcept.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp lib/Serialization/ASTWriterDecl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp === --- /dev/null +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +namespace nodiag { + +struct B { +template requires bool(T()) +static int A; +}; + +template requires bool(U()) +int B::A = int(U()); + +} // end namespace nodiag + +namespace diag { + +struct B { +template requires bool(T()) // expected-note{{previous template declaration is here}} +static int A; +}; + +template requires !bool(U()) // expected-error{{associated constraints differ in template redeclaration}} +int B::A = int(U()); + +} // end namespace diag \ No newline at end of file Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp === --- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp @@ -1,65 +1,52 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { template requires bool(T()) -struct A; +int A(); template requires bool(U()) -struct A; +int A(); } // end namespace nodiag namespace diag { template requires true // expected-note{{previous template declaration is here}} -struct A; -template struct A; // expected-error{{associated constraints differ in template redeclaration}} +int A(); +template int A(); // expected-error{{associated constraints differ in template redeclaration}} -template struct B; // expected-note{{previous template declaration is here}} +template int B(); // expected-note{{previous template declaration is here}} template requires true // expected-error{{associated constraints differ in template redeclaration}} -struct B; +int B(); template requires true // expected-note{{previous template declaration is here}} -struct C; +int C(); template requires !0 // expected-error{{associated constraints differ in template redeclaration}} -struct C; +int C(); } // end namespace diag namespace nodiag { struct AA { template requires someFunc(T()) - struct A; + int A(); }; template requires someFunc(T()) -struct AA::A { }; - -struct AAF { - template requires someFunc(T()) - friend struct AA::A; -}; +int AA::A() { return sizeof(T); } } // end namespace nodiag namespace diag { template struct TA { - template class TT> requires TT::happy // expected-note 2{{previous template declaration is here}} - struct A; - - struct AF; + template class TT> requires TT::happy // expected-note{{previous template declaration is here}} + int A(); }; template -template class TT> struct TA::A { }; // expected-error{{associated constraints differ in template redeclaration}} - -template -struct TA::AF { - template class TT> requires TT::happy // expected-error{{associated constraints differ in template redeclaration}} - friend struct TA::A; -}; +template class TT> int TA::A() { return sizeof(TT); } // expected-error{{associated constraints differ in template redeclaration}} } // end namespace diag Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp === --- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { @@ -33,7 +33,7 @@ struct A; }; -template requires someFunc(T()) +template requires someFunc(U()) struct AA::A { }; struct AAF { @@ -47,18 +47,26 @@ template struct TA { - template class TT> requ
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
rsmith added inline comments. Comment at: lib/AST/DeclTemplate.cpp:203 + +Expr *TemplateDecl::getAssociatedConstraints() { + return getOrCollectAssociatedConstraints(getASTContext(), Rather than producing an `Expr*` (which will presumably eventually need to contain synthetic `&&` expressions), this should produce a vector of constraints (notionally and'd together), which will (eventually) be either constraint-expressions or some representation of "the constraints implied by this template parameter". If you do that, I don't think there's any reason to cache this information on the `TemplateDecl`; it should be cheap enough to recompute when we need it. Comment at: lib/Sema/SemaConcept.cpp:47-58 + const Expr *NewAC) { + if (!(NewAC || OldAC)) +return true; // Nothing to check; no mismatch. + if (NewAC && OldAC) { +llvm::FoldingSetNodeID OldACInfo, NewACInfo; +NewAC->Profile(NewACInfo, Context, /*Canonical=*/true); +OldAC->Profile(OldACInfo, Context, /*Canonical=*/true); I'm sure we already have this "profile two expressions and check they are canonically equivalent" functionality factored out //somewhere//. Is there nothing like that that's appropriate to reuse here? Comment at: lib/Sema/SemaTemplate.cpp:2145-2154 if (RemoveDefaultArguments) { -for (TemplateParameterList::iterator NewParam = NewParams->begin(), - NewParamEnd = NewParams->end(); - NewParam != NewParamEnd; ++NewParam) { - if (TemplateTypeParmDecl *TTP = dyn_cast(*NewParam)) +for (NamedDecl *NewParam : *NewParams) { + if (TemplateTypeParmDecl *TTP = dyn_cast(NewParam)) TTP->removeDefaultArgument(); else if (NonTypeTemplateParmDecl *NTTP -= dyn_cast(*NewParam)) += dyn_cast(NewParam)) NTTP->removeDefaultArgument(); Unrelated cleanup: please commit this separately. Comment at: lib/Sema/SemaTemplateInstantiateDecl.cpp:3141-3148 + Expr *InstRequiresClause = nullptr; + if (Expr *E = L->getRequiresClause()) { +ExprResult Res = SemaRef.SubstExpr(E, TemplateArgs); +if (Res.isInvalid() || !Res.isUsable()) { + return nullptr; +} +InstRequiresClause = Res.get(); This is wrong (we should never substitute into a constraint-expression except as part of satisfaction or subsumption checks). Please at least add a FIXME. Comment at: lib/Serialization/ASTReaderDecl.cpp:2003-2006 +bool HasAssociatedConstraints = Record.readInt(); +if (HasAssociatedConstraints) { + AssociatedConstraints = Record.readExpr(); +} There doesn't seem to be a good reason to serialize the cached associated constraints, even if we want to keep them (which I don't think we do). Comment at: lib/Serialization/ASTWriter.cpp:5856 for (const auto &P : *TemplateParams) -AddDeclRef(P); +AddDeclRef(P); // TODO: Concepts - constrained parameters. + if (const Expr *RequiresClause = TemplateParams->getRequiresClause()) { What would be left "to do" here? For constrained parameters, there may be something interesting to track on the `*Template*ParmDecl`, but not here, I wouldn't think, Repository: rC Clang https://reviews.llvm.org/D41284 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
saar.raz updated this revision to Diff 159236. saar.raz added a comment. - Consider requires clause when determining if TPL has an unexpanded pack Repository: rC Clang https://reviews.llvm.org/D41284 Files: include/clang/AST/DeclTemplate.h include/clang/AST/RecursiveASTVisitor.h include/clang/Sema/Sema.h lib/AST/DeclTemplate.cpp lib/Sema/SemaConcept.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp lib/Serialization/ASTWriterDecl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp === --- /dev/null +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +namespace nodiag { + +struct B { +template requires bool(T()) +static int A; +}; + +template requires bool(U()) +int B::A = int(U()); + +} // end namespace nodiag + +namespace diag { + +struct B { +template requires bool(T()) // expected-note{{previous template declaration is here}} +static int A; +}; + +template requires !bool(U()) // expected-error{{associated constraints differ in template redeclaration}} +int B::A = int(U()); + +} // end namespace diag \ No newline at end of file Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp === --- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp @@ -1,65 +1,52 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { template requires bool(T()) -struct A; +int A(); template requires bool(U()) -struct A; +int A(); } // end namespace nodiag namespace diag { template requires true // expected-note{{previous template declaration is here}} -struct A; -template struct A; // expected-error{{associated constraints differ in template redeclaration}} +int A(); +template int A(); // expected-error{{associated constraints differ in template redeclaration}} -template struct B; // expected-note{{previous template declaration is here}} +template int B(); // expected-note{{previous template declaration is here}} template requires true // expected-error{{associated constraints differ in template redeclaration}} -struct B; +int B(); template requires true // expected-note{{previous template declaration is here}} -struct C; +int C(); template requires !0 // expected-error{{associated constraints differ in template redeclaration}} -struct C; +int C(); } // end namespace diag namespace nodiag { struct AA { template requires someFunc(T()) - struct A; + int A(); }; template requires someFunc(T()) -struct AA::A { }; - -struct AAF { - template requires someFunc(T()) - friend struct AA::A; -}; +int AA::A() { return sizeof(T); } } // end namespace nodiag namespace diag { template struct TA { - template class TT> requires TT::happy // expected-note 2{{previous template declaration is here}} - struct A; - - struct AF; + template class TT> requires TT::happy // expected-note{{previous template declaration is here}} + int A(); }; template -template class TT> struct TA::A { }; // expected-error{{associated constraints differ in template redeclaration}} - -template -struct TA::AF { - template class TT> requires TT::happy // expected-error{{associated constraints differ in template redeclaration}} - friend struct TA::A; -}; +template class TT> int TA::A() { return sizeof(TT); } // expected-error{{associated constraints differ in template redeclaration}} } // end namespace diag Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp === --- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { @@ -33,7 +33,7 @@ struct A; }; -template requires someFunc(T()) +template requires someFunc(U()) struct AA::A { }; struct AAF { @@ -47,18 +47,26 @@ template struct TA { - template class TT> requires TT::happy // expected-note 2{{previous template declaration is here}} + template class TT>
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
saar.raz updated this revision to Diff 138500. saar.raz added a comment. Fixed reference to TemplateParams member in assertion. Repository: rC Clang https://reviews.llvm.org/D41284 Files: include/clang/AST/DeclTemplate.h include/clang/AST/RecursiveASTVisitor.h include/clang/Sema/Sema.h lib/AST/DeclTemplate.cpp lib/Sema/SemaConcept.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp lib/Serialization/ASTWriterDecl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp === --- /dev/null +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +namespace nodiag { + +struct B { +template requires bool(T()) +static int A; +}; + +template requires bool(U()) +int B::A = int(U()); + +} // end namespace nodiag + +namespace diag { + +struct B { +template requires bool(T()) // expected-note{{previous template declaration is here}} +static int A; +}; + +template requires !bool(U()) // expected-error{{associated constraints differ in template redeclaration}} +int B::A = int(U()); + +} // end namespace diag \ No newline at end of file Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp === --- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp @@ -1,65 +1,52 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { template requires bool(T()) -struct A; +int A(); template requires bool(U()) -struct A; +int A(); } // end namespace nodiag namespace diag { template requires true // expected-note{{previous template declaration is here}} -struct A; -template struct A; // expected-error{{associated constraints differ in template redeclaration}} +int A(); +template int A(); // expected-error{{associated constraints differ in template redeclaration}} -template struct B; // expected-note{{previous template declaration is here}} +template int B(); // expected-note{{previous template declaration is here}} template requires true // expected-error{{associated constraints differ in template redeclaration}} -struct B; +int B(); template requires true // expected-note{{previous template declaration is here}} -struct C; +int C(); template requires !0 // expected-error{{associated constraints differ in template redeclaration}} -struct C; +int C(); } // end namespace diag namespace nodiag { struct AA { template requires someFunc(T()) - struct A; + int A(); }; template requires someFunc(T()) -struct AA::A { }; - -struct AAF { - template requires someFunc(T()) - friend struct AA::A; -}; +int AA::A() { return sizeof(T); } } // end namespace nodiag namespace diag { template struct TA { - template class TT> requires TT::happy // expected-note 2{{previous template declaration is here}} - struct A; - - struct AF; + template class TT> requires TT::happy // expected-note{{previous template declaration is here}} + int A(); }; template -template class TT> struct TA::A { }; // expected-error{{associated constraints differ in template redeclaration}} - -template -struct TA::AF { - template class TT> requires TT::happy // expected-error{{associated constraints differ in template redeclaration}} - friend struct TA::A; -}; +template class TT> int TA::A() { return sizeof(TT); } // expected-error{{associated constraints differ in template redeclaration}} } // end namespace diag Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp === --- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { @@ -33,7 +33,7 @@ struct A; }; -template requires someFunc(T()) +template requires someFunc(U()) struct AA::A { }; struct AAF { @@ -47,18 +47,26 @@ template struct TA { - template class TT> requires TT::happy // expected-note 2{{previous template declaration is here}} + template class TT> requires TT::happy
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
saar.raz updated this revision to Diff 132748. saar.raz added a comment. Moved function into SemaConcept.cpp. Repository: rC Clang https://reviews.llvm.org/D41284 Files: include/clang/AST/DeclTemplate.h include/clang/AST/RecursiveASTVisitor.h include/clang/Sema/Sema.h lib/AST/DeclTemplate.cpp lib/Sema/SemaConcept.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp lib/Serialization/ASTWriterDecl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp === --- /dev/null +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +namespace nodiag { + +struct B { +template requires bool(T()) +static int A; +}; + +template requires bool(U()) +int B::A = int(U()); + +} // end namespace nodiag + +namespace diag { + +struct B { +template requires bool(T()) // expected-note{{previous template declaration is here}} +static int A; +}; + +template requires !bool(U()) // expected-error{{associated constraints differ in template redeclaration}} +int B::A = int(U()); + +} // end namespace diag \ No newline at end of file Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp === --- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp @@ -1,65 +1,52 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { template requires bool(T()) -struct A; +int A(); template requires bool(U()) -struct A; +int A(); } // end namespace nodiag namespace diag { template requires true // expected-note{{previous template declaration is here}} -struct A; -template struct A; // expected-error{{associated constraints differ in template redeclaration}} +int A(); +template int A(); // expected-error{{associated constraints differ in template redeclaration}} -template struct B; // expected-note{{previous template declaration is here}} +template int B(); // expected-note{{previous template declaration is here}} template requires true // expected-error{{associated constraints differ in template redeclaration}} -struct B; +int B(); template requires true // expected-note{{previous template declaration is here}} -struct C; +int C(); template requires !0 // expected-error{{associated constraints differ in template redeclaration}} -struct C; +int C(); } // end namespace diag namespace nodiag { struct AA { template requires someFunc(T()) - struct A; + int A(); }; template requires someFunc(T()) -struct AA::A { }; - -struct AAF { - template requires someFunc(T()) - friend struct AA::A; -}; +int AA::A() { return sizeof(T); } } // end namespace nodiag namespace diag { template struct TA { - template class TT> requires TT::happy // expected-note 2{{previous template declaration is here}} - struct A; - - struct AF; + template class TT> requires TT::happy // expected-note{{previous template declaration is here}} + int A(); }; template -template class TT> struct TA::A { }; // expected-error{{associated constraints differ in template redeclaration}} - -template -struct TA::AF { - template class TT> requires TT::happy // expected-error{{associated constraints differ in template redeclaration}} - friend struct TA::A; -}; +template class TT> int TA::A() { return sizeof(TT); } // expected-error{{associated constraints differ in template redeclaration}} } // end namespace diag Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp === --- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { @@ -33,7 +33,7 @@ struct A; }; -template requires someFunc(T()) +template requires someFunc(U()) struct AA::A { }; struct AAF { @@ -47,18 +47,26 @@ template struct TA { - template class TT> requires TT::happy // expected-note 2{{previous template declaration is here}} + template class TT> requires TT::happy // expected-note {
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
saar.raz updated this revision to Diff 129297. saar.raz added a comment. - Fixed wrong if that would cause valid instantiated requires clauses to not be accepted. Repository: rC Clang https://reviews.llvm.org/D41284 Files: include/clang/AST/DeclTemplate.h include/clang/AST/RecursiveASTVisitor.h include/clang/Sema/Sema.h lib/AST/DeclTemplate.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp lib/Serialization/ASTWriterDecl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp === --- /dev/null +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +namespace nodiag { + +struct B { +template requires bool(T()) +static int A; +}; + +template requires bool(U()) +int B::A = int(U()); + +} // end namespace nodiag + +namespace diag { + +struct B { +template requires bool(T()) // expected-note{{previous template declaration is here}} +static int A; +}; + +template requires !bool(U()) // expected-error{{associated constraints differ in template redeclaration}} +int B::A = int(U()); + +} // end namespace diag \ No newline at end of file Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp === --- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp @@ -1,65 +1,52 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { template requires bool(T()) -struct A; +int A(); template requires bool(U()) -struct A; +int A(); } // end namespace nodiag namespace diag { template requires true // expected-note{{previous template declaration is here}} -struct A; -template struct A; // expected-error{{associated constraints differ in template redeclaration}} +int A(); +template int A(); // expected-error{{associated constraints differ in template redeclaration}} -template struct B; // expected-note{{previous template declaration is here}} +template int B(); // expected-note{{previous template declaration is here}} template requires true // expected-error{{associated constraints differ in template redeclaration}} -struct B; +int B(); template requires true // expected-note{{previous template declaration is here}} -struct C; +int C(); template requires !0 // expected-error{{associated constraints differ in template redeclaration}} -struct C; +int C(); } // end namespace diag namespace nodiag { struct AA { template requires someFunc(T()) - struct A; + int A(); }; template requires someFunc(T()) -struct AA::A { }; - -struct AAF { - template requires someFunc(T()) - friend struct AA::A; -}; +int AA::A() { return sizeof(T); } } // end namespace nodiag namespace diag { template struct TA { - template class TT> requires TT::happy // expected-note 2{{previous template declaration is here}} - struct A; - - struct AF; + template class TT> requires TT::happy // expected-note{{previous template declaration is here}} + int A(); }; template -template class TT> struct TA::A { }; // expected-error{{associated constraints differ in template redeclaration}} - -template -struct TA::AF { - template class TT> requires TT::happy // expected-error{{associated constraints differ in template redeclaration}} - friend struct TA::A; -}; +template class TT> int TA::A() { return sizeof(TT); } // expected-error{{associated constraints differ in template redeclaration}} } // end namespace diag Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp === --- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { @@ -33,7 +33,7 @@ struct A; }; -template requires someFunc(T()) +template requires someFunc(U()) struct AA::A { }; struct AAF { @@ -47,18 +47,26 @@ template struct TA { - template class TT> requires TT::happy // expected-note 2{{previous template declaration is here}} + template class TT> requires T
[PATCH] D41284: [Concepts] Associated constraints infrastructure.
saar.raz updated this revision to Diff 127163. saar.raz added a comment. - Added requires clause matching for all kinds of template redeclarations instead of just classes. Repository: rC Clang https://reviews.llvm.org/D41284 Files: include/clang/AST/DeclTemplate.h include/clang/AST/RecursiveASTVisitor.h include/clang/Sema/Sema.h lib/AST/DeclTemplate.cpp lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Serialization/ASTReader.cpp lib/Serialization/ASTReaderDecl.cpp lib/Serialization/ASTWriter.cpp lib/Serialization/ASTWriterDecl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp === --- /dev/null +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s + +namespace nodiag { + +struct B { +template requires bool(T()) +static int A; +}; + +template requires bool(U()) +int B::A = int(U()); + +} // end namespace nodiag + +namespace diag { + +struct B { +template requires bool(T()) // expected-note{{previous template declaration is here}} +static int A; +}; + +template requires !bool(U()) // expected-error{{associated constraints differ in template redeclaration}} +int B::A = int(U()); + +} // end namespace diag \ No newline at end of file Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp === --- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp @@ -1,65 +1,52 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { template requires bool(T()) -struct A; +int A(); template requires bool(U()) -struct A; +int A(); } // end namespace nodiag namespace diag { template requires true // expected-note{{previous template declaration is here}} -struct A; -template struct A; // expected-error{{associated constraints differ in template redeclaration}} +int A(); +template int A(); // expected-error{{associated constraints differ in template redeclaration}} -template struct B; // expected-note{{previous template declaration is here}} +template int B(); // expected-note{{previous template declaration is here}} template requires true // expected-error{{associated constraints differ in template redeclaration}} -struct B; +int B(); template requires true // expected-note{{previous template declaration is here}} -struct C; +int C(); template requires !0 // expected-error{{associated constraints differ in template redeclaration}} -struct C; +int C(); } // end namespace diag namespace nodiag { struct AA { template requires someFunc(T()) - struct A; + int A(); }; template requires someFunc(T()) -struct AA::A { }; - -struct AAF { - template requires someFunc(T()) - friend struct AA::A; -}; +int AA::A() { return sizeof(T); } } // end namespace nodiag namespace diag { template struct TA { - template class TT> requires TT::happy // expected-note 2{{previous template declaration is here}} - struct A; - - struct AF; + template class TT> requires TT::happy // expected-note{{previous template declaration is here}} + int A(); }; template -template class TT> struct TA::A { }; // expected-error{{associated constraints differ in template redeclaration}} - -template -struct TA::AF { - template class TT> requires TT::happy // expected-error{{associated constraints differ in template redeclaration}} - friend struct TA::A; -}; +template class TT> int TA::A() { return sizeof(TT); } // expected-error{{associated constraints differ in template redeclaration}} } // end namespace diag Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp === --- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp +++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s +// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s namespace nodiag { @@ -33,7 +33,7 @@ struct A; }; -template requires someFunc(T()) +template requires someFunc(U()) struct AA::A { }; struct AAF { @@ -47,18 +47,26 @@ template struct TA { - template class TT> requires TT::happy // expected-note 2{{previous template declaration is here}} + template class TT> r