[PATCH] D73155: [Concepts] Implement P1616R1 - Using unconstrained template template parameters with constrained templates

2020-01-23 Thread Saar Raz via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGd42d5eb8ea77: [Concepts] Implement P1616R1 - Using 
unconstrained template template parameters… (authored by saar.raz).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D73155

Files:
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp


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
@@ -7,9 +7,9 @@
 // expected-note@-1{{similar constraint expressions not considered equivalent}}
 template class P> struct S1 { }; // expected-note 2{{'P' declared 
here}}
 
-template struct X { }; // expected-note{{'X' declared here}}
+template struct X { };
 
-template struct Y { }; // expected-note 2{{'Y' declared here}}
+template struct Y { }; // expected-note{{'Y' declared here}}
 template struct Z { };
 template struct W { }; // expected-note{{'W' declared here}}
 
@@ -18,10 +18,10 @@
 S1 s13;
 S1 s14; // expected-error{{template template argument 'W' is more 
constrained than template template parameter 'P'}}
 
-template class P> struct S2 { }; // expected-note 2{{'P' 
declared here}}
+template class P> struct S2 { };
 
-S2 s21; // expected-error{{template template argument 'X' is more 
constrained than template template parameter 'P'}}
-S2 s22; // expected-error{{template template argument 'Y' is more 
constrained than template template parameter 'P'}}
+S2 s21;
+S2 s22;
 S2 s23;
 
 template  class C>
Index: clang/lib/Sema/SemaTemplate.cpp
===
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -7164,6 +7164,11 @@
   //   [temp.constr.order].
   SmallVector ParamsAC, TemplateAC;
   Params->getAssociatedConstraints(ParamsAC);
+  // C++2a[temp.arg.template]p3
+  //   [...] In this comparison, if P is unconstrained, the constraints on 
A
+  //   are not considered.
+  if (ParamsAC.empty())
+return false;
   Template->getAssociatedConstraints(TemplateAC);
   bool IsParamAtLeastAsConstrained;
   if (IsAtLeastAsConstrained(Param, ParamsAC, Template, TemplateAC,


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
@@ -7,9 +7,9 @@
 // expected-note@-1{{similar constraint expressions not considered equivalent}}
 template class P> struct S1 { }; // expected-note 2{{'P' declared here}}
 
-template struct X { }; // expected-note{{'X' declared here}}
+template struct X { };
 
-template struct Y { }; // expected-note 2{{'Y' declared here}}
+template struct Y { }; // expected-note{{'Y' declared here}}
 template struct Z { };
 template struct W { }; // expected-note{{'W' declared here}}
 
@@ -18,10 +18,10 @@
 S1 s13;
 S1 s14; // expected-error{{template template argument 'W' is more constrained than template template parameter 'P'}}
 
-template class P> struct S2 { }; // expected-note 2{{'P' declared here}}
+template class P> struct S2 { };
 
-S2 s21; // expected-error{{template template argument 'X' is more constrained than template template parameter 'P'}}
-S2 s22; // expected-error{{template template argument 'Y' is more constrained than template template parameter 'P'}}
+S2 s21;
+S2 s22;
 S2 s23;
 
 template  class C>
Index: clang/lib/Sema/SemaTemplate.cpp
===
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -7164,6 +7164,11 @@
   //   [temp.constr.order].
   SmallVector ParamsAC, TemplateAC;
   Params->getAssociatedConstraints(ParamsAC);
+  // C++2a[temp.arg.template]p3
+  //   [...] In this comparison, if P is unconstrained, the constraints on A
+  //   are not considered.
+  if (ParamsAC.empty())
+return false;
   Template->getAssociatedConstraints(TemplateAC);
   bool IsParamAtLeastAsConstrained;
   if (IsAtLeastAsConstrained(Param, ParamsAC, Template, TemplateAC,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73155: [Concepts] Implement P1616R1 - Using unconstrained template template parameters with constrained templates

2020-01-21 Thread Saar Raz via Phabricator via cfe-commits
saar.raz created this revision.
saar.raz added a reviewer: rsmith.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Allow unconstrained template template parameters to accept constrainted 
templates as arguments.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D73155

Files:
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp


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
@@ -7,9 +7,9 @@
 // expected-note@-1{{similar constraint expressions not considered equivalent}}
 template class P> struct S1 { }; // expected-note 2{{'P' declared 
here}}
 
-template struct X { }; // expected-note{{'X' declared here}}
+template struct X { };
 
-template struct Y { }; // expected-note 2{{'Y' declared here}}
+template struct Y { }; // expected-note{{'Y' declared here}}
 template struct Z { };
 template struct W { }; // expected-note{{'W' declared here}}
 
@@ -18,10 +18,10 @@
 S1 s13;
 S1 s14; // expected-error{{template template argument 'W' is more 
constrained than template template parameter 'P'}}
 
-template class P> struct S2 { }; // expected-note 2{{'P' 
declared here}}
+template class P> struct S2 { };
 
-S2 s21; // expected-error{{template template argument 'X' is more 
constrained than template template parameter 'P'}}
-S2 s22; // expected-error{{template template argument 'Y' is more 
constrained than template template parameter 'P'}}
+S2 s21;
+S2 s22;
 S2 s23;
 
 template  class C>
Index: clang/lib/Sema/SemaTemplate.cpp
===
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -7164,6 +7164,11 @@
   //   [temp.constr.order].
   SmallVector ParamsAC, TemplateAC;
   Params->getAssociatedConstraints(ParamsAC);
+  // C++2a[temp.arg.template]p3
+  //   [...] In this comparison, if P is unconstrained, the constraints on 
A
+  //   are not considered.
+  if (ParamsAC.empty())
+return false;
   Template->getAssociatedConstraints(TemplateAC);
   bool IsParamAtLeastAsConstrained;
   if (IsAtLeastAsConstrained(Param, ParamsAC, Template, TemplateAC,


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
@@ -7,9 +7,9 @@
 // expected-note@-1{{similar constraint expressions not considered equivalent}}
 template class P> struct S1 { }; // expected-note 2{{'P' declared here}}
 
-template struct X { }; // expected-note{{'X' declared here}}
+template struct X { };
 
-template struct Y { }; // expected-note 2{{'Y' declared here}}
+template struct Y { }; // expected-note{{'Y' declared here}}
 template struct Z { };
 template struct W { }; // expected-note{{'W' declared here}}
 
@@ -18,10 +18,10 @@
 S1 s13;
 S1 s14; // expected-error{{template template argument 'W' is more constrained than template template parameter 'P'}}
 
-template class P> struct S2 { }; // expected-note 2{{'P' declared here}}
+template class P> struct S2 { };
 
-S2 s21; // expected-error{{template template argument 'X' is more constrained than template template parameter 'P'}}
-S2 s22; // expected-error{{template template argument 'Y' is more constrained than template template parameter 'P'}}
+S2 s21;
+S2 s22;
 S2 s23;
 
 template  class C>
Index: clang/lib/Sema/SemaTemplate.cpp
===
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -7164,6 +7164,11 @@
   //   [temp.constr.order].
   SmallVector ParamsAC, TemplateAC;
   Params->getAssociatedConstraints(ParamsAC);
+  // C++2a[temp.arg.template]p3
+  //   [...] In this comparison, if P is unconstrained, the constraints on A
+  //   are not considered.
+  if (ParamsAC.empty())
+return false;
   Template->getAssociatedConstraints(TemplateAC);
   bool IsParamAtLeastAsConstrained;
   if (IsAtLeastAsConstrained(Param, ParamsAC, Template, TemplateAC,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73150: [Concepts] Remove -fconcepts-ts, enable concepts support under -std=c++2a

2020-01-21 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 239472.
saar.raz added a comment.

Readd -fconcepts-ts for deprecation diagnostic


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D73150

Files:
  clang/include/clang/Basic/DiagnosticFrontendKinds.td
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Basic/TokenKinds.def
  clang/lib/Basic/IdentifierTable.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CXX/class.derived/class.virtual/p6.cpp
  clang/test/CXX/dcl/dcl.decl/p3.cpp
  clang/test/CXX/dcl/dcl.fct/p17.cpp
  clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.id/mixed-constraints.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.id/p4.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.lambda/expr.prim.lambda.closure/p3.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/equivalence.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/p3.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/requires-expr.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp
  clang/test/CXX/over/over.match/over.match.best/p1-2a.cpp
  clang/test/CXX/over/over.match/over.match.viable/p3.cpp
  clang/test/CXX/over/over.over/p4-2a.cpp
  clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
  clang/test/CXX/temp/temp.constr/temp.constr.constr/function-templates.cpp
  clang/test/CXX/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
  clang/test/CXX/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
  clang/test/CXX/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
  clang/test/CXX/temp/temp.constr/temp.constr.decl/p3.cpp
  clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp
  
clang/test/CXX/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
  clang/test/CXX/temp/temp.constr/temp.constr.order/function-templates.cpp
  
clang/test/CXX/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
  clang/test/CXX/temp/temp.explicit/p8.cpp
  clang/test/CXX/temp/temp.param/p10-2a.cpp
  clang/test/CodeGenCXX/mangle-concept.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/Lexer/keywords_test.cpp
  clang/test/PCH/cxx2a-requires-expr.cpp
  clang/test/Parser/cxx-concept-declaration.cpp
  clang/test/Parser/cxx-concepts-ambig-constraint-expr.cpp
  clang/test/Parser/cxx-concepts-requires-clause.cpp
  clang/test/Parser/cxx2a-concept-declaration.cpp
  clang/test/Parser/cxx2a-concepts-requires-expr.cpp
  clang/test/Parser/cxx2a-constrained-template-param-with-partial-id.cpp
  clang/test/Parser/cxx2a-constrained-template-param.cpp
  clang/test/Parser/cxx2a-placeholder-type-constraint.cpp
  clang/test/SemaTemplate/cxx2a-constraint-caching.cpp
  clang/test/SemaTemplate/instantiate-expanded-type-constraint.cpp
  clang/test/SemaTemplate/instantiate-requires-clause.cpp
  clang/test/SemaTemplate/instantiate-requires-expr.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -881,7 +881,7 @@
 
   Concepts
   https://wg21.link/p0734r0;>P0734R0
-  No
+  Clang 10
 

 https://wg21.link/p0857r0;>P0857R0
Index: clang/test/SemaTemplate/instantiate-requires-expr.cpp
===
--- clang/test/SemaTemplate/instantiate-requires-expr.cpp
+++ clang/test/SemaTemplate/instantiate-requires-expr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ %s -verify -Wno-unused-value
+// RUN: %clang_cc1 -std=c++2a -x c++ %s -verify -Wno-unused-value
 
 template
 constexpr bool is_same_v = false;
Index: clang/test/SemaTemplate/instantiate-requires-clause.cpp
===
--- clang/test/SemaTemplate/instantiate-requires-clause.cpp
+++ clang/test/SemaTemplate/instantiate-requires-clause.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ %s -verify
+// RUN: %clang_cc1 -std=c++2a -x c++ %s -verify
 
 template  requires ((sizeof(Args) == 1), ...)
 // expected-note@-1 {{because '(sizeof(int) == 1) , (sizeof(char) == 1) , (sizeof(int) == 1)' evaluated to false}}
Index: clang/test/SemaTemplate/instantiate-expanded-type-constraint.cpp
===
--- clang/test/SemaTemplate/instantiate-expanded-type-constraint.cpp
+++ clang/test/SemaTemplate/instantiate-expanded-type-constraint.cpp
@@ -1,4 +1,4 @@
-// RUN:  %clang_cc1 

[PATCH] D73153: [Concepts] Update ReleaseNotes with Concepts support

2020-01-21 Thread Saar Raz via Phabricator via cfe-commits
saar.raz created this revision.
saar.raz added a reviewer: rsmith.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Update Clang 10 release notes with news of Concepts support.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D73153

Files:
  clang/docs/ReleaseNotes.rst


Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -51,7 +51,7 @@
   restores the former behavior. The ``-v`` and ``-###`` flags will print
   "(in-process)" when compilations are done in-process.
 
-- ...
+- Concepts support. Clang now supports C++2a Concepts under the -std=c++2a 
flag.
 
 Improvements to Clang's diagnostics
 ^^^
@@ -123,6 +123,10 @@
   You can also force vzeroupper insertion to be used on CPUs that normally
   wouldn't with -mvzeroupper.
 
+- The -fno-concept-satisfaction-caching can be used to disable caching for
+  satisfactions of Concepts. Using this flag might incur significant
+  compile-time costs.
+
 Deprecated Compiler Flags
 -
 
@@ -132,6 +136,8 @@
 - -mmpx used to enable the __MPX__ preprocessor define for the Intel MPX
   instructions. There were no MPX intrinsics.
 - -mno-mpx used to disable -mmpx and is the default behavior.
+- -fconcepts-ts previously used to enable experimental concepts support. Use
+  -std=c++2a instead to enable Concepts support.
 
 - ...
 


Index: clang/docs/ReleaseNotes.rst
===
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -51,7 +51,7 @@
   restores the former behavior. The ``-v`` and ``-###`` flags will print
   "(in-process)" when compilations are done in-process.
 
-- ...
+- Concepts support. Clang now supports C++2a Concepts under the -std=c++2a flag.
 
 Improvements to Clang's diagnostics
 ^^^
@@ -123,6 +123,10 @@
   You can also force vzeroupper insertion to be used on CPUs that normally
   wouldn't with -mvzeroupper.
 
+- The -fno-concept-satisfaction-caching can be used to disable caching for
+  satisfactions of Concepts. Using this flag might incur significant
+  compile-time costs.
+
 Deprecated Compiler Flags
 -
 
@@ -132,6 +136,8 @@
 - -mmpx used to enable the __MPX__ preprocessor define for the Intel MPX
   instructions. There were no MPX intrinsics.
 - -mno-mpx used to disable -mmpx and is the default behavior.
+- -fconcepts-ts previously used to enable experimental concepts support. Use
+  -std=c++2a instead to enable Concepts support.
 
 - ...
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D73150: [Concepts] Remove -fconcepts-ts, enable concepts support under -std=c++2a

2020-01-21 Thread Saar Raz via Phabricator via cfe-commits
saar.raz created this revision.
saar.raz added a reviewer: rsmith.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Enable concepts support under normal -std=c++2a and not under -fconcepts-ts, 
which is now deprecated.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D73150

Files:
  clang/include/clang/Basic/DiagnosticFrontendKinds.td
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Driver/CC1Options.td
  clang/lib/Basic/IdentifierTable.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Frontend/InitPreprocessor.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/CXX/class.derived/class.virtual/p6.cpp
  clang/test/CXX/dcl/dcl.decl/p3.cpp
  clang/test/CXX/dcl/dcl.fct/p17.cpp
  clang/test/CXX/dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.id/mixed-constraints.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.id/p4.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.lambda/expr.prim.lambda.closure/p3.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/equivalence.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/p3.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/requires-expr.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/simple-requirement.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp
  clang/test/CXX/over/over.match/over.match.best/p1-2a.cpp
  clang/test/CXX/over/over.match/over.match.viable/p3.cpp
  clang/test/CXX/over/over.over/p4-2a.cpp
  clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
  clang/test/CXX/temp/temp.constr/temp.constr.constr/function-templates.cpp
  clang/test/CXX/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
  clang/test/CXX/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
  clang/test/CXX/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
  clang/test/CXX/temp/temp.constr/temp.constr.decl/p3.cpp
  clang/test/CXX/temp/temp.constr/temp.constr.normal/p1.cpp
  
clang/test/CXX/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
  clang/test/CXX/temp/temp.constr/temp.constr.order/function-templates.cpp
  
clang/test/CXX/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
  clang/test/CXX/temp/temp.explicit/p8.cpp
  clang/test/CXX/temp/temp.param/p10-2a.cpp
  clang/test/CodeGenCXX/mangle-concept.cpp
  clang/test/Lexer/cxx-features.cpp
  clang/test/Lexer/keywords_test.cpp
  clang/test/PCH/cxx2a-requires-expr.cpp
  clang/test/Parser/cxx-concept-declaration.cpp
  clang/test/Parser/cxx-concepts-ambig-constraint-expr.cpp
  clang/test/Parser/cxx-concepts-requires-clause.cpp
  clang/test/Parser/cxx2a-concept-declaration.cpp
  clang/test/Parser/cxx2a-concepts-requires-expr.cpp
  clang/test/Parser/cxx2a-constrained-template-param-with-partial-id.cpp
  clang/test/Parser/cxx2a-constrained-template-param.cpp
  clang/test/Parser/cxx2a-placeholder-type-constraint.cpp
  clang/test/SemaTemplate/cxx2a-constraint-caching.cpp
  clang/test/SemaTemplate/instantiate-expanded-type-constraint.cpp
  clang/test/SemaTemplate/instantiate-requires-clause.cpp
  clang/test/SemaTemplate/instantiate-requires-expr.cpp
  clang/www/cxx_status.html

Index: clang/www/cxx_status.html
===
--- clang/www/cxx_status.html
+++ clang/www/cxx_status.html
@@ -881,7 +881,7 @@
 
   Concepts
   https://wg21.link/p0734r0;>P0734R0
-  No
+  Clang 10
 

 https://wg21.link/p0857r0;>P0857R0
Index: clang/test/SemaTemplate/instantiate-requires-expr.cpp
===
--- clang/test/SemaTemplate/instantiate-requires-expr.cpp
+++ clang/test/SemaTemplate/instantiate-requires-expr.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ %s -verify -Wno-unused-value
+// RUN: %clang_cc1 -std=c++2a -x c++ %s -verify -Wno-unused-value
 
 template
 constexpr bool is_same_v = false;
Index: clang/test/SemaTemplate/instantiate-requires-clause.cpp
===
--- clang/test/SemaTemplate/instantiate-requires-clause.cpp
+++ clang/test/SemaTemplate/instantiate-requires-clause.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ %s -verify
+// RUN: %clang_cc1 -std=c++2a -x c++ %s -verify
 
 template  requires ((sizeof(Args) == 1), ...)
 // expected-note@-1 {{because '(sizeof(int) == 1) , (sizeof(char) == 1) , (sizeof(int) == 1)' evaluated to false}}
Index: clang/test/SemaTemplate/instantiate-expanded-type-constraint.cpp
===
--- clang/test/SemaTemplate/instantiate-expanded-type-constraint.cpp
+++ 

[PATCH] D72552: [Concepts] Constraint Satisfaction Caching

2020-01-21 Thread Saar Raz via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb933d37cd377: [Concepts] Constraint Satisfaction Caching 
(authored by saar.raz).

Changed prior to commit:
  https://reviews.llvm.org/D72552?vs=237474=239464#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D72552

Files:
  clang/include/clang/AST/ASTConcept.h
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/CC1Options.td
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Sema/TemplateDeduction.h
  clang/lib/AST/ASTConcept.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaConcept.cpp
  clang/test/SemaTemplate/cxx2a-constraint-caching.cpp

Index: clang/test/SemaTemplate/cxx2a-constraint-caching.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/cxx2a-constraint-caching.cpp
@@ -0,0 +1,34 @@
+// RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
+// RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s -fno-concept-satisfaction-caching -DNO_CACHE
+// expected-no-diagnostics
+
+template
+concept C = (f(T()), true);
+
+template
+constexpr bool foo() { return false; }
+
+template
+  requires (f(T()), true)
+constexpr bool foo() requires (f(T()), true) { return true; }
+
+namespace a {
+  struct A {};
+  void f(A a);
+}
+
+static_assert(C);
+static_assert(foo());
+
+namespace a {
+  // This makes calls to f ambiguous, but the second check will still succeed
+  // because the constraint satisfaction results are cached.
+  void f(A a, int = 2);
+}
+#ifdef NO_CACHE
+static_assert(!C);
+static_assert(!foo());
+#else
+static_assert(C);
+static_assert(foo());
+#endif
\ No newline at end of file
Index: clang/lib/Sema/SemaConcept.cpp
===
--- clang/lib/Sema/SemaConcept.cpp
+++ clang/lib/Sema/SemaConcept.cpp
@@ -272,36 +272,56 @@
   return false;
 }
 
-bool Sema::CheckConstraintSatisfaction(TemplateDecl *Template,
-   ArrayRef ConstraintExprs,
-   ArrayRef TemplateArgs,
-   SourceRange TemplateIDRange,
-   ConstraintSatisfaction ) {
-  return ::CheckConstraintSatisfaction(*this, Template, ConstraintExprs,
-   TemplateArgs, TemplateIDRange,
-   Satisfaction);
-}
+bool Sema::CheckConstraintSatisfaction(
+NamedDecl *Template, ArrayRef ConstraintExprs,
+ArrayRef TemplateArgs, SourceRange TemplateIDRange,
+ConstraintSatisfaction ) {
+  if (ConstraintExprs.empty()) {
+OutSatisfaction.IsSatisfied = true;
+return false;
+  }
 
-bool
-Sema::CheckConstraintSatisfaction(ClassTemplatePartialSpecializationDecl* Part,
-  ArrayRef ConstraintExprs,
-  ArrayRef TemplateArgs,
-  SourceRange TemplateIDRange,
-  ConstraintSatisfaction ) {
-  return ::CheckConstraintSatisfaction(*this, Part, ConstraintExprs,
-   TemplateArgs, TemplateIDRange,
-   Satisfaction);
-}
+  llvm::FoldingSetNodeID ID;
+  void *InsertPos;
+  ConstraintSatisfaction *Satisfaction = nullptr;
+  if (LangOpts.ConceptSatisfactionCaching) {
+ConstraintSatisfaction::Profile(ID, Context, Template, TemplateArgs);
+Satisfaction = SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos);
+if (Satisfaction) {
+  OutSatisfaction = *Satisfaction;
+  return false;
+}
+Satisfaction = new ConstraintSatisfaction(Template, TemplateArgs);
+  } else {
+Satisfaction = 
+  }
+  bool Failed;
+  if (auto *T = dyn_cast(Template))
+Failed = ::CheckConstraintSatisfaction(*this, T, ConstraintExprs,
+   TemplateArgs, TemplateIDRange,
+   *Satisfaction);
+  else if (auto *P =
+   dyn_cast(Template))
+Failed = ::CheckConstraintSatisfaction(*this, P, ConstraintExprs,
+   TemplateArgs, TemplateIDRange,
+   *Satisfaction);
+  else
+Failed = ::CheckConstraintSatisfaction(
+*this, cast(Template),
+ConstraintExprs, TemplateArgs, TemplateIDRange, *Satisfaction);
+  if (Failed) {
+if (LangOpts.ConceptSatisfactionCaching)
+  delete Satisfaction;
+return true;
+  }
 
-bool
-Sema::CheckConstraintSatisfaction(VarTemplatePartialSpecializationDecl* Partial,
-  ArrayRef ConstraintExprs,
-  ArrayRef TemplateArgs,
-  SourceRange TemplateIDRange,
-  

[PATCH] D65042: [Concept] Placeholder constraints and abbreviated templates

2020-01-16 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 238478.
saar.raz marked 21 inline comments as done.
saar.raz added a comment.

Address CR comments.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D65042

Files:
  .gitignore
  clang/include/clang/Parse/Parser.h
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseTemplate.cpp
  clang/test/SemaTemplate/ms-delayed-default-template-args.cpp

Index: clang/test/SemaTemplate/ms-delayed-default-template-args.cpp
===
--- clang/test/SemaTemplate/ms-delayed-default-template-args.cpp
+++ clang/test/SemaTemplate/ms-delayed-default-template-args.cpp
@@ -94,6 +94,7 @@
 template  struct Bar { T x; };
 
 template  *P> // expected-error {{use of undeclared identifier 'Xylophone'}}
+// expected-note@-1{{template parameter is declared here}}
 struct Foo { };
 
 typedef int Xylophone;
Index: clang/lib/Parse/ParseTemplate.cpp
===
--- clang/lib/Parse/ParseTemplate.cpp
+++ clang/lib/Parse/ParseTemplate.cpp
@@ -501,7 +501,7 @@
 
 /// Determine whether the parser is at the start of a template
 /// type parameter.
-/// \param ScopeError will receive true if there was a parsing error.
+/// \param Error will receive true if there was a parsing error.
 bool Parser::isStartOfTemplateTypeParameter(bool ) {
   Error = false;
   if (Tok.is(tok::kw_class)) {
@@ -611,8 +611,8 @@
   // type-constraint is in fact part of a placeholder-type-specifier of a
   // non-type template parameter.
 
-  bool ScopeError;
-  if (isStartOfTemplateTypeParameter(ScopeError)) {
+  bool Error;
+  if (isStartOfTemplateTypeParameter(Error)) {
 // Is there just a typo in the input code? ('typedef' instead of
 // 'typename')
 if (Tok.is(tok::kw_typedef)) {
@@ -629,7 +629,7 @@
 
 return ParseTypeParameter(Depth, Position);
   }
-  if (ScopeError) {
+  if (Error) {
 // We return an invalid parameter as opposed to null to avoid having bogus
 // diagnostics about an empty template parameter list.
 // FIXME: Fix ParseTemplateParameterList to better handle nullptr results
@@ -679,7 +679,7 @@
 /// \returns true if an error occurred, and false otherwise.
 bool Parser::TryAnnotateTypeConstraint(CXXScopeSpec ) {
   if (!getLangOpts().ConceptsTS)
-return true;
+return false;
   if (ParseOptionalCXXScopeSpecifier(SS, ParsedType(),
  /*EnteringContext=*/false,
  /*MayBePseudoDestructor=*/nullptr,
Index: clang/lib/Parse/ParseDecl.cpp
===
--- clang/lib/Parse/ParseDecl.cpp
+++ clang/lib/Parse/ParseDecl.cpp
@@ -3472,13 +3472,12 @@
 ConsumeAnnotationToken();
 SourceLocation AutoLoc = Tok.getLocation();
 if (TryConsumeToken(tok::kw_decltype)) {
-  if (!Tok.is(tok::l_paren)) {
+  BalancedDelimiterTracker Tracker(*this, tok::l_paren);
+  if (Tracker.consumeOpen()) {
 // Something like `void foo(Iterator decltype i)`
 Diag(Tok, diag::err_expected) << tok::l_paren;
   } else {
-BalancedDelimiterTracker Tracker(*this, tok::l_paren);
-Tracker.consumeOpen();
-if (!ExpectAndConsume(tok::kw_auto)) {
+if (!TryConsumeToken(tok::kw_auto)) {
   // Something like `void foo(Iterator decltype(int) i)`
   Tracker.skipToEnd();
   Diag(Tok, diag::err_placeholder_decltype_non_auto)
@@ -3489,6 +3488,7 @@
   Tracker.consumeClose();
 }
   }
+  ConsumedEnd = Tok.getLocation();
   // Even if something went wrong above, continue as if we've seen
   // `decltype(auto)`.
   isInvalid = DS.SetTypeSpecType(TST_decltype_auto, Loc, PrevSpec,
Index: clang/include/clang/Parse/Parser.h
===
--- clang/include/clang/Parse/Parser.h
+++ clang/include/clang/Parse/Parser.h
@@ -3079,7 +3079,7 @@
SourceLocation );
   bool ParseTemplateParameterList(unsigned Depth,
   SmallVectorImpl );
-  bool isStartOfTemplateTypeParameter(bool );
+  bool isStartOfTemplateTypeParameter(bool );
   NamedDecl *ParseTemplateParameter(unsigned Depth, unsigned Position);
   NamedDecl *ParseTypeParameter(unsigned Depth, unsigned Position);
   NamedDecl *ParseTemplateTemplateParameter(unsigned Depth, unsigned Position);
Index: .gitignore
===
--- .gitignore
+++ .gitignore
@@ -54,7 +54,3 @@
 .vs
 # clangd index
 .clangd
-<<< Updated upstream
-===
-clang/\.idea/
->>> Stashed changes
___
cfe-commits mailing list
cfe-commits@lists.llvm.org

[PATCH] D50360: [Concepts] Requires Expressions

2020-01-15 Thread Saar Raz via Phabricator via cfe-commits
saar.raz marked an inline comment as done.
saar.raz added a comment.

Addressed comments in latest diff.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D50360



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


[PATCH] D50360: [Concepts] Requires Expressions

2020-01-15 Thread Saar Raz via Phabricator via cfe-commits
saar.raz marked 4 inline comments as done.
saar.raz added a comment.

Addressed comments in latest diff.




Comment at: clang/include/clang/AST/RecursiveASTVisitor.h:2714-2716
+  if (RetReq.isTypeConstraint())
+TRY_TO(TraverseTemplateParameterListHelper(
+   RetReq.getTypeConstraintTemplateParameterList()));

rsmith wrote:
> We should traverse the entire //type-constraint// here, including the nested 
> name specifier and concept name.
We are traversing all that down the line when traversing the actual template 
type parameter.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D50360



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


[PATCH] D72552: [Concepts] Constraint Satisfaction Caching

2020-01-10 Thread Saar Raz via Phabricator via cfe-commits
saar.raz created this revision.
saar.raz added a reviewer: rsmith.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Add a simple cache for constraint satisfaction results. This results in a
major speedup (cjdb measured x2 faster than gcc with this caching, compared
to being 'unbearably slow' without caching) and is conformant with gcc's
implementation.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D72552

Files:
  clang/include/clang/AST/ASTConcept.h
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Sema/TemplateDeduction.h
  clang/lib/AST/ASTConcept.cpp
  clang/lib/Sema/Sema.cpp
  clang/lib/Sema/SemaConcept.cpp
  clang/test/SemaTemplate/cxx2a-constraint-caching.cpp

Index: clang/test/SemaTemplate/cxx2a-constraint-caching.cpp
===
--- /dev/null
+++ clang/test/SemaTemplate/cxx2a-constraint-caching.cpp
@@ -0,0 +1,25 @@
+// RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
+// expected-no-diagnostics
+
+template
+concept C = (f(T()), true);
+
+template
+  requires (f(T()), true)
+constexpr bool foo() requires (f(T()), true) { return true; }
+
+namespace a {
+  struct A {};
+  void f(A a);
+}
+
+static_assert(C);
+static_assert(foo());
+
+namespace a {
+  // This makes calls to f ambiguous, but the second check will still succeed
+  // because the constraint satisfaction results are cached.
+  void f(A a, int = 2);
+}
+static_assert(C);
+static_assert(foo());
\ No newline at end of file
Index: clang/lib/Sema/SemaConcept.cpp
===
--- clang/lib/Sema/SemaConcept.cpp
+++ clang/lib/Sema/SemaConcept.cpp
@@ -269,36 +269,49 @@
   return false;
 }
 
-bool Sema::CheckConstraintSatisfaction(TemplateDecl *Template,
-   ArrayRef ConstraintExprs,
-   ArrayRef TemplateArgs,
-   SourceRange TemplateIDRange,
-   ConstraintSatisfaction ) {
-  return ::CheckConstraintSatisfaction(*this, Template, ConstraintExprs,
-   TemplateArgs, TemplateIDRange,
-   Satisfaction);
-}
+bool Sema::CheckConstraintSatisfaction(
+NamedDecl *Template, ArrayRef ConstraintExprs,
+ArrayRef TemplateArgs, SourceRange TemplateIDRange,
+ConstraintSatisfaction ) {
+  if (ConstraintExprs.empty()) {
+Satisfaction.IsSatisfied = true;
+return false;
+  }
 
-bool
-Sema::CheckConstraintSatisfaction(ClassTemplatePartialSpecializationDecl* Part,
-  ArrayRef ConstraintExprs,
-  ArrayRef TemplateArgs,
-  SourceRange TemplateIDRange,
-  ConstraintSatisfaction ) {
-  return ::CheckConstraintSatisfaction(*this, Part, ConstraintExprs,
-   TemplateArgs, TemplateIDRange,
-   Satisfaction);
-}
+  llvm::FoldingSetNodeID ID;
+  void *InsertPos;
+  ConstraintSatisfaction::Profile(ID, Context, Template, TemplateArgs);
+  ConstraintSatisfaction *Cached =
+  SatisfactionCache.FindNodeOrInsertPos(ID, InsertPos);
+  if (!Cached) {
+Cached = new ConstraintSatisfaction(Template, TemplateArgs);
+
+bool Failed;
+if (auto *T = dyn_cast(Template))
+  Failed = ::CheckConstraintSatisfaction(*this, T, ConstraintExprs,
+ TemplateArgs, TemplateIDRange,
+ *Cached);
+else if (auto *P =
+ dyn_cast(Template))
+  Failed = ::CheckConstraintSatisfaction(*this, P, ConstraintExprs,
+ TemplateArgs, TemplateIDRange,
+ *Cached);
+else
+  Failed = ::CheckConstraintSatisfaction(
+  *this, cast(Template),
+  ConstraintExprs, TemplateArgs, TemplateIDRange, *Cached);
+if (Failed) {
+  delete Cached;
+  return true;
+}
 
-bool
-Sema::CheckConstraintSatisfaction(VarTemplatePartialSpecializationDecl* Partial,
-  ArrayRef ConstraintExprs,
-  ArrayRef TemplateArgs,
-  SourceRange TemplateIDRange,
-  ConstraintSatisfaction ) {
-  return ::CheckConstraintSatisfaction(*this, Partial, ConstraintExprs,
-   TemplateArgs, TemplateIDRange,
-   Satisfaction);
+// We cannot use InsertNode here because CheckConstraintSatisfaction might
+// have invalidated it.
+SatisfactionCache.InsertNode(Cached);
+  }
+
+  Satisfaction = *Cached;
+  return false;
 }
 
 bool Sema::CheckConstraintSatisfaction(const Expr *ConstraintExpr,
Index: clang/lib/Sema/Sema.cpp

[PATCH] D44352: [Concepts] Type Constraints

2020-01-10 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added a comment.




Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D44352



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


[PATCH] D44352: [Concepts] Type Constraints

2020-01-09 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added a comment.

Addressed all but one comment in recent commit.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D44352



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


[PATCH] D43357: [Concepts] Function trailing requires clauses

2020-01-08 Thread Saar Raz via Phabricator via cfe-commits
saar.raz marked an inline comment as done.
saar.raz added inline comments.



Comment at: clang/lib/Sema/SemaOverload.cpp:6340-6347
   if (!AllowExplicit) {
 ExplicitSpecifier ES = ExplicitSpecifier::getFromDecl(Function);
 if (ES.getKind() != ExplicitSpecKind::ResolvedFalse) {
   Candidate.Viable = false;
   Candidate.FailureKind = ovl_fail_explicit_resolved;
   return;
 }

rsmith wrote:
> (Huh, this looks wrong: we should be checking this before we form parameter 
> conversion sequences, shouldn't we?)
Should I fix this in this patch?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D43357



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


[PATCH] D43357: [Concepts] Function trailing requires clauses

2019-12-20 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added inline comments.



Comment at: clang/lib/Parse/ParseDecl.cpp:2068-2069
 
   if (ParseAsmAttributesAfterDeclarator(D))
 return nullptr;
 

rsmith wrote:
> We should check with GCC to see which side of the requires-clause they expect 
> this.
> 
> For the second and subsequent declarations, we expect the asm label before 
> the requires clause; here we parse the asm label after the requires clause.
They expect the requires clause first.



Comment at: clang/lib/Parse/ParseDeclCXX.cpp:3799-3810
+if (D.isFunctionDeclarator()) {
+  auto  = D.getFunctionTypeInfo();
+  if (FTI.Params)
+for (auto  : ArrayRef(FTI.Params,
+
FTI.NumParams)){
+  auto *ParamDecl = cast(Param.Param);
+  if (ParamDecl->getIdentifier())

rsmith wrote:
> This scope-building code should be in `Sema`, not in the parser. (Consider 
> adding an `ActOnStartTrailingRequiresClause` / 
> `ActOnFinishTrailingRequiresClause` pair.)
Is there anything that needs to be in ActOnFinishTrailingRequiresClause?



Comment at: clang/lib/Parse/ParseExpr.cpp:349-350
+  if (Tok.is(tok::l_paren) &&
+  isa(RightMostExpr) &&
+  RightMostExpr->isTypeDependent()) {
+// We're facing one of the following cases:

rsmith wrote:
> The parser shouldn't be encoding this kind of semantic knowledge. Please move 
> this to `Sema`. (This is also not really a very general way to detect a 
> function-like name: checking for an expression whose type is a function type 
> or OverloadType would catch more cases.)
Function types and overload types would not reach here (would be eliminated in 
the previous check for 'bool' types). Only dependent types and bools get here, 
and checking for a function type or OverloadType would not catch those cases.

Anyway, moved this to Sema



Comment at: clang/lib/Parse/ParseExpr.cpp:354
+// template void foo() requires func(
+// In the first case, '(' cannot start a declaration, and in the second,
+// '(' cannot follow the requires-clause in a function-definition nor in

rsmith wrote:
> I don't think this is true. Consider:
> 
> ```
> struct A {
>   template requires X
>   (A)() {}
> };
> ```
> 
> For a trailing requires clause, we can be much more aggressive with our error 
> detection here, though, and in that case perhaps we can unconditionally treat 
> a trailing `(` as a function call.
If the cases where this is possible are only very remote - could we maybe turn 
this into a warning instead and keep it here?

Also, if X is a function type or OverloadType, then this is ill-formed 
anyway, right? since the constraint expression can't be a bool.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D43357



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


[PATCH] D41910: [Concepts] Constrained partial specializations and function overloads.

2019-12-18 Thread Saar Raz via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG12038be20ee6: [Concepts] Fix crash in D41910 (authored by 
saar.raz).

Changed prior to commit:
  https://reviews.llvm.org/D41910?vs=232457=234587#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D41910

Files:
  clang/lib/Sema/SemaConcept.cpp


Index: clang/lib/Sema/SemaConcept.cpp
===
--- clang/lib/Sema/SemaConcept.cpp
+++ clang/lib/Sema/SemaConcept.cpp
@@ -558,7 +558,7 @@
 Atomic.ParameterMapping.emplace();
 Atomic.ParameterMapping->reserve(OccurringIndices.size());
 for (unsigned I = 0, C = TemplateParams->size(); I != C; ++I)
-  if (OccurringIndices[I])
+  if (I < OccurringIndices.size() && OccurringIndices[I])
 Atomic.ParameterMapping->push_back(
 S.getIdentityTemplateArgumentLoc(TemplateParams->begin()[I],
 // Here we assume we do not support things like


Index: clang/lib/Sema/SemaConcept.cpp
===
--- clang/lib/Sema/SemaConcept.cpp
+++ clang/lib/Sema/SemaConcept.cpp
@@ -558,7 +558,7 @@
 Atomic.ParameterMapping.emplace();
 Atomic.ParameterMapping->reserve(OccurringIndices.size());
 for (unsigned I = 0, C = TemplateParams->size(); I != C; ++I)
-  if (OccurringIndices[I])
+  if (I < OccurringIndices.size() && OccurringIndices[I])
 Atomic.ParameterMapping->push_back(
 S.getIdentityTemplateArgumentLoc(TemplateParams->begin()[I],
 // Here we assume we do not support things like
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41910: [Concepts] Constrained partial specializations and function overloads.

2019-12-05 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added a comment.

Addressed in latest diff


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D41910



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


[PATCH] D41910: [Concepts] Constrained partial specializations and function overloads.

2019-12-05 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 232457.
saar.raz marked 7 inline comments as done.
saar.raz added a comment.

Address all CR comments by rsmith (including rewrite of normalization).
Decided to not support things like:

template
concept C = ...;

template requires C
struct S { };

For now, as wording is not clear what the normal form of these should be.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D41910

Files:
  clang/include/clang/AST/DeclTemplate.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/lib/AST/ASTImporter.cpp
  clang/lib/AST/DeclTemplate.cpp
  clang/lib/Sema/SemaConcept.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/lib/Serialization/ASTReaderDecl.cpp
  clang/lib/Serialization/ASTWriterDecl.cpp
  clang/test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  clang/test/CXX/concepts-ts/temp/temp.constr/temp.constr.normal/p1.cpp
  
clang/test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
  
clang/test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
  
clang/test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp

Index: clang/test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
===
--- /dev/null
+++ clang/test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 4
+bool a = false; // expected-note{{template is declared here}}
+
+template requires sizeof(T) >= 4 && sizeof(T) <= 10
+bool a = true; // expected-error{{variable template partial specialization is not more specialized than the primary template}}
+
+template
+concept C1 = sizeof(T) >= 4;
+
+template requires C1
+bool b = false;
+
+template requires C1 && sizeof(T) <= 10
+bool b = true;
+
+template
+concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
+
+template
+bool c = false;
+
+template requires C1
+bool c = true;
+
+template
+bool d = false;
+
+template
+bool d = true; // expected-error{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+
+template requires C1
+bool e = false;
+
+template
+bool e = true; // expected-error{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+
+template
+constexpr int f = 1;
+
+template requires C1 && C2
+constexpr int f = 2;
+
+template requires C1 || C2
+constexpr int f = 3;
+
+static_assert(f == 2);
+static_assert(f == 3);
+static_assert(f == 1);
+
+
+
Index: clang/test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
===
--- /dev/null
+++ clang/test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 4
+bool a() { return false; } // expected-note {{candidate function [with T = unsigned int]}}
+
+template requires sizeof(T) >= 4 && sizeof(T) <= 10
+bool a() { return true; } // expected-note {{candidate function [with T = unsigned int]}}
+
+bool av = a(); // expected-error {{call to 'a' is ambiguous}}
+
+template
+concept C1 = sizeof(T) >= 4;
+
+template requires C1
+constexpr bool b() { return false; }
+
+template requires C1 && sizeof(T) <= 10
+constexpr bool b() { return true; }
+
+static_assert(b());
+static_assert(!b());
+
+template
+concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
+
+template
+bool c() { return false; }
+
+template requires C1
+bool c() { return true; }
+
+template requires C1
+constexpr bool d() { return false; }
+
+template
+constexpr bool d() { return true; }
+
+static_assert(!d());
+
+template
+constexpr int e() { return 1; }
+
+template requires C1 && C2
+constexpr int e() { return 2; }
+
+template requires C1 || C2
+constexpr int e() { return 3; }
+
+static_assert(e() == 2);
+static_assert(e() == 3);
+static_assert(e() == 1);
+
+template
+concept BiggerThan = sizeof(T) > sizeof(U);
+
+template
+concept BiggerThanInt = BiggerThan;
+
+template requires BiggerThan
+void f() { }
+// expected-note@-1 {{candidate function [with T = long long, U = int]}}
+
+template requires BiggerThanInt
+void f() { }
+// expected-note@-1 {{candidate function [with T = long long, U = int]}}
+
+static_assert(sizeof(f()));
+// expected-error@-1 {{call to 'f' is ambiguous}}
+
+template
+concept C3 = true;
+
+template
+concept C4 = true && C3;
+

[PATCH] D50360: [Concepts] Requires Expressions

2019-11-05 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added inline comments.



Comment at: lib/Sema/SemaTemplateInstantiate.cpp:1021-1052
+ExprResult TransformRequiresExpr(RequiresExpr *E) {
+  LocalInstantiationScope Scope(SemaRef, /*CombineWithOuterScope=*/true);
+  return TreeTransform::TransformRequiresExpr(E);
+}
+
+bool TransformRequiresExprRequirements(ArrayRef Reqs,
+SmallVectorImpl ) {

rsmith wrote:
> Do we really need to duplicate the `TreeTransform` code here, and add a 
> representation for a requirement whose substitution failed, and so on?
> 
> Possible alternative: create a `SFINAETrap` for the entire 
> requires-expression, perform a `TreeTransform` of the whole thing, and if it 
> fails, capture the diagnostic and build a `FailedRequiresExpr` node that 
> stores the diagnostic and evaluates to `false`. (Under this model, a 
> non-value-dependent `RequiresExpr` would always evaluate to `true`.) That 
> should simplify this code, and the representations of `RequiresExpr` and 
> `Requirements` (since you don't need to model "substitution failed" any more, 
> nor conditionally store a diagnostic on a requirement).
> 
> Are there cases where we want to retain more information than that? (I don't 
> think there are, since you don't actually retain any useful information from 
> the requirement that failed, other than the diagnostic itself, but maybe I've 
> missed something.) The results of a successful substitution into some parts 
> of a failed `RequiresExpr` don't really seem interesting.
Wouldn't it be interesting to store the successful requirements prior to the 
failed ones? I imagine some tools might want this information


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D50360



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


[PATCH] D41569: [Concepts] Constraint enforcement and diagnostics

2019-10-24 Thread Saar Raz via Phabricator via cfe-commits
saar.raz closed this revision.
saar.raz added a comment.

Committed ffa214ef22892d75340dc6720271863901dc2c90 



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D41569



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


[PATCH] D41569: [Concepts] Constraint enforcement and diagnostics

2019-10-17 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 225418.
saar.raz added a comment.

Address CR comments by rsmith.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D41569

Files:
  clang/include/clang/AST/ASTConcept.h
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Sema/TemplateDeduction.h
  clang/lib/AST/ASTConcept.cpp
  clang/lib/AST/ASTContext.cpp
  clang/lib/AST/CMakeLists.txt
  clang/lib/AST/Decl.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/Sema/SemaConcept.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateDeduction.cpp
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/test/CXX/expr/expr.prim/expr.prim.id/p3.cpp
  clang/test/CXX/temp/temp.constr/temp.constr.constr/function-templates.cpp
  clang/test/CXX/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
  clang/test/CXX/temp/temp.constr/temp.constr.constr/partial-specializations.cpp

Index: clang/test/CXX/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
===
--- /dev/null
+++ clang/test/CXX/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+namespace class_templates
+{
+  template requires sizeof(T) >= 4 // expected-note {{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}}
+  struct is_same { static constexpr bool value = false; };
+
+  template requires sizeof(T*) >= 4 && sizeof(T) >= 4
+  struct is_same { static constexpr bool value = true; };
+
+  static_assert(!is_same::value);
+  static_assert(!is_same::value);
+  static_assert(is_same::value);
+  static_assert(is_same::value); // expected-error {{constraints not satisfied for class template 'is_same' [with T = char, U = char]}}
+
+  template
+  struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}}
+
+  template
+  struct B {};
+
+  template requires A::type // expected-note{{in instantiation of template class 'class_templates::A' requested here}}
+   // expected-note@-1{{while substituting template arguments into constraint expression here}}
+  struct B {};
+
+  template requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}}
+  struct B {};
+
+  static_assert((B{}, true)); // expected-note{{while checking constraint satisfaction for class template partial specialization 'B' required here}}
+  // expected-note@-1{{while checking constraint satisfaction for class template partial specialization 'B' required here}}
+  // expected-note@-2{{during template argument deduction for class template partial specialization 'B' [with T = int *]}}
+  // expected-note@-3{{during template argument deduction for class template partial specialization 'B' [with T = int]}}
+  // expected-note@-4 2{{in instantiation of template class 'class_templates::B' requested here}}
+}
+
+namespace variable_templates
+{
+  template requires sizeof(T) >= 4
+  constexpr bool is_same_v = false;
+
+  template requires sizeof(T*) >= 4 && sizeof(T) >= 4
+  constexpr bool is_same_v = true;
+
+  static_assert(!is_same_v);
+  static_assert(!is_same_v);
+  static_assert(is_same_v);
+
+  template
+  struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}}
+
+  template
+  constexpr bool v1 = false;
+
+  template requires A::type // expected-note{{in instantiation of template class 'variable_templates::A' requested here}}
+   // expected-note@-1{{while substituting template arguments into constraint expression here}}
+  constexpr bool v1 = true;
+
+  template requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}}
+  constexpr bool v1 = true;
+
+  static_assert(v1); // expected-note{{while checking constraint satisfaction for variable template partial specialization 'v1' required here}}
+  // expected-note@-1{{while checking constraint satisfaction for variable template partial specialization 'v1' required here}}
+  // expected-note@-2{{during template argument deduction for variable template partial specialization 'v1' [with T = int *]}}
+  // expected-note@-3{{during template argument deduction for variable template partial specialization 'v1' [with T = int]}}
+  // expected-error@-4{{static_assert failed due to requirement 'v1'}}
+
+}
\ No newline at end of file
Index: clang/test/CXX/temp/temp.constr/temp.constr.constr/non-function-templates.cpp

[PATCH] D50360: [Concepts] Requires Expressions

2019-10-14 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added inline comments.



Comment at: lib/AST/StmtProfile.cpp:1325
+  //expression. It is equivalent to the simple-requirement x++; [...]
+  // We therefore do not profile isSimple() here.
+  ID.AddBoolean(ExprReq->getNoexceptLoc().isValid());

rsmith wrote:
> We don't /need to/ profile `isSimple`, but we still could. (This "is 
> equivalent to" doesn't override the general ODR requirement that you spell 
> the expression with the same token sequence.)
> 
> Do we mangle simple and compound requirements the same way? (Has a mangling 
> for requires-expressions even been proposed on the Itanium ABI list yet?)
Not yet :(


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D50360



___
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.

2019-10-14 Thread Saar Raz via Phabricator via cfe-commits
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] D41217: [Concepts] Concept Specialization Expressions

2019-10-13 Thread Saar Raz via Phabricator via cfe-commits
saar.raz marked 14 inline comments as done and 2 inline comments as done.
saar.raz added inline comments.



Comment at: lib/Sema/SemaConcept.cpp:51-68
+  if (auto *BO = dyn_cast(ConstraintExpr)) {
+if (BO->getOpcode() == BO_LAnd) {
+  if (CalculateConstraintSatisfaction(NamedConcept, MLTAL, BO->getLHS(),
+  IsSatisfied))
+return true;
+  if (!IsSatisfied)
+return false;

rsmith wrote:
> If an `operator&&` or `operator||` function is declared, this could be a 
> `CXXOperatorCallExpr` instead. You will need to recurse into those constructs 
> too.
Atomic constraints will have bool types anyway, can this really happen?



Comment at: lib/Sema/SemaConcept.cpp:72-74
+  else if (auto *C = dyn_cast(ConstraintExpr))
+return CalculateConstraintSatisfaction(NamedConcept, MLTAL, 
C->getSubExpr(),
+   IsSatisfied);

rsmith wrote:
> This case is not handled by `CheckConstraintExpression`; we should be 
> consistent in whether we step over these or not.
> 
> Perhaps it would make sense to factor out a mechanism to take an expression 
> and classify it as atomic constraint (with the corresponding expression), or 
> conjunction (with a pair of subexpressions), or disjunction (with a pair of 
> subexpressions), and use that everywhere we traverse a constraint expression.
Since this part will be changed in later patches, I'd like to delay this fix to 
a later patch for now.



Comment at: lib/Sema/SemaTemplateInstantiate.cpp:679-681
+  Diags.Report(Active->PointOfInstantiation,
+   diag::note_constraint_substitution_here)
+  << Active->InstantiationRange;

saar.raz wrote:
> saar.raz wrote:
> > rsmith wrote:
> > > Is this note ever useful? It will presumably always point into the same 
> > > concept definition that the prior diagnostic also pointed at, and doesn't 
> > > seem to add anything in the testcases.
> > > 
> > > Maybe we could keep the CodeSynthesisContext around as a marker that 
> > > we've entered a SFINAE context, but not have any corresponding 
> > > diagnostic. (The note produced for the enclosing `ConstraintsCheck` 
> > > context covers that.) Or we could remove this and store a flag on the 
> > > `ConstraintsCheck` to indicate whether we're in a SFINAEable portion of 
> > > it.
> > If the concept definition is multiline/contains macros, this would point at 
> > the exact place where the problematic constraint occured, we should 
> > probably add tests for this case though.
> > Maybe we can omit the diagnostic when the concept and the constraint are on 
> > the same line or something?
> > 
> Correction - I just now realized you were referring to the 'in instantiation 
> of template class' note and not the 'while checking the satisfaction...' note.
> In this case - the only case I can think of where the problematic 
> instantiation and the constraint expression would be in very different places 
> is indeed multiline constraint expressions or macros in a constraint 
> expression (but you know better than I do - can you think of any other cases? 
> or maybe there are other non-SFINAE errors that can result from substitution 
> and would not produce a note?). Maybe these cases are remote enough to 
> warrant removing this diagnostic or as I said earlier omit them in cases 
> where they are unhelpful.
In any case, I'm in favor of pushing this to a separate patch (after we have 
diagnostics for requires exprs, which would suffer from a similar problem)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D41217



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


[PATCH] D41217: [Concepts] Concept Specialization Expressions

2019-10-13 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 224789.
saar.raz marked 2 inline comments as done.
saar.raz added a comment.

Address CR comments by rsmith


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D41217

Files:
  clang/include/clang/AST/ExprCXX.h
  clang/include/clang/AST/RecursiveASTVisitor.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/StmtNodes.td
  clang/include/clang/Sema/Sema.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/lib/AST/Expr.cpp
  clang/lib/AST/ExprCXX.cpp
  clang/lib/AST/ExprClassification.cpp
  clang/lib/AST/ExprConstant.cpp
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/StmtPrinter.cpp
  clang/lib/AST/StmtProfile.cpp
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/lib/Frontend/FrontendActions.cpp
  clang/lib/Parse/ParseExpr.cpp
  clang/lib/Sema/CMakeLists.txt
  clang/lib/Sema/SemaConcept.cpp
  clang/lib/Sema/SemaExceptionSpec.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/lib/Sema/SemaTemplateInstantiate.cpp
  clang/lib/Sema/TreeTransform.h
  clang/lib/Serialization/ASTReaderStmt.cpp
  clang/lib/Serialization/ASTWriterStmt.cpp
  clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  clang/test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  clang/test/Parser/cxx2a-concept-declaration.cpp
  clang/tools/libclang/CXCursor.cpp

Index: clang/tools/libclang/CXCursor.cpp
===
--- clang/tools/libclang/CXCursor.cpp
+++ clang/tools/libclang/CXCursor.cpp
@@ -256,6 +256,7 @@
   case Stmt::BinaryConditionalOperatorClass:
   case Stmt::TypeTraitExprClass:
   case Stmt::CoawaitExprClass:
+  case Stmt::ConceptSpecializationExprClass:
   case Stmt::DependentCoawaitExprClass:
   case Stmt::CoyieldExprClass:
   case Stmt::CXXBindTemporaryExprClass:
Index: clang/test/Parser/cxx2a-concept-declaration.cpp
===
--- clang/test/Parser/cxx2a-concept-declaration.cpp
+++ clang/test/Parser/cxx2a-concept-declaration.cpp
@@ -14,8 +14,6 @@
 // expected-error@-2{{template template parameter requires 'class' after the parameter list}}
 // expected-error@-3{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}}
 
-template concept C2 = 0.f; // expected-error {{constraint expression must be of type 'bool' but is of type 'float'}}
-
 struct S1 {
   template concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}}
 };
@@ -26,15 +24,15 @@
 
 template
 template
-concept C4 = true; // expected-error {{extraneous template parameter list in concept definition}}
+concept C2 = true; // expected-error {{extraneous template parameter list in concept definition}}
 
-template concept C5 = true; // expected-note {{previous}} expected-note {{previous}}
-int C5; // expected-error {{redefinition}}
-struct C5 {}; // expected-error {{redefinition}}
+template concept C3 = true; // expected-note {{previous}} expected-note {{previous}}
+int C3; // expected-error {{redefinition}}
+struct C3 {}; // expected-error {{redefinition}}
 
-struct C6 {}; // expected-note{{previous definition is here}}
-template concept C6 = true;
-// expected-error@-1{{redefinition of 'C6' as different kind of symbol}}
+struct C4 {}; // expected-note{{previous definition is here}}
+template concept C4 = true;
+// expected-error@-1{{redefinition of 'C4' as different kind of symbol}}
 
 // TODO: Add test to prevent explicit specialization, partial specialization
 // and explicit instantiation of concepts.
@@ -43,31 +41,60 @@
 struct integral_constant { static constexpr T value = v; };
 
 namespace N {
-  template concept C7 = true;
+  template concept C5 = true;
 }
-using N::C7;
+using N::C5;
 
-template  concept C8 = integral_constant::value;
+template  concept C6 = integral_constant::value;
 // expected-error@-1{{use of undeclared identifier 'wor'; did you mean 'word'?}}
 // expected-note@-2{{'word' declared here}}
 
-template concept bool C9 = true;
+template concept bool C7 = true;
 // expected-warning@-1{{ISO C++2a does not permit the 'bool' keyword after 'concept'}}
 
-template<> concept C10 = false;
+template<> concept C8 = false;
 // expected-error@-1{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}}
 
-template<> concept C9 = false;
+template<> concept C7 = false;
 // expected-error@-1{{name defined in concept definition must be an identifier}}
 
-template concept N::C11 = false;
+template concept N::C9 = false;
 // expected-error@-1{{name defined in concept definition must be an identifier}}
 
 class A { };
 // expected-note@-1{{'A' declared here}}
 
-template concept A::C12 = false;
+template concept A::C10 = false;
 // expected-error@-1{{expected namespace name}}
 
 template concept operator int = false;
 // expected-error@-1{{name 

[PATCH] D41569: [Concepts] Constraint enforcement and diagnostics

2019-07-13 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 209695.
saar.raz added a comment.

Move ConstraintSatisfaction to ASTConcept.h


Repository:
  rC Clang

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

https://reviews.llvm.org/D41569

Files:
  include/clang/AST/ASTConcept.h
  include/clang/AST/ExprCXX.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  include/clang/Sema/TemplateDeduction.h
  lib/AST/ASTConcept.cpp
  lib/AST/ASTContext.cpp
  lib/AST/CMakeLists.txt
  lib/AST/Decl.cpp
  lib/AST/ExprCXX.cpp
  lib/AST/ItaniumMangle.cpp
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
  test/CodeGenCXX/mangle-concept.cpp

Index: test/CodeGenCXX/mangle-concept.cpp
===
--- /dev/null
+++ test/CodeGenCXX/mangle-concept.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -verify -Wno-return-type -Wno-main -std=c++2a -fconcepts-ts -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
+// expected-no-diagnostics
+
+namespace test1 {
+template  struct S {};
+template  concept C = true;
+template  S> f0() { return S>{}; }
+template S> f0<>();
+// CHECK: void @_ZN5test12f0IiEENS_1SIXL_ZNS_1CIT_EEv()
+}
+
+template  struct S {};
+template  concept C = true;
+template  S> f0() { return S>{}; }
+template S> f0<>();
+// CHECK: void @_Z2f0IiE1SIXL_Z1CIT_v()
\ No newline at end of file
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+namespace class_templates
+{
+  template requires sizeof(T) >= 4 // expected-note {{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}}
+  struct is_same { static constexpr bool value = false; };
+
+  template requires sizeof(T*) >= 4 && sizeof(T) >= 4
+  struct is_same { static constexpr bool value = true; };
+
+  static_assert(!is_same::value);
+  static_assert(!is_same::value);
+  static_assert(is_same::value);
+  static_assert(is_same::value); // expected-error {{constraints not satisfied for class template 'is_same' [with T = char, U = char]}}
+
+  template
+  struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}}
+
+  template
+  struct B {};
+
+  template requires A::type // expected-note{{in instantiation of template class 'class_templates::A' requested here}}
+   // expected-note@-1{{while substituting template arguments into constraint expression here}}
+  struct B {};
+
+  template requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}}
+  struct B {};
+
+  static_assert((B{}, true)); // expected-note{{while checking constraint satisfaction for class template partial specialization 'B' required here}}
+  // expected-note@-1{{while checking constraint satisfaction for class template partial specialization 'B' required here}}
+  // expected-note@-2{{during template argument deduction for class template partial specialization 'B' [with T = int *]}}
+  // expected-note@-3{{during template argument deduction for class template partial specialization 'B' [with T = int]}}
+  // expected-note@-4 2{{in instantiation of template class 'class_templates::B' requested here}}
+}
+
+namespace variable_templates
+{
+  template requires sizeof(T) >= 4
+  constexpr bool is_same_v = false;
+
+  template requires sizeof(T*) >= 4 && sizeof(T) >= 4
+  constexpr bool is_same_v = true;
+
+  static_assert(!is_same_v);
+  static_assert(!is_same_v);
+  static_assert(is_same_v);
+
+  template
+  struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}}
+
+  template
+  constexpr bool v1 = false;
+
+  template requires A::type // expected-note{{in instantiation of template class 'variable_templates::A' requested here}}
+   // expected-note@-1{{while substituting template arguments into constraint expression here}}
+  constexpr bool v1 = true;
+
+  template requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}}
+  constexpr bool v1 = true;
+
+  

[PATCH] D41569: [Concepts] Constraint enforcement and diagnostics

2019-07-13 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 209689.
saar.raz added a comment.

Create ASTConstraintSatisfaction for correctly storing constraint satisfaction 
data in AST nodes, add support for mangling of ConceptSpecializtationExprs


Repository:
  rC Clang

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

https://reviews.llvm.org/D41569

Files:
  include/clang/AST/ASTConcept.h
  include/clang/AST/ExprCXX.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  include/clang/Sema/SemaConcept.h
  include/clang/Sema/TemplateDeduction.h
  lib/AST/ASTConcept.cpp
  lib/AST/CMakeLists.txt
  lib/AST/Decl.cpp
  lib/AST/ExprCXX.cpp
  lib/AST/ItaniumMangle.cpp
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
  test/CodeGenCXX/mangle-concept.cpp

Index: test/CodeGenCXX/mangle-concept.cpp
===
--- /dev/null
+++ test/CodeGenCXX/mangle-concept.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -verify -Wno-return-type -Wno-main -std=c++2a -fconcepts-ts -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
+// expected-no-diagnostics
+
+namespace test1 {
+template  struct S {};
+template  concept C = true;
+template  S> f0() { return S>{}; }
+template S> f0<>();
+// CHECK: void @_ZN5test12f0IiEENS_1SIXL_ZNS_1CIT_EEv()
+}
+
+template  struct S {};
+template  concept C = true;
+template  S> f0() { return S>{}; }
+template S> f0<>();
+// CHECK: void @_Z2f0IiE1SIXL_Z1CIT_v()
\ No newline at end of file
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+namespace class_templates
+{
+  template requires sizeof(T) >= 4 // expected-note {{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}}
+  struct is_same { static constexpr bool value = false; };
+
+  template requires sizeof(T*) >= 4 && sizeof(T) >= 4
+  struct is_same { static constexpr bool value = true; };
+
+  static_assert(!is_same::value);
+  static_assert(!is_same::value);
+  static_assert(is_same::value);
+  static_assert(is_same::value); // expected-error {{constraints not satisfied for class template 'is_same' [with T = char, U = char]}}
+
+  template
+  struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}}
+
+  template
+  struct B {};
+
+  template requires A::type // expected-note{{in instantiation of template class 'class_templates::A' requested here}}
+   // expected-note@-1{{while substituting template arguments into constraint expression here}}
+  struct B {};
+
+  template requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}}
+  struct B {};
+
+  static_assert((B{}, true)); // expected-note{{while checking constraint satisfaction for class template partial specialization 'B' required here}}
+  // expected-note@-1{{while checking constraint satisfaction for class template partial specialization 'B' required here}}
+  // expected-note@-2{{during template argument deduction for class template partial specialization 'B' [with T = int *]}}
+  // expected-note@-3{{during template argument deduction for class template partial specialization 'B' [with T = int]}}
+  // expected-note@-4 2{{in instantiation of template class 'class_templates::B' requested here}}
+}
+
+namespace variable_templates
+{
+  template requires sizeof(T) >= 4
+  constexpr bool is_same_v = false;
+
+  template requires sizeof(T*) >= 4 && sizeof(T) >= 4
+  constexpr bool is_same_v = true;
+
+  static_assert(!is_same_v);
+  static_assert(!is_same_v);
+  static_assert(is_same_v);
+
+  template
+  struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}}
+
+  template
+  constexpr bool v1 = false;
+
+  template requires A::type // expected-note{{in instantiation of template class 'variable_templates::A' requested here}}
+   // expected-note@-1{{while substituting template arguments into constraint expression here}}
+  constexpr bool v1 = true;
+
+  template requires T{} // 

[PATCH] D41284: [Concepts] Associated constraints infrastructure.

2019-07-13 Thread Saar Raz via Phabricator via cfe-commits
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 {
-  

[PATCH] D41217: [Concepts] Concept Specialization Expressions

2019-07-13 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 209686.
saar.raz added a comment.
Herald added a subscriber: erik.pilkington.

Rebase onto trunk.


Repository:
  rC Clang

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

https://reviews.llvm.org/D41217

Files:
  include/clang/AST/ExprCXX.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/StmtNodes.td
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/Expr.cpp
  lib/AST/ExprCXX.cpp
  lib/AST/ExprClassification.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Frontend/FrontendActions.cpp
  lib/Parse/ParseExpr.cpp
  lib/Sema/CMakeLists.txt
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaExceptionSpec.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  test/Parser/cxx2a-concept-declaration.cpp
  tools/libclang/CXCursor.cpp

Index: tools/libclang/CXCursor.cpp
===
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -256,6 +256,7 @@
   case Stmt::BinaryConditionalOperatorClass:
   case Stmt::TypeTraitExprClass:
   case Stmt::CoawaitExprClass:
+  case Stmt::ConceptSpecializationExprClass:
   case Stmt::DependentCoawaitExprClass:
   case Stmt::CoyieldExprClass:
   case Stmt::CXXBindTemporaryExprClass:
Index: test/Parser/cxx2a-concept-declaration.cpp
===
--- test/Parser/cxx2a-concept-declaration.cpp
+++ test/Parser/cxx2a-concept-declaration.cpp
@@ -14,8 +14,6 @@
 // expected-error@-2{{template template parameter requires 'class' after the parameter list}}
 // expected-error@-3{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}}
 
-template concept C2 = 0.f; // expected-error {{constraint expression must be of type 'bool' but is of type 'float'}}
-
 struct S1 {
   template concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}}
 };
@@ -26,15 +24,15 @@
 
 template
 template
-concept C4 = true; // expected-error {{extraneous template parameter list in concept definition}}
+concept C2 = true; // expected-error {{extraneous template parameter list in concept definition}}
 
-template concept C5 = true; // expected-note {{previous}} expected-note {{previous}}
-int C5; // expected-error {{redefinition}}
-struct C5 {}; // expected-error {{redefinition}}
+template concept C3 = true; // expected-note {{previous}} expected-note {{previous}}
+int C3; // expected-error {{redefinition}}
+struct C3 {}; // expected-error {{redefinition}}
 
-struct C6 {}; // expected-note{{previous definition is here}}
-template concept C6 = true;
-// expected-error@-1{{redefinition of 'C6' as different kind of symbol}}
+struct C4 {}; // expected-note{{previous definition is here}}
+template concept C4 = true;
+// expected-error@-1{{redefinition of 'C4' as different kind of symbol}}
 
 // TODO: Add test to prevent explicit specialization, partial specialization
 // and explicit instantiation of concepts.
@@ -43,31 +41,55 @@
 struct integral_constant { static constexpr T value = v; };
 
 namespace N {
-  template concept C7 = true;
+  template concept C5 = true;
 }
-using N::C7;
+using N::C5;
 
-template  concept C8 = integral_constant::value;
+template  concept C6 = integral_constant::value;
 // expected-error@-1{{use of undeclared identifier 'wor'; did you mean 'word'?}}
 // expected-note@-2{{'word' declared here}}
 
-template concept bool C9 = true;
+template concept bool C7 = true;
 // expected-warning@-1{{ISO C++2a does not permit the 'bool' keyword after 'concept'}}
 
-template<> concept C10 = false;
+template<> concept C8 = false;
 // expected-error@-1{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}}
 
-template<> concept C9 = false;
+template<> concept C7 = false;
 // expected-error@-1{{name defined in concept definition must be an identifier}}
 
-template concept N::C11 = false;
+template concept N::C9 = false;
 // expected-error@-1{{name defined in concept definition must be an identifier}}
 
 class A { };
 // expected-note@-1{{'A' declared here}}
 
-template concept A::C12 = false;
+template concept A::C10 = false;
 // expected-error@-1{{expected namespace name}}
 
 template concept operator int = false;
 // expected-error@-1{{name defined in concept definition must be an identifier}}
+
+template concept C11 = 2; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template concept C12 = 2 && x; // expected-error {{atomic 

[PATCH] D40381: Parse concept definition

2019-07-10 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 209068.
saar.raz added a comment.

Final committed diff.


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

https://reviews.llvm.org/D40381

Files:
  include/clang/AST/ASTNodeTraverser.h
  include/clang/AST/DeclTemplate.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/AST/TextNodeDumper.h
  include/clang/Basic/DeclNodes.td
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/TemplateKinds.h
  include/clang/Parse/Parser.h
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTStructuralEquivalence.cpp
  lib/AST/DeclBase.cpp
  lib/AST/DeclPrinter.cpp
  lib/AST/DeclTemplate.cpp
  lib/AST/TextNodeDumper.cpp
  lib/CodeGen/CGDecl.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/Index/IndexDecl.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaLookup.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  test/Parser/cxx-concept-declaration.cpp
  test/Parser/cxx-concepts-ambig-constraint-expr.cpp
  test/Parser/cxx-concepts-requires-clause.cpp
  test/Parser/cxx2a-concept-declaration.cpp
  test/Parser/cxx2a-concepts-ambig-constraint-expr.cpp
  test/Parser/cxx2a-concepts-requires-clause.cpp
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -6269,6 +6269,7 @@
   case Decl::PragmaComment:
   case Decl::PragmaDetectMismatch:
   case Decl::UsingPack:
+  case Decl::Concept:
 return C;
 
   // Declaration kinds that don't make any sense here, but are
Index: test/Parser/cxx2a-concept-declaration.cpp
===
--- /dev/null
+++ test/Parser/cxx2a-concept-declaration.cpp
@@ -0,0 +1,73 @@
+// Support parsing of concepts
+
+// RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
+template concept C1 = true; // expected-note 2{{previous}}
+
+template concept C1 = true; // expected-error{{redefinition}}
+
+template concept D1 = true;
+// expected-error@-1{{expected template parameter}}
+// expected-error@-2{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}}
+
+template concept T> concept D2 = true;
+// expected-error@-1{{expected identifier}}
+// expected-error@-2{{template template parameter requires 'class' after the parameter list}}
+// expected-error@-3{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}}
+
+template concept C2 = 0.f; // expected-error {{constraint expression must be of type 'bool' but is of type 'float'}}
+
+struct S1 {
+  template concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}}
+};
+
+extern "C++" {
+  template concept C1 = true; // expected-error{{redefinition}}
+}
+
+template
+template
+concept C4 = true; // expected-error {{extraneous template parameter list in concept definition}}
+
+template concept C5 = true; // expected-note {{previous}} expected-note {{previous}}
+int C5; // expected-error {{redefinition}}
+struct C5 {}; // expected-error {{redefinition}}
+
+struct C6 {}; // expected-note{{previous definition is here}}
+template concept C6 = true;
+// expected-error@-1{{redefinition of 'C6' as different kind of symbol}}
+
+// TODO: Add test to prevent explicit specialization, partial specialization
+// and explicit instantiation of concepts.
+
+template
+struct integral_constant { static constexpr T value = v; };
+
+namespace N {
+  template concept C7 = true;
+}
+using N::C7;
+
+template  concept C8 = integral_constant::value;
+// expected-error@-1{{use of undeclared identifier 'wor'; did you mean 'word'?}}
+// expected-note@-2{{'word' declared here}}
+
+template concept bool C9 = true;
+// expected-warning@-1{{ISO C++2a does not permit the 'bool' keyword after 'concept'}}
+
+template<> concept C10 = false;
+// expected-error@-1{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}}
+
+template<> concept C9 = false;
+// expected-error@-1{{name defined in concept definition must be an identifier}}
+
+template concept N::C11 = false;
+// expected-error@-1{{name defined in concept definition must be an identifier}}
+
+class A { };
+// expected-note@-1{{'A' declared here}}
+
+template concept A::C12 = false;
+// expected-error@-1{{expected namespace name}}
+
+template concept operator int = false;
+// expected-error@-1{{name defined in concept definition must be an identifier}}
Index: test/Parser/cxx-concept-declaration.cpp

[PATCH] D41569: [Concepts] Constraint enforcement and diagnostics

2019-06-29 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 207209.
saar.raz added a comment.
Herald added subscribers: erik.pilkington, mgorny.

Create ASTConstraintSatisfaction for correctly storing constraint satisfaction 
data in AST nodes.


Repository:
  rC Clang

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

https://reviews.llvm.org/D41569

Files:
  include/clang/AST/ASTConcept.h
  include/clang/AST/ExprCXX.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  include/clang/Sema/SemaConcept.h
  include/clang/Sema/TemplateDeduction.h
  lib/AST/ASTConcept.cpp
  lib/AST/CMakeLists.txt
  lib/AST/Decl.cpp
  lib/AST/ExprCXX.cpp
  lib/AST/ItaniumMangle.cpp
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
  test/CodeGenCXX/mangle-concept.cpp

Index: test/CodeGenCXX/mangle-concept.cpp
===
--- /dev/null
+++ test/CodeGenCXX/mangle-concept.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -verify -Wno-return-type -Wno-main -std=c++2a -fconcepts-ts -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
+// expected-no-diagnostics
+
+namespace test1 {
+template  struct S {};
+template  concept C = true;
+template  S> f0() { return S>{}; }
+template S> f0<>();
+// CHECK: void @_ZN5test12f0IiEENS_1SIXL_ZNS_1CIT_EEv()
+}
+
+template  struct S {};
+template  concept C = true;
+template  S> f0() { return S>{}; }
+template S> f0<>();
+// CHECK: void @_Z2f0IiE1SIXL_Z1CIT_v()
\ No newline at end of file
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+namespace class_templates
+{
+  template requires sizeof(T) >= 4 // expected-note {{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}}
+  struct is_same { static constexpr bool value = false; };
+
+  template requires sizeof(T*) >= 4 && sizeof(T) >= 4
+  struct is_same { static constexpr bool value = true; };
+
+  static_assert(!is_same::value);
+  static_assert(!is_same::value);
+  static_assert(is_same::value);
+  static_assert(is_same::value); // expected-error {{constraints not satisfied for class template 'is_same' [with T = char, U = char]}}
+
+  template
+  struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}}
+
+  template
+  struct B {};
+
+  template requires A::type // expected-note{{in instantiation of template class 'class_templates::A' requested here}}
+   // expected-note@-1{{while substituting template arguments into constraint expression here}}
+  struct B {};
+
+  template requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}}
+  struct B {};
+
+  static_assert((B{}, true)); // expected-note{{while checking constraint satisfaction for class template partial specialization 'B' required here}}
+  // expected-note@-1{{while checking constraint satisfaction for class template partial specialization 'B' required here}}
+  // expected-note@-2{{during template argument deduction for class template partial specialization 'B' [with T = int *]}}
+  // expected-note@-3{{during template argument deduction for class template partial specialization 'B' [with T = int]}}
+  // expected-note@-4 2{{in instantiation of template class 'class_templates::B' requested here}}
+}
+
+namespace variable_templates
+{
+  template requires sizeof(T) >= 4
+  constexpr bool is_same_v = false;
+
+  template requires sizeof(T*) >= 4 && sizeof(T) >= 4
+  constexpr bool is_same_v = true;
+
+  static_assert(!is_same_v);
+  static_assert(!is_same_v);
+  static_assert(is_same_v);
+
+  template
+  struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}}
+
+  template
+  constexpr bool v1 = false;
+
+  template requires A::type // expected-note{{in instantiation of template class 'variable_templates::A' requested here}}
+   // expected-note@-1{{while substituting template arguments into constraint expression here}}
+  constexpr bool v1 = true;
+
+  template requires T{} // 

[PATCH] D41217: [Concepts] Concept Specialization Expressions

2019-06-14 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 204784.
saar.raz added a comment.

Delay support for mangling to later patch (where CSEs are formed instead of 
UnresolvedLookupExprs with dependent args)


Repository:
  rC Clang

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

https://reviews.llvm.org/D41217

Files:
  include/clang/AST/ExprCXX.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/StmtNodes.td
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/Expr.cpp
  lib/AST/ExprCXX.cpp
  lib/AST/ExprClassification.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Frontend/FrontendActions.cpp
  lib/Parse/ParseExpr.cpp
  lib/Sema/CMakeLists.txt
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaExceptionSpec.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  test/Parser/cxx2a-concept-declaration.cpp
  tools/libclang/CXCursor.cpp

Index: tools/libclang/CXCursor.cpp
===
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -256,6 +256,7 @@
   case Stmt::BinaryConditionalOperatorClass:
   case Stmt::TypeTraitExprClass:
   case Stmt::CoawaitExprClass:
+  case Stmt::ConceptSpecializationExprClass:
   case Stmt::DependentCoawaitExprClass:
   case Stmt::CoyieldExprClass:
   case Stmt::CXXBindTemporaryExprClass:
Index: test/Parser/cxx2a-concept-declaration.cpp
===
--- test/Parser/cxx2a-concept-declaration.cpp
+++ test/Parser/cxx2a-concept-declaration.cpp
@@ -14,8 +14,6 @@
 // expected-error@-2{{template template parameter requires 'class' after the parameter list}}
 // expected-error@-3{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}}
 
-template concept C2 = 0.f; // expected-error {{constraint expression must be of type 'bool' but is of type 'float'}}
-
 struct S1 {
   template concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}}
 };
@@ -26,15 +24,15 @@
 
 template
 template
-concept C4 = true; // expected-error {{extraneous template parameter list in concept definition}}
+concept C2 = true; // expected-error {{extraneous template parameter list in concept definition}}
 
-template concept C5 = true; // expected-note {{previous}} expected-note {{previous}}
-int C5; // expected-error {{redefinition}}
-struct C5 {}; // expected-error {{redefinition}}
+template concept C3 = true; // expected-note {{previous}} expected-note {{previous}}
+int C3; // expected-error {{redefinition}}
+struct C3 {}; // expected-error {{redefinition}}
 
-struct C6 {}; // expected-note{{previous definition is here}}
-template concept C6 = true;
-// expected-error@-1{{redefinition of 'C6' as different kind of symbol}}
+struct C4 {}; // expected-note{{previous definition is here}}
+template concept C4 = true;
+// expected-error@-1{{redefinition of 'C4' as different kind of symbol}}
 
 // TODO: Add test to prevent explicit specialization, partial specialization
 // and explicit instantiation of concepts.
@@ -43,31 +41,55 @@
 struct integral_constant { static constexpr T value = v; };
 
 namespace N {
-  template concept C7 = true;
+  template concept C5 = true;
 }
-using N::C7;
+using N::C5;
 
-template  concept C8 = integral_constant::value;
+template  concept C6 = integral_constant::value;
 // expected-error@-1{{use of undeclared identifier 'wor'; did you mean 'word'?}}
 // expected-note@-2{{'word' declared here}}
 
-template concept bool C9 = true;
+template concept bool C7 = true;
 // expected-warning@-1{{ISO C++2a does not permit the 'bool' keyword after 'concept'}}
 
-template<> concept C10 = false;
+template<> concept C8 = false;
 // expected-error@-1{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}}
 
-template<> concept C9 = false;
+template<> concept C7 = false;
 // expected-error@-1{{name defined in concept definition must be an identifier}}
 
-template concept N::C11 = false;
+template concept N::C9 = false;
 // expected-error@-1{{name defined in concept definition must be an identifier}}
 
 class A { };
 // expected-note@-1{{'A' declared here}}
 
-template concept A::C12 = false;
+template concept A::C10 = false;
 // expected-error@-1{{expected namespace name}}
 
 template concept operator int = false;
 // expected-error@-1{{name defined in concept definition must be an identifier}}
+
+template concept C11 = 2; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template 

[PATCH] D41569: [Concepts] Constraint enforcement and diagnostics

2019-06-14 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 204782.
saar.raz added a comment.

Add support for CSE mangling


Repository:
  rC Clang

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

https://reviews.llvm.org/D41569

Files:
  include/clang/AST/ExprCXX.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  include/clang/Sema/SemaConcept.h
  include/clang/Sema/TemplateDeduction.h
  lib/AST/ExprCXX.cpp
  lib/AST/ItaniumMangle.cpp
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
  test/CodeGenCXX/mangle-concept.cpp

Index: test/CodeGenCXX/mangle-concept.cpp
===
--- /dev/null
+++ test/CodeGenCXX/mangle-concept.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -verify -Wno-return-type -Wno-main -std=c++2a -fconcepts-ts -emit-llvm -triple %itanium_abi_triple -o - %s | FileCheck %s
+// expected-no-diagnostics
+
+namespace test1 {
+template  struct S {};
+template  concept C = true;
+template  S> f0() { return S>{}; }
+template S> f0<>();
+// CHECK: void @_ZN5test12f0IiEENS_1SIXL_ZNS_1CIT_EEv()
+}
+
+template  struct S {};
+template  concept C = true;
+template  S> f0() { return S>{}; }
+template S> f0<>();
+// CHECK: void @_Z2f0IiE1SIXL_Z1CIT_v()
\ No newline at end of file
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+namespace class_templates
+{
+  template requires sizeof(T) >= 4 // expected-note {{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}}
+  struct is_same { static constexpr bool value = false; };
+
+  template requires sizeof(T*) >= 4 && sizeof(T) >= 4
+  struct is_same { static constexpr bool value = true; };
+
+  static_assert(!is_same::value);
+  static_assert(!is_same::value);
+  static_assert(is_same::value);
+  static_assert(is_same::value); // expected-error {{constraints not satisfied for class template 'is_same' [with T = char, U = char]}}
+
+  template
+  struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}}
+
+  template
+  struct B {};
+
+  template requires A::type // expected-note{{in instantiation of template class 'class_templates::A' requested here}}
+   // expected-note@-1{{while substituting template arguments into constraint expression here}}
+  struct B {};
+
+  template requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}}
+  struct B {};
+
+  static_assert((B{}, true)); // expected-note{{while checking constraint satisfaction for class template partial specialization 'B' required here}}
+  // expected-note@-1{{while checking constraint satisfaction for class template partial specialization 'B' required here}}
+  // expected-note@-2{{during template argument deduction for class template partial specialization 'B' [with T = int *]}}
+  // expected-note@-3{{during template argument deduction for class template partial specialization 'B' [with T = int]}}
+  // expected-note@-4 2{{in instantiation of template class 'class_templates::B' requested here}}
+}
+
+namespace variable_templates
+{
+  template requires sizeof(T) >= 4
+  constexpr bool is_same_v = false;
+
+  template requires sizeof(T*) >= 4 && sizeof(T) >= 4
+  constexpr bool is_same_v = true;
+
+  static_assert(!is_same_v);
+  static_assert(!is_same_v);
+  static_assert(is_same_v);
+
+  template
+  struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}}
+
+  template
+  constexpr bool v1 = false;
+
+  template requires A::type // expected-note{{in instantiation of template class 'variable_templates::A' requested here}}
+   // expected-note@-1{{while substituting template arguments into constraint expression here}}
+  constexpr bool v1 = true;
+
+  template requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}}
+  constexpr bool v1 = true;
+
+  static_assert(v1); // expected-note{{while checking constraint satisfaction for variable template partial specialization 

[PATCH] D41217: [Concepts] Concept Specialization Expressions

2019-06-14 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 204764.
saar.raz added a comment.

Add support for CSE mangling


Repository:
  rC Clang

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

https://reviews.llvm.org/D41217

Files:
  include/clang/AST/ExprCXX.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/StmtNodes.td
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/Expr.cpp
  lib/AST/ExprCXX.cpp
  lib/AST/ExprClassification.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Frontend/FrontendActions.cpp
  lib/Parse/ParseExpr.cpp
  lib/Sema/CMakeLists.txt
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaExceptionSpec.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  test/CodeGenCXX/mangle-concept.cpp
  test/Parser/cxx2a-concept-declaration.cpp
  tools/libclang/CXCursor.cpp

Index: tools/libclang/CXCursor.cpp
===
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -256,6 +256,7 @@
   case Stmt::BinaryConditionalOperatorClass:
   case Stmt::TypeTraitExprClass:
   case Stmt::CoawaitExprClass:
+  case Stmt::ConceptSpecializationExprClass:
   case Stmt::DependentCoawaitExprClass:
   case Stmt::CoyieldExprClass:
   case Stmt::CXXBindTemporaryExprClass:
Index: test/Parser/cxx2a-concept-declaration.cpp
===
--- test/Parser/cxx2a-concept-declaration.cpp
+++ test/Parser/cxx2a-concept-declaration.cpp
@@ -14,8 +14,6 @@
 // expected-error@-2{{template template parameter requires 'class' after the parameter list}}
 // expected-error@-3{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}}
 
-template concept C2 = 0.f; // expected-error {{constraint expression must be of type 'bool' but is of type 'float'}}
-
 struct S1 {
   template concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}}
 };
@@ -26,15 +24,15 @@
 
 template
 template
-concept C4 = true; // expected-error {{extraneous template parameter list in concept definition}}
+concept C2 = true; // expected-error {{extraneous template parameter list in concept definition}}
 
-template concept C5 = true; // expected-note {{previous}} expected-note {{previous}}
-int C5; // expected-error {{redefinition}}
-struct C5 {}; // expected-error {{redefinition}}
+template concept C3 = true; // expected-note {{previous}} expected-note {{previous}}
+int C3; // expected-error {{redefinition}}
+struct C3 {}; // expected-error {{redefinition}}
 
-struct C6 {}; // expected-note{{previous definition is here}}
-template concept C6 = true;
-// expected-error@-1{{redefinition of 'C6' as different kind of symbol}}
+struct C4 {}; // expected-note{{previous definition is here}}
+template concept C4 = true;
+// expected-error@-1{{redefinition of 'C4' as different kind of symbol}}
 
 // TODO: Add test to prevent explicit specialization, partial specialization
 // and explicit instantiation of concepts.
@@ -43,31 +41,55 @@
 struct integral_constant { static constexpr T value = v; };
 
 namespace N {
-  template concept C7 = true;
+  template concept C5 = true;
 }
-using N::C7;
+using N::C5;
 
-template  concept C8 = integral_constant::value;
+template  concept C6 = integral_constant::value;
 // expected-error@-1{{use of undeclared identifier 'wor'; did you mean 'word'?}}
 // expected-note@-2{{'word' declared here}}
 
-template concept bool C9 = true;
+template concept bool C7 = true;
 // expected-warning@-1{{ISO C++2a does not permit the 'bool' keyword after 'concept'}}
 
-template<> concept C10 = false;
+template<> concept C8 = false;
 // expected-error@-1{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed}}
 
-template<> concept C9 = false;
+template<> concept C7 = false;
 // expected-error@-1{{name defined in concept definition must be an identifier}}
 
-template concept N::C11 = false;
+template concept N::C9 = false;
 // expected-error@-1{{name defined in concept definition must be an identifier}}
 
 class A { };
 // expected-note@-1{{'A' declared here}}
 
-template concept A::C12 = false;
+template concept A::C10 = false;
 // expected-error@-1{{expected namespace name}}
 
 template concept operator int = false;
 // expected-error@-1{{name defined in concept definition must be an identifier}}
+
+template concept C11 = 2; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template concept C12 = 2 && x; // expected-error {{atomic 

[PATCH] D40381: Parse concept definition

2019-05-13 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added a comment.

@rsmith?


Repository:
  rC Clang

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

https://reviews.llvm.org/D40381



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


[PATCH] D40381: Parse concept definition

2019-05-05 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added a comment.

Awesome! I do not have commit permissions though, so can you do the actual 
commit?


Repository:
  rC Clang

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

https://reviews.llvm.org/D40381



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


[PATCH] D40381: Parse concept definition

2019-05-05 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 198200.
saar.raz marked 4 inline comments as done.
saar.raz added a comment.

- Address final CR comments by rsmith


Repository:
  rC Clang

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

https://reviews.llvm.org/D40381

Files:
  include/clang/AST/ASTNodeTraverser.h
  include/clang/AST/DeclTemplate.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/AST/TextNodeDumper.h
  include/clang/Basic/DeclNodes.td
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/TemplateKinds.h
  include/clang/Parse/Parser.h
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTStructuralEquivalence.cpp
  lib/AST/DeclBase.cpp
  lib/AST/DeclPrinter.cpp
  lib/AST/DeclTemplate.cpp
  lib/AST/TextNodeDumper.cpp
  lib/CodeGen/CGDecl.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/Index/IndexDecl.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaLookup.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  test/Parser/cxx-concept-declaration.cpp
  test/Parser/cxx-concepts-ambig-constraint-expr.cpp
  test/Parser/cxx-concepts-requires-clause.cpp
  test/Parser/cxx2a-concept-declaration.cpp
  test/Parser/cxx2a-concepts-ambig-constraint-expr.cpp
  test/Parser/cxx2a-concepts-requires-clause.cpp
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -6252,6 +6252,7 @@
   case Decl::PragmaComment:
   case Decl::PragmaDetectMismatch:
   case Decl::UsingPack:
+  case Decl::Concept:
 return C;
 
   // Declaration kinds that don't make any sense here, but are
Index: test/Parser/cxx-concepts-requires-clause.cpp
===
--- /dev/null
+++ test/Parser/cxx-concepts-requires-clause.cpp
@@ -1,82 +0,0 @@
-// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ %s -verify
-// expected-no-diagnostics
-
-// Test parsing of the optional requires-clause in a template-declaration.
-
-template  requires true
-void foo() { }
-
-
-template  requires !0
-struct A {
-  void foo();
-  struct AA;
-  enum E : int;
-  static int x;
-
-  template  requires true
-  void Mfoo();
-
-  template  requires true
-  struct M;
-
-  template  requires true
-  static int Mx;
-
-  template  requires true
-  using MQ = M;
-};
-
-template  requires !0
-void A::foo() { }
-
-template  requires !0
-struct A::AA { };
-
-template  requires !0
-enum A::E : int { E0 };
-
-template  requires !0
-int A::x = 0;
-
-template  requires !0
-template  requires true
-void A::Mfoo() { }
-
-template  requires !0
-template  requires true
-struct A::M { };
-
-template  requires !0
-template  requires true
-int A::Mx = 0;
-
-
-template  requires true
-int x = 0;
-
-template  requires true
-using Q = A;
-
-struct C {
-  template  requires true
-  void Mfoo();
-
-  template  requires true
-  struct M;
-
-  template  requires true
-  static int Mx;
-
-  template  requires true
-  using MQ = M;
-};
-
-template  requires true
-void C::Mfoo() { }
-
-template  requires true
-struct C::M { };
-
-template  requires true
-int C::Mx = 0;
Index: test/Parser/cxx-concepts-ambig-constraint-expr.cpp
===
--- /dev/null
+++ test/Parser/cxx-concepts-ambig-constraint-expr.cpp
@@ -1,29 +0,0 @@
-// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ %s -verify
-
-// Test parsing of constraint-expressions in cases where the grammar is
-// ambiguous with the expectation that the longest token sequence which matches
-// the syntax is consumed without backtracking.
-
-// type-specifier-seq in conversion-type-id
-template  requires (bool)::operator short
-unsigned int foo(); // expected-error {{C++ requires a type specifier for all declarations}}
-
-// type-specifier-seq in new-type-id
-template  requires (bool)sizeof new (T::f()) short
-unsigned int bar(); // expected-error {{C++ requires a type specifier for all declarations}}
-
-template requires (bool)sizeof new (T::f()) unsigned // expected-error {{'struct' cannot be signed or unsigned}}
-struct X { }; // expected-error {{'X' cannot be defined in a type specifier}}
-
-// C-style cast
-// of function call on function-style cast
-template  requires (bool(T()))
-T (*fp)(); // expected-error {{use of undeclared identifier 'fp'}}
-
-// function-style cast
-// as the callee in a function call
-struct A {
-  static int t;
-  template  requires bool(T())
-  (A(T ())) { } // expected-error {{called object type 'bool' is not a function or function pointer}}
-};
Index: test/Parser/cxx2a-concept-declaration.cpp

[PATCH] D40381: Parse concept definition

2019-05-04 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added a comment.

@rsmith are we done with CR on this?


Repository:
  rC Clang

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

https://reviews.llvm.org/D40381



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


[PATCH] D41910: [Concepts] Constrained partial specializations and function overloads.

2019-04-22 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 196107.
saar.raz added a comment.

Renamed PartSpec to PartSpec2 (CR)


Repository:
  rC Clang

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

https://reviews.llvm.org/D41910

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/DeclTemplate.cpp
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.normal/p1.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp

Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 4
+bool a = false; // expected-note{{template is declared here}}
+
+template requires sizeof(T) >= 4 && sizeof(T) <= 10
+bool a = true; // expected-error{{variable template partial specialization is not more specialized than the primary template}}
+
+template
+concept C1 = sizeof(T) >= 4;
+
+template requires C1
+bool b = false;
+
+template requires C1 && sizeof(T) <= 10
+bool b = true;
+
+template
+concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
+
+template
+bool c = false;
+
+template requires C1
+bool c = true;
+
+template
+bool d = false;
+
+template
+bool d = true; // expected-error{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+
+template requires C1
+bool e = false;
+
+template
+bool e = true; // expected-error{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+
+template
+constexpr int f = 1;
+
+template requires C1 && C2
+constexpr int f = 2;
+
+template requires C1 || C2
+constexpr int f = 3;
+
+static_assert(f == 2);
+static_assert(f == 3);
+static_assert(f == 1);
+
+
+
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 4
+bool a() { return false; } // expected-note {{candidate function [with T = unsigned int]}}
+
+template requires sizeof(T) >= 4 && sizeof(T) <= 10
+bool a() { return true; } // expected-note {{candidate function [with T = unsigned int]}}
+
+bool av = a(); // expected-error {{call to 'a' is ambiguous}}
+
+template
+concept C1 = sizeof(T) >= 4;
+
+template requires C1
+constexpr bool b() { return false; }
+
+template requires C1 && sizeof(T) <= 10
+constexpr bool b() { return true; }
+
+static_assert(b());
+static_assert(!b());
+
+template
+concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
+
+template
+bool c() { return false; }
+
+template requires C1
+bool c() { return true; }
+
+template requires C1
+constexpr bool d() { return false; }
+
+template
+constexpr bool d() { return true; }
+
+static_assert(!d());
+
+template
+constexpr int e() { return 1; }
+
+template requires C1 && C2
+constexpr int e() { return 2; }
+
+template requires C1 || C2
+constexpr int e() { return 3; }
+
+static_assert(e() == 2);
+static_assert(e() == 3);
+static_assert(e() == 1);
+
+template
+concept BiggerThan = sizeof(T) > sizeof(U);
+
+template
+concept BiggerThanInt = BiggerThan;
+
+template requires BiggerThan
+void f() { }
+// expected-note@-1 {{candidate function [with T = long long, U = int]}}
+
+template requires BiggerThanInt
+void f() { }
+// expected-note@-1 {{candidate function [with T = long long, U = int]}}
+
+static_assert(sizeof(f()));
+// expected-error@-1 {{call to 'f' is ambiguous}}
+
+template
+concept C3 = true;
+
+template
+concept C4 = true && C3;
+
+template requires C3
+int g() { }
+
+template requires C4
+int g() { }
+
+static_assert(sizeof(g()));
\ No newline at end of file
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ 

[PATCH] D41910: [Concepts] Constrained partial specializations and function overloads.

2019-04-22 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 196106.
saar.raz added a comment.

- Fixed importing of ACs when importing partial specs.
- Adjust to getAssociatedConstraints interface change


Repository:
  rC Clang

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

https://reviews.llvm.org/D41910

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/DeclTemplate.cpp
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.normal/p1.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp

Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 4
+bool a = false; // expected-note{{template is declared here}}
+
+template requires sizeof(T) >= 4 && sizeof(T) <= 10
+bool a = true; // expected-error{{variable template partial specialization is not more specialized than the primary template}}
+
+template
+concept C1 = sizeof(T) >= 4;
+
+template requires C1
+bool b = false;
+
+template requires C1 && sizeof(T) <= 10
+bool b = true;
+
+template
+concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
+
+template
+bool c = false;
+
+template requires C1
+bool c = true;
+
+template
+bool d = false;
+
+template
+bool d = true; // expected-error{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+
+template requires C1
+bool e = false;
+
+template
+bool e = true; // expected-error{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+
+template
+constexpr int f = 1;
+
+template requires C1 && C2
+constexpr int f = 2;
+
+template requires C1 || C2
+constexpr int f = 3;
+
+static_assert(f == 2);
+static_assert(f == 3);
+static_assert(f == 1);
+
+
+
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 4
+bool a() { return false; } // expected-note {{candidate function [with T = unsigned int]}}
+
+template requires sizeof(T) >= 4 && sizeof(T) <= 10
+bool a() { return true; } // expected-note {{candidate function [with T = unsigned int]}}
+
+bool av = a(); // expected-error {{call to 'a' is ambiguous}}
+
+template
+concept C1 = sizeof(T) >= 4;
+
+template requires C1
+constexpr bool b() { return false; }
+
+template requires C1 && sizeof(T) <= 10
+constexpr bool b() { return true; }
+
+static_assert(b());
+static_assert(!b());
+
+template
+concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
+
+template
+bool c() { return false; }
+
+template requires C1
+bool c() { return true; }
+
+template requires C1
+constexpr bool d() { return false; }
+
+template
+constexpr bool d() { return true; }
+
+static_assert(!d());
+
+template
+constexpr int e() { return 1; }
+
+template requires C1 && C2
+constexpr int e() { return 2; }
+
+template requires C1 || C2
+constexpr int e() { return 3; }
+
+static_assert(e() == 2);
+static_assert(e() == 3);
+static_assert(e() == 1);
+
+template
+concept BiggerThan = sizeof(T) > sizeof(U);
+
+template
+concept BiggerThanInt = BiggerThan;
+
+template requires BiggerThan
+void f() { }
+// expected-note@-1 {{candidate function [with T = long long, U = int]}}
+
+template requires BiggerThanInt
+void f() { }
+// expected-note@-1 {{candidate function [with T = long long, U = int]}}
+
+static_assert(sizeof(f()));
+// expected-error@-1 {{call to 'f' is ambiguous}}
+
+template
+concept C3 = true;
+
+template
+concept C4 = true && C3;
+
+template requires C3
+int g() { }
+
+template requires C4
+int g() { }
+
+static_assert(sizeof(g()));
\ No newline at end of file
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
===
--- /dev/null
+++ 

[PATCH] D41569: [Concepts] Constraint enforcement and diagnostics

2019-04-22 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 196091.
saar.raz added a comment.

Adjusted to changes in getAssociatedConstraints interface


Repository:
  rC Clang

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

https://reviews.llvm.org/D41569

Files:
  include/clang/AST/ExprCXX.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  include/clang/Sema/SemaConcept.h
  include/clang/Sema/TemplateDeduction.h
  lib/AST/ExprCXX.cpp
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp

Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+namespace class_templates
+{
+  template requires sizeof(T) >= 4 // expected-note {{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}}
+  struct is_same { static constexpr bool value = false; };
+
+  template requires sizeof(T*) >= 4 && sizeof(T) >= 4
+  struct is_same { static constexpr bool value = true; };
+
+  static_assert(!is_same::value);
+  static_assert(!is_same::value);
+  static_assert(is_same::value);
+  static_assert(is_same::value); // expected-error {{constraints not satisfied for class template 'is_same' [with T = char, U = char]}}
+
+  template
+  struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}}
+
+  template
+  struct B {};
+
+  template requires A::type // expected-note{{in instantiation of template class 'class_templates::A' requested here}}
+   // expected-note@-1{{while substituting template arguments into constraint expression here}}
+  struct B {};
+
+  template requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}}
+  struct B {};
+
+  static_assert((B{}, true)); // expected-note{{while checking constraint satisfaction for class template partial specialization 'B' required here}}
+  // expected-note@-1{{while checking constraint satisfaction for class template partial specialization 'B' required here}}
+  // expected-note@-2{{during template argument deduction for class template partial specialization 'B' [with T = int *]}}
+  // expected-note@-3{{during template argument deduction for class template partial specialization 'B' [with T = int]}}
+  // expected-note@-4 2{{in instantiation of template class 'class_templates::B' requested here}}
+}
+
+namespace variable_templates
+{
+  template requires sizeof(T) >= 4
+  constexpr bool is_same_v = false;
+
+  template requires sizeof(T*) >= 4 && sizeof(T) >= 4
+  constexpr bool is_same_v = true;
+
+  static_assert(!is_same_v);
+  static_assert(!is_same_v);
+  static_assert(is_same_v);
+
+  template
+  struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}}
+
+  template
+  constexpr bool v1 = false;
+
+  template requires A::type // expected-note{{in instantiation of template class 'variable_templates::A' requested here}}
+   // expected-note@-1{{while substituting template arguments into constraint expression here}}
+  constexpr bool v1 = true;
+
+  template requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}}
+  constexpr bool v1 = true;
+
+  static_assert(v1); // expected-note{{while checking constraint satisfaction for variable template partial specialization 'v1' required here}}
+  // expected-note@-1{{while checking constraint satisfaction for variable template partial specialization 'v1' required here}}
+  // expected-note@-2{{during template argument deduction for variable template partial specialization 'v1' [with T = int *]}}
+  // expected-note@-3{{during template argument deduction for variable template partial specialization 'v1' [with T = int]}}
+  // expected-error@-4{{static_assert failed due to requirement 'v1'}}
+
+}
\ No newline at end of file
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
===
--- /dev/null
+++ 

[PATCH] D41284: [Concepts] Associated constraints infrastructure.

2019-04-22 Thread Saar Raz via Phabricator via cfe-commits
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;
 };
 

[PATCH] D40381: Parse concept definition

2019-04-21 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 196009.
saar.raz added a comment.
Herald added a reviewer: martong.

Address CR comments by rsmith


Repository:
  rC Clang

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

https://reviews.llvm.org/D40381

Files:
  include/clang/AST/ASTNodeTraverser.h
  include/clang/AST/DeclTemplate.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/AST/TextNodeDumper.h
  include/clang/Basic/DeclNodes.td
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/TemplateKinds.h
  include/clang/Parse/Parser.h
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTStructuralEquivalence.cpp
  lib/AST/DeclBase.cpp
  lib/AST/DeclPrinter.cpp
  lib/AST/DeclTemplate.cpp
  lib/AST/TextNodeDumper.cpp
  lib/CodeGen/CGDecl.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/Index/IndexDecl.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaLookup.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  test/Parser/cxx-concept-declaration.cpp
  test/Parser/cxx-concepts-ambig-constraint-expr.cpp
  test/Parser/cxx-concepts-requires-clause.cpp
  test/Parser/cxx2a-concept-declaration.cpp
  test/Parser/cxx2a-concepts-ambig-constraint-expr.cpp
  test/Parser/cxx2a-concepts-requires-clause.cpp
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -6252,6 +6252,7 @@
   case Decl::PragmaComment:
   case Decl::PragmaDetectMismatch:
   case Decl::UsingPack:
+  case Decl::Concept:
 return C;
 
   // Declaration kinds that don't make any sense here, but are
Index: test/Parser/cxx-concepts-requires-clause.cpp
===
--- /dev/null
+++ test/Parser/cxx-concepts-requires-clause.cpp
@@ -1,82 +0,0 @@
-// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ %s -verify
-// expected-no-diagnostics
-
-// Test parsing of the optional requires-clause in a template-declaration.
-
-template  requires true
-void foo() { }
-
-
-template  requires !0
-struct A {
-  void foo();
-  struct AA;
-  enum E : int;
-  static int x;
-
-  template  requires true
-  void Mfoo();
-
-  template  requires true
-  struct M;
-
-  template  requires true
-  static int Mx;
-
-  template  requires true
-  using MQ = M;
-};
-
-template  requires !0
-void A::foo() { }
-
-template  requires !0
-struct A::AA { };
-
-template  requires !0
-enum A::E : int { E0 };
-
-template  requires !0
-int A::x = 0;
-
-template  requires !0
-template  requires true
-void A::Mfoo() { }
-
-template  requires !0
-template  requires true
-struct A::M { };
-
-template  requires !0
-template  requires true
-int A::Mx = 0;
-
-
-template  requires true
-int x = 0;
-
-template  requires true
-using Q = A;
-
-struct C {
-  template  requires true
-  void Mfoo();
-
-  template  requires true
-  struct M;
-
-  template  requires true
-  static int Mx;
-
-  template  requires true
-  using MQ = M;
-};
-
-template  requires true
-void C::Mfoo() { }
-
-template  requires true
-struct C::M { };
-
-template  requires true
-int C::Mx = 0;
Index: test/Parser/cxx-concepts-ambig-constraint-expr.cpp
===
--- /dev/null
+++ test/Parser/cxx-concepts-ambig-constraint-expr.cpp
@@ -1,29 +0,0 @@
-// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ %s -verify
-
-// Test parsing of constraint-expressions in cases where the grammar is
-// ambiguous with the expectation that the longest token sequence which matches
-// the syntax is consumed without backtracking.
-
-// type-specifier-seq in conversion-type-id
-template  requires (bool)::operator short
-unsigned int foo(); // expected-error {{C++ requires a type specifier for all declarations}}
-
-// type-specifier-seq in new-type-id
-template  requires (bool)sizeof new (T::f()) short
-unsigned int bar(); // expected-error {{C++ requires a type specifier for all declarations}}
-
-template requires (bool)sizeof new (T::f()) unsigned // expected-error {{'struct' cannot be signed or unsigned}}
-struct X { }; // expected-error {{'X' cannot be defined in a type specifier}}
-
-// C-style cast
-// of function call on function-style cast
-template  requires (bool(T()))
-T (*fp)(); // expected-error {{use of undeclared identifier 'fp'}}
-
-// function-style cast
-// as the callee in a function call
-struct A {
-  static int t;
-  template  requires bool(T())
-  (A(T ())) { } // expected-error {{called object type 'bool' is not a function or function pointer}}
-};
Index: test/Parser/cxx2a-concept-declaration.cpp

[PATCH] D41910: [Concepts] Constrained partial specializations and function overloads.

2019-04-13 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 195010.
saar.raz added a comment.
Herald added a reviewer: martong.
Herald added a reviewer: shafik.

Fixed bug in normalization substitution into CSEs
Rebase onto trunk


Repository:
  rC Clang

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

https://reviews.llvm.org/D41910

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/AST/ASTImporter.cpp
  lib/AST/DeclTemplate.cpp
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.normal/p1.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp

Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 4
+bool a = false; // expected-note{{template is declared here}}
+
+template requires sizeof(T) >= 4 && sizeof(T) <= 10
+bool a = true; // expected-error{{variable template partial specialization is not more specialized than the primary template}}
+
+template
+concept C1 = sizeof(T) >= 4;
+
+template requires C1
+bool b = false;
+
+template requires C1 && sizeof(T) <= 10
+bool b = true;
+
+template
+concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
+
+template
+bool c = false;
+
+template requires C1
+bool c = true;
+
+template
+bool d = false;
+
+template
+bool d = true; // expected-error{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+
+template requires C1
+bool e = false;
+
+template
+bool e = true; // expected-error{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+
+template
+constexpr int f = 1;
+
+template requires C1 && C2
+constexpr int f = 2;
+
+template requires C1 || C2
+constexpr int f = 3;
+
+static_assert(f == 2);
+static_assert(f == 3);
+static_assert(f == 1);
+
+
+
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 4
+bool a() { return false; } // expected-note {{candidate function [with T = unsigned int]}}
+
+template requires sizeof(T) >= 4 && sizeof(T) <= 10
+bool a() { return true; } // expected-note {{candidate function [with T = unsigned int]}}
+
+bool av = a(); // expected-error {{call to 'a' is ambiguous}}
+
+template
+concept C1 = sizeof(T) >= 4;
+
+template requires C1
+constexpr bool b() { return false; }
+
+template requires C1 && sizeof(T) <= 10
+constexpr bool b() { return true; }
+
+static_assert(b());
+static_assert(!b());
+
+template
+concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
+
+template
+bool c() { return false; }
+
+template requires C1
+bool c() { return true; }
+
+template requires C1
+constexpr bool d() { return false; }
+
+template
+constexpr bool d() { return true; }
+
+static_assert(!d());
+
+template
+constexpr int e() { return 1; }
+
+template requires C1 && C2
+constexpr int e() { return 2; }
+
+template requires C1 || C2
+constexpr int e() { return 3; }
+
+static_assert(e() == 2);
+static_assert(e() == 3);
+static_assert(e() == 1);
+
+template
+concept BiggerThan = sizeof(T) > sizeof(U);
+
+template
+concept BiggerThanInt = BiggerThan;
+
+template requires BiggerThan
+void f() { }
+// expected-note@-1 {{candidate function [with T = long long, U = int]}}
+
+template requires BiggerThanInt
+void f() { }
+// expected-note@-1 {{candidate function [with T = long long, U = int]}}
+
+static_assert(sizeof(f()));
+// expected-error@-1 {{call to 'f' is ambiguous}}
+
+template
+concept C3 = true;
+
+template
+concept C4 = true && C3;
+
+template requires C3
+int g() { }
+
+template requires C4
+int g() { }
+
+static_assert(sizeof(g()));
\ No newline at end of file
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
===
--- 

[PATCH] D41569: [Concepts] Constraint enforcement and diagnostics

2019-04-13 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 195009.
saar.raz added a comment.

Rebase onto trunk


Repository:
  rC Clang

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

https://reviews.llvm.org/D41569

Files:
  include/clang/AST/ExprCXX.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  include/clang/Sema/SemaConcept.h
  include/clang/Sema/TemplateDeduction.h
  lib/AST/ExprCXX.cpp
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp

Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+namespace class_templates
+{
+  template requires sizeof(T) >= 4 // expected-note {{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}}
+  struct is_same { static constexpr bool value = false; };
+
+  template requires sizeof(T*) >= 4 && sizeof(T) >= 4
+  struct is_same { static constexpr bool value = true; };
+
+  static_assert(!is_same::value);
+  static_assert(!is_same::value);
+  static_assert(is_same::value);
+  static_assert(is_same::value); // expected-error {{constraints not satisfied for class template 'is_same' [with T = char, U = char]}}
+
+  template
+  struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}}
+
+  template
+  struct B {};
+
+  template requires A::type // expected-note{{in instantiation of template class 'class_templates::A' requested here}}
+   // expected-note@-1{{while substituting template arguments into constraint expression here}}
+  struct B {};
+
+  template requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}}
+  struct B {};
+
+  static_assert((B{}, true)); // expected-note{{while checking constraint satisfaction for class template partial specialization 'B' required here}}
+  // expected-note@-1{{while checking constraint satisfaction for class template partial specialization 'B' required here}}
+  // expected-note@-2{{during template argument deduction for class template partial specialization 'B' [with T = int *]}}
+  // expected-note@-3{{during template argument deduction for class template partial specialization 'B' [with T = int]}}
+  // expected-note@-4 2{{in instantiation of template class 'class_templates::B' requested here}}
+}
+
+namespace variable_templates
+{
+  template requires sizeof(T) >= 4
+  constexpr bool is_same_v = false;
+
+  template requires sizeof(T*) >= 4 && sizeof(T) >= 4
+  constexpr bool is_same_v = true;
+
+  static_assert(!is_same_v);
+  static_assert(!is_same_v);
+  static_assert(is_same_v);
+
+  template
+  struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}}
+
+  template
+  constexpr bool v1 = false;
+
+  template requires A::type // expected-note{{in instantiation of template class 'variable_templates::A' requested here}}
+   // expected-note@-1{{while substituting template arguments into constraint expression here}}
+  constexpr bool v1 = true;
+
+  template requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}}
+  constexpr bool v1 = true;
+
+  static_assert(v1); // expected-note{{while checking constraint satisfaction for variable template partial specialization 'v1' required here}}
+  // expected-note@-1{{while checking constraint satisfaction for variable template partial specialization 'v1' required here}}
+  // expected-note@-2{{during template argument deduction for variable template partial specialization 'v1' [with T = int *]}}
+  // expected-note@-3{{during template argument deduction for variable template partial specialization 'v1' [with T = int]}}
+  // expected-error@-4{{static_assert failed due to requirement 'v1'}}
+
+}
\ No newline at end of file
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 

[PATCH] D41284: [Concepts] Associated constraints infrastructure.

2019-04-12 Thread Saar Raz via Phabricator via cfe-commits
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] D41217: [Concepts] Concept Specialization Expressions

2019-04-12 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 194979.
saar.raz added a comment.

Fix wrong patch uploaded


Repository:
  rC Clang

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

https://reviews.llvm.org/D41217

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/StmtNodes.td
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/Expr.cpp
  lib/AST/ExprCXX.cpp
  lib/AST/ExprClassification.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Frontend/FrontendActions.cpp
  lib/Parse/ParseExpr.cpp
  lib/Sema/CMakeLists.txt
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaExceptionSpec.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  test/Parser/cxx2a-concept-declaration.cpp
  tools/libclang/CXCursor.cpp

Index: tools/libclang/CXCursor.cpp
===
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -256,6 +256,7 @@
   case Stmt::BinaryConditionalOperatorClass:
   case Stmt::TypeTraitExprClass:
   case Stmt::CoawaitExprClass:
+  case Stmt::ConceptSpecializationExprClass:
   case Stmt::DependentCoawaitExprClass:
   case Stmt::CoyieldExprClass:
   case Stmt::CXXBindTemporaryExprClass:
Index: test/Parser/cxx2a-concept-declaration.cpp
===
--- test/Parser/cxx2a-concept-declaration.cpp
+++ test/Parser/cxx2a-concept-declaration.cpp
@@ -14,8 +14,6 @@
 // expected-error@-2{{template template parameter requires 'class' after the parameter list}}
 // expected-error@-3{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed, did you attempt this?}}
 
-template concept C2 = 0.f; // expected-error {{constraint expression must be of type 'bool' but is of type 'float'}}
-
 struct S1 {
   template concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}}
 };
@@ -26,15 +24,15 @@
 
 template
 template
-concept C4 = true; // expected-error {{extraneous template parameter list in concept definition}}
+concept C2 = true; // expected-error {{extraneous template parameter list in concept definition}}
 
-template concept C5 = true; // expected-note {{previous}} expected-note {{previous}}
-int C5; // expected-error {{redefinition}}
-struct C5 {}; // expected-error {{redefinition}}
+template concept C3 = true; // expected-note {{previous}} expected-note {{previous}}
+int C3; // expected-error {{redefinition}}
+struct C3 {}; // expected-error {{redefinition}}
 
-struct C6 {}; // expected-note{{previous definition is here}}
-template concept C6 = true;
-// expected-error@-1{{redefinition of 'C6' as different kind of symbol}}
+struct C4 {}; // expected-note{{previous definition is here}}
+template concept C4 = true;
+// expected-error@-1{{redefinition of 'C4' as different kind of symbol}}
 
 // TODO: Add test to prevent explicit specialization, partial specialization
 // and explicit instantiation of concepts.
@@ -43,31 +41,55 @@
 struct integral_constant { static constexpr T value = v; };
 
 namespace N {
-  template concept C7 = true;
+  template concept C5 = true;
 }
-using N::C7;
+using N::C5;
 
-template  concept C8 = integral_constant::value;
+template  concept C6 = integral_constant::value;
 // expected-error@-1{{use of undeclared identifier 'wor'; did you mean 'word'?}}
 // expected-note@-2{{'word' declared here}}
 
-template concept bool C9 = true;
+template concept bool C7 = true;
 // expected-error@-1{{'bool' keyword after 'concept' is no longer valid in C++2a; remove it}}
 
-template<> concept C10 = false;
+template<> concept C8 = false;
 // expected-error@-1{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed, did you attempt this?}}
 
-template<> concept C9 = false;
+template<> concept C7 = false;
 // expected-error@-1{{name defined in concept definition must be an identifier}}
 
-template concept N::C11 = false;
+template concept N::C9 = false;
 // expected-error@-1{{unexpected namespace scope before concept name; concepts must be defined inside their namespace, if any}}
 
 class A { };
 // expected-note@-1{{'A' declared here}}
 
-template concept A::C12 = false;
+template concept A::C10 = false;
 // expected-error@-1{{expected namespace name}}
 
 template concept operator int = false;
 // expected-error@-1{{name defined in concept definition must be an identifier}}
+
+template concept C11 = 2; // expected-error {{atomic constraint must be of 

[PATCH] D41217: [Concepts] Concept Specialization Expressions

2019-04-12 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 194978.
saar.raz added a comment.

Add new CodeSynthesisContexts to switch where they were missing


Repository:
  rC Clang

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

https://reviews.llvm.org/D41217

Files:
  lib/Frontend/FrontendActions.cpp
  test/Parser/cxx2a-concept-declaration.cpp

Index: test/Parser/cxx2a-concept-declaration.cpp
===
--- test/Parser/cxx2a-concept-declaration.cpp
+++ test/Parser/cxx2a-concept-declaration.cpp
@@ -27,12 +27,12 @@
 concept C2 = true; // expected-error {{extraneous template parameter list in concept definition}}
 
 template concept C3 = true; // expected-note {{previous}} expected-note {{previous}}
-int C4; // expected-error {{redefinition}}
-struct C4 {}; // expected-error {{redefinition}}
+int C3; // expected-error {{redefinition}}
+struct C3 {}; // expected-error {{redefinition}}
 
-struct C5 {}; // expected-note{{previous definition is here}}
-template concept C5 = true;
-// expected-error@-1{{redefinition of 'C5' as different kind of symbol}}
+struct C4 {}; // expected-note{{previous definition is here}}
+template concept C4 = true;
+// expected-error@-1{{redefinition of 'C4' as different kind of symbol}}
 
 // TODO: Add test to prevent explicit specialization, partial specialization
 // and explicit instantiation of concepts.
@@ -41,55 +41,55 @@
 struct integral_constant { static constexpr T value = v; };
 
 namespace N {
-  template concept C6 = true;
+  template concept C5 = true;
 }
-using N::C6;
+using N::C5;
 
-template  concept C7 = integral_constant::value;
+template  concept C6 = integral_constant::value;
 // expected-error@-1{{use of undeclared identifier 'wor'; did you mean 'word'?}}
 // expected-note@-2{{'word' declared here}}
 
-template concept bool C8 = true;
+template concept bool C7 = true;
 // expected-error@-1{{'bool' keyword after 'concept' is no longer valid in C++2a; remove it}}
 
-template<> concept C9 = false;
+template<> concept C8 = false;
 // expected-error@-1{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed, did you attempt this?}}
 
-template<> concept C8 = false;
+template<> concept C7 = false;
 // expected-error@-1{{name defined in concept definition must be an identifier}}
 
-template concept N::C12 = false;
+template concept N::C9 = false;
 // expected-error@-1{{unexpected namespace scope before concept name; concepts must be defined inside their namespace, if any}}
 
 class A { };
 // expected-note@-1{{'A' declared here}}
 
-template concept A::C13 = false;
+template concept A::C10 = false;
 // expected-error@-1{{expected namespace name}}
 
 template concept operator int = false;
 // expected-error@-1{{name defined in concept definition must be an identifier}}
 
-template concept C14 = 2; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
-template concept C15 = 2 && x; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
-template concept C16 = x || 2 || x; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
-template concept C17 = 8ull && x || x; // expected-error {{atomic constraint must be of type 'bool' (found 'unsigned long long')}}
-template concept C18 = sizeof(T); // expected-error {{atomic constraint must be of type 'bool' (found 'unsigned long')}}
-template concept C19 = T{};
-static_assert(!C19);
-template concept C20 = (bool&&)true;
-static_assert(C20);
-template concept C21 = (const bool&)true;
-static_assert(C21);
-template concept C22 = (const bool)true;
-static_assert(C22);
-template  concept C23 = integral_constant::value && true;
-static_assert(C23);
-static_assert(!C23);
-template  concept C24 = integral_constant::value;
-static_assert(C24);
-static_assert(!C24);
-
-template  concept C25 = integral_constant::value;
+template concept C11 = 2; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template concept C12 = 2 && x; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template concept C13 = x || 2 || x; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template concept C14 = 8ull && x || x; // expected-error {{atomic constraint must be of type 'bool' (found 'unsigned long long')}}
+template concept C15 = sizeof(T); // expected-error {{atomic constraint must be of type 'bool' (found 'unsigned long')}}
+template concept C16 = T{};
+static_assert(!C16);
+template concept C17 = (bool&&)true;
+static_assert(C17);
+template concept C18 = (const bool&)true;
+static_assert(C18);
+template concept C19 = (const bool)true;
+static_assert(C19);
+template  concept C20 = integral_constant::value && true;
+static_assert(C20);
+static_assert(!C20);
+template  concept C21 = integral_constant::value;
+static_assert(C21);
+static_assert(!C21);
+
+template  concept C22 = 

[PATCH] D41217: [Concepts] Concept Specialization Expressions

2019-04-12 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 194811.
saar.raz marked 3 inline comments as done.
saar.raz added a comment.

Moved from getLocStart, getLocEnd to getBeginLoc, getEndLoc. Rebase onto 
master/trunk.


Repository:
  rC Clang

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

https://reviews.llvm.org/D41217

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/StmtNodes.td
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/Expr.cpp
  lib/AST/ExprCXX.cpp
  lib/AST/ExprClassification.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Parse/ParseExpr.cpp
  lib/Sema/CMakeLists.txt
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaExceptionSpec.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  test/Parser/cxx2a-concept-declaration.cpp
  tools/libclang/CXCursor.cpp

Index: tools/libclang/CXCursor.cpp
===
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -256,6 +256,7 @@
   case Stmt::BinaryConditionalOperatorClass:
   case Stmt::TypeTraitExprClass:
   case Stmt::CoawaitExprClass:
+  case Stmt::ConceptSpecializationExprClass:
   case Stmt::DependentCoawaitExprClass:
   case Stmt::CoyieldExprClass:
   case Stmt::CXXBindTemporaryExprClass:
Index: test/Parser/cxx2a-concept-declaration.cpp
===
--- test/Parser/cxx2a-concept-declaration.cpp
+++ test/Parser/cxx2a-concept-declaration.cpp
@@ -14,8 +14,6 @@
 // expected-error@-2{{template template parameter requires 'class' after the parameter list}}
 // expected-error@-3{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed, did you attempt this?}}
 
-template concept C2 = 0.f; // expected-error {{constraint expression must be of type 'bool' but is of type 'float'}}
-
 struct S1 {
   template concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}}
 };
@@ -26,15 +24,15 @@
 
 template
 template
-concept C4 = true; // expected-error {{extraneous template parameter list in concept definition}}
+concept C2 = true; // expected-error {{extraneous template parameter list in concept definition}}
 
-template concept C5 = true; // expected-note {{previous}} expected-note {{previous}}
-int C5; // expected-error {{redefinition}}
-struct C5 {}; // expected-error {{redefinition}}
+template concept C3 = true; // expected-note {{previous}} expected-note {{previous}}
+int C3; // expected-error {{redefinition}}
+struct C3 {}; // expected-error {{redefinition}}
 
-struct C6 {}; // expected-note{{previous definition is here}}
-template concept C6 = true;
-// expected-error@-1{{redefinition of 'C6' as different kind of symbol}}
+struct C4 {}; // expected-note{{previous definition is here}}
+template concept C4 = true;
+// expected-error@-1{{redefinition of 'C4' as different kind of symbol}}
 
 // TODO: Add test to prevent explicit specialization, partial specialization
 // and explicit instantiation of concepts.
@@ -43,31 +41,55 @@
 struct integral_constant { static constexpr T value = v; };
 
 namespace N {
-  template concept C7 = true;
+  template concept C5 = true;
 }
-using N::C7;
+using N::C5;
 
-template  concept C8 = integral_constant::value;
+template  concept C6 = integral_constant::value;
 // expected-error@-1{{use of undeclared identifier 'wor'; did you mean 'word'?}}
 // expected-note@-2{{'word' declared here}}
 
-template concept bool C9 = true;
+template concept bool C7 = true;
 // expected-error@-1{{'bool' keyword after 'concept' is no longer valid in C++2a; remove it}}
 
-template<> concept C10 = false;
+template<> concept C8 = false;
 // expected-error@-1{{concept template parameter list must have at least one parameter; explicit specialization of concepts is not allowed, did you attempt this?}}
 
-template<> concept C9 = false;
+template<> concept C7 = false;
 // expected-error@-1{{name defined in concept definition must be an identifier}}
 
-template concept N::C11 = false;
+template concept N::C9 = false;
 // expected-error@-1{{unexpected namespace scope before concept name; concepts must be defined inside their namespace, if any}}
 
 class A { };
 // expected-note@-1{{'A' declared here}}
 
-template concept A::C12 = false;
+template concept A::C10 = false;
 // expected-error@-1{{expected namespace name}}
 
 template concept operator int = false;
 // expected-error@-1{{name defined in concept definition must be an identifier}}
+

[PATCH] D40381: Parse concept definition

2019-04-09 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 194417.
saar.raz added a comment.
Herald added a subscriber: jfb.
Herald added a project: clang.

Address most of rsmith's CR comments, rebase onto trunk


Repository:
  rC Clang

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

https://reviews.llvm.org/D40381

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Basic/DeclNodes.td
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/TemplateKinds.h
  include/clang/Parse/Parser.h
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTDumper.cpp
  lib/AST/DeclBase.cpp
  lib/AST/DeclPrinter.cpp
  lib/AST/DeclTemplate.cpp
  lib/CodeGen/CGDecl.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/Index/IndexDecl.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaLookup.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  test/Driver/Inputs/CUDA-nolibdevice/usr/local/cuda/bin/ptxas
  test/Driver/Inputs/CUDA-symlinks/opt/cuda/bin/ptxas
  test/Driver/Inputs/CUDA/usr/local/cuda/bin/ptxas
  test/Parser/cxx-concept-declaration.cpp
  test/Parser/cxx-concepts-ambig-constraint-expr.cpp
  test/Parser/cxx-concepts-requires-clause.cpp
  test/Parser/cxx2a-concept-declaration.cpp
  test/Parser/cxx2a-concepts-ambig-constraint-expr.cpp
  test/Parser/cxx2a-concepts-requires-clause.cpp
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -6252,6 +6252,7 @@
   case Decl::PragmaComment:
   case Decl::PragmaDetectMismatch:
   case Decl::UsingPack:
+  case Decl::Concept:
 return C;
 
   // Declaration kinds that don't make any sense here, but are
Index: test/Parser/cxx-concepts-requires-clause.cpp
===
--- /dev/null
+++ test/Parser/cxx-concepts-requires-clause.cpp
@@ -1,82 +0,0 @@
-// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ %s -verify
-// expected-no-diagnostics
-
-// Test parsing of the optional requires-clause in a template-declaration.
-
-template  requires true
-void foo() { }
-
-
-template  requires !0
-struct A {
-  void foo();
-  struct AA;
-  enum E : int;
-  static int x;
-
-  template  requires true
-  void Mfoo();
-
-  template  requires true
-  struct M;
-
-  template  requires true
-  static int Mx;
-
-  template  requires true
-  using MQ = M;
-};
-
-template  requires !0
-void A::foo() { }
-
-template  requires !0
-struct A::AA { };
-
-template  requires !0
-enum A::E : int { E0 };
-
-template  requires !0
-int A::x = 0;
-
-template  requires !0
-template  requires true
-void A::Mfoo() { }
-
-template  requires !0
-template  requires true
-struct A::M { };
-
-template  requires !0
-template  requires true
-int A::Mx = 0;
-
-
-template  requires true
-int x = 0;
-
-template  requires true
-using Q = A;
-
-struct C {
-  template  requires true
-  void Mfoo();
-
-  template  requires true
-  struct M;
-
-  template  requires true
-  static int Mx;
-
-  template  requires true
-  using MQ = M;
-};
-
-template  requires true
-void C::Mfoo() { }
-
-template  requires true
-struct C::M { };
-
-template  requires true
-int C::Mx = 0;
Index: test/Parser/cxx-concepts-ambig-constraint-expr.cpp
===
--- /dev/null
+++ test/Parser/cxx-concepts-ambig-constraint-expr.cpp
@@ -1,29 +0,0 @@
-// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ %s -verify
-
-// Test parsing of constraint-expressions in cases where the grammar is
-// ambiguous with the expectation that the longest token sequence which matches
-// the syntax is consumed without backtracking.
-
-// type-specifier-seq in conversion-type-id
-template  requires (bool)::operator short
-unsigned int foo(); // expected-error {{C++ requires a type specifier for all declarations}}
-
-// type-specifier-seq in new-type-id
-template  requires (bool)sizeof new (T::f()) short
-unsigned int bar(); // expected-error {{C++ requires a type specifier for all declarations}}
-
-template requires (bool)sizeof new (T::f()) unsigned // expected-error {{'struct' cannot be signed or unsigned}}
-struct X { }; // expected-error {{'X' cannot be defined in a type specifier}}
-
-// C-style cast
-// of function call on function-style cast
-template  requires (bool(T()))
-T (*fp)(); // expected-error {{use of undeclared identifier 'fp'}}
-
-// function-style cast
-// as the callee in a function call
-struct A {
-  static int t;
-  template  requires bool(T())
-  (A(T ())) { } // expected-error {{called object type 'bool' is not a 

[PATCH] D40381: Parse concept definition

2019-04-09 Thread Saar Raz via Phabricator via cfe-commits
saar.raz marked 21 inline comments as done.
saar.raz added a comment.

Only the TemplatedDecl issue remains, all other comments have been addressed 
and we're rebased onto master.
@rsmith please reply to the last comment, and lets finally start merging these 
:)


Repository:
  rC Clang

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

https://reviews.llvm.org/D40381



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


[PATCH] D40381: Parse concept definition

2019-04-09 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added inline comments.
Herald added a subscriber: arphaman.



Comment at: include/clang/AST/DeclTemplate.h:3035
+  SourceRange getSourceRange() const override LLVM_READONLY {
+return SourceRange(getLocation(), getLocation());
+  }

rsmith wrote:
> faisalv wrote:
> > why not just fix it now?
> >   return SourceRange(getTemplateParameters()->getTemplateLoc(), 
> > ConstraintExpr->getLocEnd(); 
> > 
> > ?
> There's a bigger problem here:
> 
> ```
> TemplateDecl *TD = /*some ConceptDecl*/;
> auto SR = TD->getSourceRange(); // crash
> ```
> 
> `TemplateDecl` has a hard assumption that it contains a `TemplatedDecl`. So, 
> three options:
> 
> 1) Change `TemplateDecl` and all its users to remove this assumption (hard 
> and leads to an awkward-to-use AST)
> 2) Add a `Decl` subclass that acts as the templated declaration in a concept 
> declaration (corresponding to the C++ grammar's //concept-definition// 
> production)
> 3) Make `ConceptDecl` //not// derive from a `TemplateDecl` at all
> 
> I think option 2 is my preference, but option 3 is also somewhat appealing 
> (there are other ways in which a concept is not a template: for instance, it 
> cannot be constrained, and it cannot be classified as either a type template 
> or a non-type template, because its kind depends on the context in which it 
> appears).
> 
> Of course, this leads to one of the Hard Problems Of Computer Science: naming 
> things. `ConceptDecl` for a //concept-definition// and `ConceptTemplateDecl` 
> for the //template-head concept-definition// would be consistent with the 
> rest of the AST. It's a little unfortunate for the longer name to be the AST 
> node that we actually interact with, but the consistency is probably worth 
> the cost.
The dummy decl is pretty confusing and will be a very weird decl in and of 
itself. I can't think of a good name right now, but your proposed naming will 
be pretty confusing given that a ConceptTemplateDecl does not template a 
concept declaration given the meaning of the phrase in the standard... Maybe 
ConceptBodyDecl? ConceptDummyDecl? ConceptDefinitionDecl? We need something 
that screams "this is not interesting" for the AST usage to be reasonable. 
Option 3 feels like loads of code duplication.
I'm not entirely sure how many blind (through TemplateDecl) uses of 
getTemplatedDecl there are, but there might not be that many, in which case the 
first option might be the lesser of all these evils.


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

https://reviews.llvm.org/D40381



___
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.

2018-08-18 Thread Saar Raz via Phabricator via cfe-commits
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.

2018-08-18 Thread Saar Raz via Phabricator via cfe-commits
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] D41217: [Concepts] Concept Specialization Expressions

2018-08-18 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 161372.
saar.raz added a comment.

- Address CR comments - add FoundDecl tracking, instantiationdependent 
calculation, display non-constant expression diagnostic notes


Repository:
  rC Clang

https://reviews.llvm.org/D41217

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/StmtNodes.td
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/Expr.cpp
  lib/AST/ExprCXX.cpp
  lib/AST/ExprClassification.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Parse/ParseExpr.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Sema/CMakeLists.txt
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaExceptionSpec.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  test/Parser/cxx-concept-declaration.cpp
  tools/libclang/CXCursor.cpp

Index: tools/libclang/CXCursor.cpp
===
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -231,6 +231,7 @@
   case Stmt::TypeTraitExprClass:
   case Stmt::CoroutineBodyStmtClass:
   case Stmt::CoawaitExprClass:
+  case Stmt::ConceptSpecializationExprClass:
   case Stmt::DependentCoawaitExprClass:
   case Stmt::CoreturnStmtClass:
   case Stmt::CoyieldExprClass:
Index: test/Parser/cxx-concept-declaration.cpp
===
--- test/Parser/cxx-concept-declaration.cpp
+++ test/Parser/cxx-concept-declaration.cpp
@@ -9,8 +9,6 @@
 
 template concept D1 = true; // expected-error {{expected template parameter}}
 
-template concept C2 = 0.f; // expected-error {{constraint expression must be 'bool'}}
-
 struct S1 {
   template concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}}
 };
@@ -29,3 +27,31 @@
 
 // TODO: Add test to prevent explicit specialization, partial specialization
 // and explicit instantiation of concepts.
+
+template concept C7 = 2; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template concept C8 = 2 && x; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template concept C9 = x || 2 || x; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template concept C10 = 8ull && x || x; // expected-error {{atomic constraint must be of type 'bool' (found 'unsigned long long')}}
+template concept C11 = sizeof(T); // expected-error {{atomic constraint must be of type 'bool' (found 'unsigned long')}}
+template concept C12 = T{};
+static_assert(!C12);
+template concept C13 = (bool&&)true;
+static_assert(C13);
+template concept C14 = (const bool&)true;
+static_assert(C14);
+template concept C15 = (const bool)true;
+static_assert(C15);
+
+template
+struct integral_constant { static constexpr T value = v; };
+
+template  concept C16 = integral_constant::value && true;
+static_assert(C16);
+static_assert(!C16);
+template  concept C17 = integral_constant::value;
+static_assert(C17);
+static_assert(!C17);
+
+template  concept C18 = integral_constant::value;
+// expected-error@-1{{use of undeclared identifier 'wor'; did you mean 'word'?}}
+// expected-note@-2{{'word' declared here}}
\ No newline at end of file
Index: test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
===
--- test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
+++ test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
@@ -1,5 +1,151 @@
 // RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
-// expected-no-diagnostics
 
-template concept C = true;
-static_assert(C);
+template concept C1 = true;
+static_assert(C1);
+
+template concept C2 = sizeof(T) == 4;
+static_assert(C2);
+static_assert(!C2);
+static_assert(C2);
+static_assert(!C2);
+
+template concept C3 = sizeof(*T{}) == 4;
+static_assert(C3);
+static_assert(!C3);
+
+struct A {
+  static constexpr int add(int a, int b) {
+return a + b;
+  }
+};
+struct B {
+  static int add(int a, int b) { // expected-note{{declared here}}
+return a + b;
+  }
+};
+template
+concept C4 = U::add(1, 2) == 3;
+// expected-error@-1{{substitution into constraint expression resulted in a non-constant expression}}
+// expected-note@-2{{non-constexpr function 'add' cannot be used in a constant expression}}
+static_assert(C4);
+static_assert(!C4); // expected-note {{while checking the satisfaction of concept 'C4' requested here}}
+
+template
+constexpr bool is_same_v = false;
+
+template
+constexpr bool is_same_v = true;
+
+template
+concept Same = is_same_v;
+

[PATCH] D41284: [Concepts] Associated constraints infrastructure.

2018-08-18 Thread Saar Raz via Phabricator via cfe-commits
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] D41217: [Concepts] Concept Specialization Expressions

2018-08-18 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added inline comments.



Comment at: lib/Sema/SemaTemplateInstantiate.cpp:679-681
+  Diags.Report(Active->PointOfInstantiation,
+   diag::note_constraint_substitution_here)
+  << Active->InstantiationRange;

saar.raz wrote:
> rsmith wrote:
> > Is this note ever useful? It will presumably always point into the same 
> > concept definition that the prior diagnostic also pointed at, and doesn't 
> > seem to add anything in the testcases.
> > 
> > Maybe we could keep the CodeSynthesisContext around as a marker that we've 
> > entered a SFINAE context, but not have any corresponding diagnostic. (The 
> > note produced for the enclosing `ConstraintsCheck` context covers that.) Or 
> > we could remove this and store a flag on the `ConstraintsCheck` to indicate 
> > whether we're in a SFINAEable portion of it.
> If the concept definition is multiline/contains macros, this would point at 
> the exact place where the problematic constraint occured, we should probably 
> add tests for this case though.
> Maybe we can omit the diagnostic when the concept and the constraint are on 
> the same line or something?
> 
Correction - I just now realized you were referring to the 'in instantiation of 
template class' note and not the 'while checking the satisfaction...' note.
In this case - the only case I can think of where the problematic instantiation 
and the constraint expression would be in very different places is indeed 
multiline constraint expressions or macros in a constraint expression (but you 
know better than I do - can you think of any other cases? or maybe there are 
other non-SFINAE errors that can result from substitution and would not produce 
a note?). Maybe these cases are remote enough to warrant removing this 
diagnostic or as I said earlier omit them in cases where they are unhelpful.


Repository:
  rC Clang

https://reviews.llvm.org/D41217



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


[PATCH] D41217: [Concepts] Concept Specialization Expressions

2018-08-18 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added inline comments.



Comment at: lib/Sema/SemaTemplateInstantiate.cpp:679-681
+  Diags.Report(Active->PointOfInstantiation,
+   diag::note_constraint_substitution_here)
+  << Active->InstantiationRange;

rsmith wrote:
> Is this note ever useful? It will presumably always point into the same 
> concept definition that the prior diagnostic also pointed at, and doesn't 
> seem to add anything in the testcases.
> 
> Maybe we could keep the CodeSynthesisContext around as a marker that we've 
> entered a SFINAE context, but not have any corresponding diagnostic. (The 
> note produced for the enclosing `ConstraintsCheck` context covers that.) Or 
> we could remove this and store a flag on the `ConstraintsCheck` to indicate 
> whether we're in a SFINAEable portion of it.
If the concept definition is multiline/contains macros, this would point at the 
exact place where the problematic constraint occured, we should probably add 
tests for this case though.
Maybe we can omit the diagnostic when the concept and the constraint are on the 
same line or something?



Repository:
  rC Clang

https://reviews.llvm.org/D41217



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


[PATCH] D41569: [Concepts] Constraint enforcement and diagnostics

2018-08-17 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 161348.
saar.raz added a comment.

- Adjusted to new CodeSynthesisContexts, added tests for them.


Repository:
  rC Clang

https://reviews.llvm.org/D41569

Files:
  include/clang/AST/ExprCXX.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  include/clang/Sema/SemaConcept.h
  include/clang/Sema/TemplateDeduction.h
  lib/AST/ExprCXX.cpp
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp

Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+namespace class_templates
+{
+  template requires sizeof(T) >= 4 // expected-note {{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}}
+  struct is_same { static constexpr bool value = false; };
+
+  template requires sizeof(T*) >= 4 && sizeof(T) >= 4
+  struct is_same { static constexpr bool value = true; };
+
+  static_assert(!is_same::value);
+  static_assert(!is_same::value);
+  static_assert(is_same::value);
+  static_assert(is_same::value); // expected-error {{constraints not satisfied for class template 'is_same' [with T = char, U = char]}}
+
+  template
+  struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}}
+
+  template
+  struct B {};
+
+  template requires A::type // expected-note{{in instantiation of template class 'class_templates::A' requested here}}
+   // expected-note@-1{{while substituting template arguments into constraint expression here}}
+  struct B {};
+
+  template requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}}
+  struct B {};
+
+  static_assert((B{}, true)); // expected-note{{while checking constraint satisfaction for class template partial specialization 'B' required here}}
+  // expected-note@-1{{while checking constraint satisfaction for class template partial specialization 'B' required here}}
+  // expected-note@-2{{during template argument deduction for class template partial specialization 'B' [with T = int *]}}
+  // expected-note@-3{{during template argument deduction for class template partial specialization 'B' [with T = int]}}
+  // expected-note@-4 2{{in instantiation of template class 'class_templates::B' requested here}}
+}
+
+namespace variable_templates
+{
+  template requires sizeof(T) >= 4
+  constexpr bool is_same_v = false;
+
+  template requires sizeof(T*) >= 4 && sizeof(T) >= 4
+  constexpr bool is_same_v = true;
+
+  static_assert(!is_same_v);
+  static_assert(!is_same_v);
+  static_assert(is_same_v);
+
+  template
+  struct A { using type = typename T::type; }; // expected-error{{type 'int *' cannot be used prior to '::' because it has no members}}
+
+  template
+  constexpr bool v1 = false;
+
+  template requires A::type // expected-note{{in instantiation of template class 'variable_templates::A' requested here}}
+   // expected-note@-1{{while substituting template arguments into constraint expression here}}
+  constexpr bool v1 = true;
+
+  template requires T{} // expected-error{{atomic constraint must be of type 'bool' (found 'int')}}
+  constexpr bool v1 = true;
+
+  static_assert(v1); // expected-note{{while checking constraint satisfaction for variable template partial specialization 'v1' required here}}
+  // expected-note@-1{{while checking constraint satisfaction for variable template partial specialization 'v1' required here}}
+  // expected-note@-2{{during template argument deduction for variable template partial specialization 'v1' [with T = int *]}}
+  // expected-note@-3{{during template argument deduction for variable template partial specialization 'v1' [with T = int]}}
+  // expected-error@-4{{static_assert failed due to requirement 'v1'}}
+
+}
\ No newline at end of file
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
@@ -0,0 +1,92 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+

[PATCH] D41284: [Concepts] Associated constraints infrastructure.

2018-08-17 Thread Saar Raz via Phabricator via cfe-commits
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] D41217: [Concepts] Concept Specialization Expressions

2018-08-17 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 161343.
saar.raz added a comment.

- Fix bad ArgsAsWritten assertion, add missing null initializer in 
ConceptSpecializationExpr.


Repository:
  rC Clang

https://reviews.llvm.org/D41217

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/StmtNodes.td
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/Expr.cpp
  lib/AST/ExprCXX.cpp
  lib/AST/ExprClassification.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Parse/ParseExpr.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Sema/CMakeLists.txt
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaExceptionSpec.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  test/Parser/cxx-concept-declaration.cpp
  tools/libclang/CXCursor.cpp

Index: tools/libclang/CXCursor.cpp
===
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -231,6 +231,7 @@
   case Stmt::TypeTraitExprClass:
   case Stmt::CoroutineBodyStmtClass:
   case Stmt::CoawaitExprClass:
+  case Stmt::ConceptSpecializationExprClass:
   case Stmt::DependentCoawaitExprClass:
   case Stmt::CoreturnStmtClass:
   case Stmt::CoyieldExprClass:
Index: test/Parser/cxx-concept-declaration.cpp
===
--- test/Parser/cxx-concept-declaration.cpp
+++ test/Parser/cxx-concept-declaration.cpp
@@ -9,8 +9,6 @@
 
 template concept D1 = true; // expected-error {{expected template parameter}}
 
-template concept C2 = 0.f; // expected-error {{constraint expression must be 'bool'}}
-
 struct S1 {
   template concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}}
 };
@@ -29,3 +27,31 @@
 
 // TODO: Add test to prevent explicit specialization, partial specialization
 // and explicit instantiation of concepts.
+
+template concept C7 = 2; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template concept C8 = 2 && x; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template concept C9 = x || 2 || x; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template concept C10 = 8ull && x || x; // expected-error {{atomic constraint must be of type 'bool' (found 'unsigned long long')}}
+template concept C11 = sizeof(T); // expected-error {{atomic constraint must be of type 'bool' (found 'unsigned long')}}
+template concept C12 = T{};
+static_assert(!C12);
+template concept C13 = (bool&&)true;
+static_assert(C13);
+template concept C14 = (const bool&)true;
+static_assert(C14);
+template concept C15 = (const bool)true;
+static_assert(C15);
+
+template
+struct integral_constant { static constexpr T value = v; };
+
+template  concept C16 = integral_constant::value && true;
+static_assert(C16);
+static_assert(!C16);
+template  concept C17 = integral_constant::value;
+static_assert(C17);
+static_assert(!C17);
+
+template  concept C18 = integral_constant::value;
+// expected-error@-1{{use of undeclared identifier 'wor'; did you mean 'word'?}}
+// expected-note@-2{{'word' declared here}}
\ No newline at end of file
Index: test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
===
--- test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
+++ test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
@@ -1,5 +1,146 @@
 // RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
-// expected-no-diagnostics
 
-template concept C = true;
-static_assert(C);
+template concept C1 = true;
+static_assert(C1);
+
+template concept C2 = sizeof(T) == 4;
+static_assert(C2);
+static_assert(!C2);
+static_assert(C2);
+static_assert(!C2);
+
+template concept C3 = sizeof(*T{}) == 4;
+static_assert(C3);
+static_assert(!C3);
+
+struct A {
+  static constexpr int add(int a, int b) {
+return a + b;
+  }
+};
+struct B {
+  static int add(int a, int b) {
+return a + b;
+  }
+};
+template
+concept C4 = U::add(1, 2) == 3; // expected-error {{substitution into constraint expression resulted in a non-constant expression}}
+static_assert(C4);
+static_assert(!C4); // expected-note {{while checking the satisfaction of concept 'C4' requested here}}
+
+template
+constexpr bool is_same_v = false;
+
+template
+constexpr bool is_same_v = true;
+
+template
+concept Same = is_same_v;
+
+static_assert(Same);
+static_assert(Same);
+static_assert(!Same);
+static_assert(!Same);
+static_assert(Same);
+
+static_assert(Same)>);
+static_assert(Same)>);

[PATCH] D41284: [Concepts] Associated constraints infrastructure.

2018-08-15 Thread Saar Raz via Phabricator via cfe-commits
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> 

[PATCH] D41217: [Concepts] Concept Specialization Expressions

2018-08-13 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added inline comments.



Comment at: include/clang/AST/DeclTemplate.h:3063
   SourceRange getSourceRange() const override LLVM_READONLY {
-return SourceRange(getLocation(), getLocation());
+return SourceRange(getLocation(), getConstraintExpr()->getLocEnd());
   }

steveire wrote:
> `getLocEnd` is deprecated and will be removed soon. See 
> http://clang-developers.42468.n3.nabble.com/API-Removal-Notice-4-weeks-getStartLoc-getLocStart-getLocEnd-td4061566.html
Good to know, but I'm not yet merged against trunk so getEndLoc isn't here yet 
(will soon post a merged version of this patch)


Repository:
  rC Clang

https://reviews.llvm.org/D41217



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


[PATCH] D41217: [Concepts] Concept Specialization Expressions

2018-08-13 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 160437.
saar.raz added a comment.

Address Arthur's comments, add missing CorrectDelayedTyposInExpr


Repository:
  rC Clang

https://reviews.llvm.org/D41217

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/StmtNodes.td
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/Expr.cpp
  lib/AST/ExprCXX.cpp
  lib/AST/ExprClassification.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Parse/ParseExpr.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Sema/CMakeLists.txt
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaExceptionSpec.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  test/Parser/cxx-concept-declaration.cpp
  tools/libclang/CXCursor.cpp

Index: tools/libclang/CXCursor.cpp
===
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -231,6 +231,7 @@
   case Stmt::TypeTraitExprClass:
   case Stmt::CoroutineBodyStmtClass:
   case Stmt::CoawaitExprClass:
+  case Stmt::ConceptSpecializationExprClass:
   case Stmt::DependentCoawaitExprClass:
   case Stmt::CoreturnStmtClass:
   case Stmt::CoyieldExprClass:
Index: test/Parser/cxx-concept-declaration.cpp
===
--- test/Parser/cxx-concept-declaration.cpp
+++ test/Parser/cxx-concept-declaration.cpp
@@ -9,8 +9,6 @@
 
 template concept D1 = true; // expected-error {{expected template parameter}}
 
-template concept C2 = 0.f; // expected-error {{constraint expression must be 'bool'}}
-
 struct S1 {
   template concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}}
 };
@@ -29,3 +27,31 @@
 
 // TODO: Add test to prevent explicit specialization, partial specialization
 // and explicit instantiation of concepts.
+
+template concept C7 = 2; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template concept C8 = 2 && x; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template concept C9 = x || 2 || x; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template concept C10 = 8ull && x || x; // expected-error {{atomic constraint must be of type 'bool' (found 'unsigned long long')}}
+template concept C11 = sizeof(T); // expected-error {{atomic constraint must be of type 'bool' (found 'unsigned long')}}
+template concept C12 = T{};
+static_assert(!C12);
+template concept C13 = (bool&&)true;
+static_assert(C13);
+template concept C14 = (const bool&)true;
+static_assert(C14);
+template concept C15 = (const bool)true;
+static_assert(C15);
+
+template
+struct integral_constant { static constexpr T value = v; };
+
+template  concept C16 = integral_constant::value && true;
+static_assert(C16);
+static_assert(!C16);
+template  concept C17 = integral_constant::value;
+static_assert(C17);
+static_assert(!C17);
+
+template  concept C18 = integral_constant::value;
+// expected-error@-1{{use of undeclared identifier 'wor'; did you mean 'word'?}}
+// expected-note@-2{{'word' declared here}}
\ No newline at end of file
Index: test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
===
--- test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
+++ test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
@@ -1,5 +1,146 @@
 // RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
-// expected-no-diagnostics
 
-template concept C = true;
-static_assert(C);
+template concept C1 = true;
+static_assert(C1);
+
+template concept C2 = sizeof(T) == 4;
+static_assert(C2);
+static_assert(!C2);
+static_assert(C2);
+static_assert(!C2);
+
+template concept C3 = sizeof(*T{}) == 4;
+static_assert(C3);
+static_assert(!C3);
+
+struct A {
+  static constexpr int add(int a, int b) {
+return a + b;
+  }
+};
+struct B {
+  static int add(int a, int b) {
+return a + b;
+  }
+};
+template
+concept C4 = U::add(1, 2) == 3; // expected-error {{substitution into constraint expression resulted in a non-constant expression}}
+static_assert(C4);
+static_assert(!C4); // expected-note {{while checking the satisfaction of concept 'C4' requested here}}
+
+template
+constexpr bool is_same_v = false;
+
+template
+constexpr bool is_same_v = true;
+
+template
+concept Same = is_same_v;
+
+static_assert(Same);
+static_assert(Same);
+static_assert(!Same);
+static_assert(!Same);
+static_assert(Same);
+
+static_assert(Same)>);
+static_assert(Same)>);
+static_assert(Same)>);

[PATCH] D41217: [Concepts] Concept Specialization Expressions

2018-08-11 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added inline comments.



Comment at: test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp:121
+template
+concept C7 = sizeof(T) == 1 || sizeof(typename T3::type) == 1; // 
expected-note{{while substituting template arguments into constraint expression 
here}} expected-note{{in instantiation of template class 'T3' requested 
here}}
+

Quuxplusone wrote:
> Nit: You could use `// expected-note@-1{{...}}`, `// expected-note@-2{{...}}` 
> to make lines like this more readable.
 Well you learn something every day 



Comment at: test/Parser/cxx-concept-declaration.cpp:48
+bool a = C16;
+bool b = C17;

Quuxplusone wrote:
> Should you static-assert the expected results?
> ```
> static_assert(!C12);
> static_assert(C13);
> static_assert(C14);
> static_assert(C15);
> static_assert(C16);
> static_assert(C16);
> static_assert(C17);
> static_assert(!C17);
> ```
That's not the point of these tests but it couldn't hurt, I guess 


Repository:
  rC Clang

https://reviews.llvm.org/D41217



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


[PATCH] D41217: [Concepts] Concept Specialization Expressions

2018-08-11 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 160237.
saar.raz added a comment.

Removed unused "note_in_concept_specialization" diagnostic ID.


Repository:
  rC Clang

https://reviews.llvm.org/D41217

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/StmtNodes.td
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/Expr.cpp
  lib/AST/ExprCXX.cpp
  lib/AST/ExprClassification.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Parse/ParseExpr.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Sema/CMakeLists.txt
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaExceptionSpec.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  test/Parser/cxx-concept-declaration.cpp
  tools/libclang/CXCursor.cpp

Index: tools/libclang/CXCursor.cpp
===
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -231,6 +231,7 @@
   case Stmt::TypeTraitExprClass:
   case Stmt::CoroutineBodyStmtClass:
   case Stmt::CoawaitExprClass:
+  case Stmt::ConceptSpecializationExprClass:
   case Stmt::DependentCoawaitExprClass:
   case Stmt::CoreturnStmtClass:
   case Stmt::CoyieldExprClass:
Index: test/Parser/cxx-concept-declaration.cpp
===
--- test/Parser/cxx-concept-declaration.cpp
+++ test/Parser/cxx-concept-declaration.cpp
@@ -9,8 +9,6 @@
 
 template concept D1 = true; // expected-error {{expected template parameter}}
 
-template concept C2 = 0.f; // expected-error {{constraint expression must be 'bool'}}
-
 struct S1 {
   template concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}}
 };
@@ -29,3 +27,22 @@
 
 // TODO: Add test to prevent explicit specialization, partial specialization
 // and explicit instantiation of concepts.
+
+template concept C7 = 2; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template concept C8 = 2 && x; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template concept C9 = x || 2 || x; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template concept C10 = 8ull && x || x; // expected-error {{atomic constraint must be of type 'bool' (found 'unsigned long long')}}
+template concept C11 = sizeof(T); // expected-error {{atomic constraint must be of type 'bool' (found 'unsigned long')}}
+template concept C12 = T{};
+template concept C13 = (bool&&)true;
+template concept C14 = (const bool&)true;
+template concept C15 = (const bool)true;
+
+template
+struct integral_constant { static constexpr T value = v; };
+
+template  concept C16 = integral_constant::value && true;
+template  concept C17 = integral_constant::value;
+
+bool a = C16;
+bool b = C17;
Index: test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
===
--- test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
+++ test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
@@ -1,5 +1,136 @@
 // RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
-// expected-no-diagnostics
 
-template concept C = true;
-static_assert(C);
+template concept C1 = true;
+static_assert(C1);
+
+template concept C2 = sizeof(T) == 4;
+static_assert(C2);
+static_assert(!C2);
+static_assert(C2);
+static_assert(!C2);
+
+template concept C3 = sizeof(*T{}) == 4;
+static_assert(C3);
+static_assert(!C3);
+
+struct A {
+  static constexpr int add(int a, int b) {
+return a + b;
+  }
+};
+struct B {
+  static int add(int a, int b) {
+return a + b;
+  }
+};
+template
+concept C4 = U::add(1, 2) == 3; // expected-error {{substitution into constraint expression resulted in a non-constant expression}}
+static_assert(C4);
+static_assert(!C4); // expected-note {{while checking the satisfaction of concept 'C4' requested here}}
+
+template
+constexpr bool is_same_v = false;
+
+template
+constexpr bool is_same_v = true;
+
+template
+concept Same = is_same_v;
+
+static_assert(Same);
+static_assert(Same);
+static_assert(!Same);
+static_assert(!Same);
+static_assert(Same);
+
+static_assert(Same)>);
+static_assert(Same)>);
+static_assert(Same)>);
+static_assert(Same)>);
+
+template concept C5 = T{}; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+constexpr bool x = C5; // expected-note {{while checking the satisfaction of concept 'C5' requested here}}
+
+template
+concept IsEven = (x % 2) == 0;
+
+static_assert(IsEven<20>);
+static_assert(!IsEven<11>);
+
+template typename P>

[PATCH] D41217: [Concepts] Concept Specialization Expressions

2018-08-10 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 160216.
saar.raz added a comment.

Address Richard's CR comments. Among other things:

- CSEs overhauled and now store both source and converted template arguments 
(latter are tail-allocated), template KW location and NNS.
- CSEs no longer violate layering - satisfaction check now moved back to 
CheckConceptTemplateId.
- CodeSynthesisContexts created for both the act of checking the associated 
constraints of a template or the constraint expression of a concept 
(non-SFINAE), and for the act of substituting template arguments into a(n 
atomic) constraint expression (SFINAE).
- Added more tests for cases where substitution leads to a non-SFINAE failure 
and emits diagnostics
- Fixed and added test for incorrect conversion of instantiated CSE argument 
list.


Repository:
  rC Clang

https://reviews.llvm.org/D41217

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/StmtNodes.td
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/Expr.cpp
  lib/AST/ExprCXX.cpp
  lib/AST/ExprClassification.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Parse/ParseExpr.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Sema/CMakeLists.txt
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaExceptionSpec.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  test/Parser/cxx-concept-declaration.cpp
  tools/libclang/CXCursor.cpp

Index: tools/libclang/CXCursor.cpp
===
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -231,6 +231,7 @@
   case Stmt::TypeTraitExprClass:
   case Stmt::CoroutineBodyStmtClass:
   case Stmt::CoawaitExprClass:
+  case Stmt::ConceptSpecializationExprClass:
   case Stmt::DependentCoawaitExprClass:
   case Stmt::CoreturnStmtClass:
   case Stmt::CoyieldExprClass:
Index: test/Parser/cxx-concept-declaration.cpp
===
--- test/Parser/cxx-concept-declaration.cpp
+++ test/Parser/cxx-concept-declaration.cpp
@@ -9,8 +9,6 @@
 
 template concept D1 = true; // expected-error {{expected template parameter}}
 
-template concept C2 = 0.f; // expected-error {{constraint expression must be 'bool'}}
-
 struct S1 {
   template concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}}
 };
@@ -29,3 +27,22 @@
 
 // TODO: Add test to prevent explicit specialization, partial specialization
 // and explicit instantiation of concepts.
+
+template concept C7 = 2; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template concept C8 = 2 && x; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template concept C9 = x || 2 || x; // expected-error {{atomic constraint must be of type 'bool' (found 'int')}}
+template concept C10 = 8ull && x || x; // expected-error {{atomic constraint must be of type 'bool' (found 'unsigned long long')}}
+template concept C11 = sizeof(T); // expected-error {{atomic constraint must be of type 'bool' (found 'unsigned long')}}
+template concept C12 = T{};
+template concept C13 = (bool&&)true;
+template concept C14 = (const bool&)true;
+template concept C15 = (const bool)true;
+
+template
+struct integral_constant { static constexpr T value = v; };
+
+template  concept C16 = integral_constant::value && true;
+template  concept C17 = integral_constant::value;
+
+bool a = C16;
+bool b = C17;
Index: test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
===
--- test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
+++ test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
@@ -1,5 +1,136 @@
 // RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
-// expected-no-diagnostics
 
-template concept C = true;
-static_assert(C);
+template concept C1 = true;
+static_assert(C1);
+
+template concept C2 = sizeof(T) == 4;
+static_assert(C2);
+static_assert(!C2);
+static_assert(C2);
+static_assert(!C2);
+
+template concept C3 = sizeof(*T{}) == 4;
+static_assert(C3);
+static_assert(!C3);
+
+struct A {
+  static constexpr int add(int a, int b) {
+return a + b;
+  }
+};
+struct B {
+  static int add(int a, int b) {
+return a + b;
+  }
+};
+template
+concept C4 = U::add(1, 2) == 3; // expected-error {{substitution into constraint expression resulted in a non-constant expression}}
+static_assert(C4);
+static_assert(!C4); // expected-note {{while checking the satisfaction of concept 'C4' requested here}}
+
+template

[PATCH] D41910: [Concepts] Constrained partial specializations and function overloads.

2018-08-08 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 159759.
saar.raz added a comment.

- Moved constraint checks to the end of FinishTemplateArgumentDeduction


Repository:
  rC Clang

https://reviews.llvm.org/D41910

Files:
  include/clang/AST/DeclTemplate.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/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.normal/p1.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp

Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 4
+bool a = false; // expected-note{{template is declared here}}
+
+template requires sizeof(T) >= 4 && sizeof(T) <= 10
+bool a = true; // expected-error{{variable template partial specialization is not more specialized than the primary template}}
+
+template
+concept C1 = sizeof(T) >= 4;
+
+template requires C1
+bool b = false;
+
+template requires C1 && sizeof(T) <= 10
+bool b = true;
+
+template
+concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
+
+template
+bool c = false;
+
+template requires C1
+bool c = true;
+
+template
+bool d = false;
+
+template
+bool d = true; // expected-error{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+
+template requires C1
+bool e = false;
+
+template
+bool e = true; // expected-error{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+
+template
+constexpr int f = 1;
+
+template requires C1 && C2
+constexpr int f = 2;
+
+template requires C1 || C2
+constexpr int f = 3;
+
+static_assert(f == 2);
+static_assert(f == 3);
+static_assert(f == 1);
+
+
+
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 4
+bool a() { return false; } // expected-note {{candidate function [with T = unsigned int]}}
+
+template requires sizeof(T) >= 4 && sizeof(T) <= 10
+bool a() { return true; } // expected-note {{candidate function [with T = unsigned int]}}
+
+bool av = a(); // expected-error {{call to 'a' is ambiguous}}
+
+template
+concept C1 = sizeof(T) >= 4;
+
+template requires C1
+constexpr bool b() { return false; }
+
+template requires C1 && sizeof(T) <= 10
+constexpr bool b() { return true; }
+
+static_assert(b());
+static_assert(!b());
+
+template
+concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
+
+template
+bool c() { return false; }
+
+template requires C1
+bool c() { return true; }
+
+template requires C1
+constexpr bool d() { return false; }
+
+template
+constexpr bool d() { return true; }
+
+static_assert(!d());
+
+template
+constexpr int e() { return 1; }
+
+template requires C1 && C2
+constexpr int e() { return 2; }
+
+template requires C1 || C2
+constexpr int e() { return 3; }
+
+static_assert(e() == 2);
+static_assert(e() == 3);
+static_assert(e() == 1);
+
+
+
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 4
+class A{}; // expected-note{{template is declared here}}
+
+template requires sizeof(T) >= 4 && sizeof(T) <= 10
+class A{}; // expected-error{{class template partial specialization is not more specialized than the primary template}}
+
+template
+concept C1 = sizeof(T) >= 4;
+
+template requires C1
+class B{};
+
+template requires C1 && sizeof(T) <= 10
+class B{};
+
+template
+concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
+
+template
+class C{};
+
+template requires C1
+class C{};
+
+template
+class D{}; // 

[PATCH] D43357: [Concepts] Function trailing requires clauses

2018-08-07 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added inline comments.



Comment at: lib/Sema/SemaDecl.cpp:8377-8381
+  } else if (D.hasTrailingRequiresClause()) {
+// C++2a [class.virtual]p6
+// A virtual method shall not have a requires-clause.
+Diag(NewFD->getTrailingRequiresClause()->getLocStart(),
+ diag::err_constrained_virtual_method);

rsmith wrote:
> This is the wrong place for this check. We don't yet know whether the 
> function is virtual here in general. A function can become virtual due to 
> template instantiation:
> 
> ```
> template struct A : T { void f() requires true; };
> struct B { virtual void f(); };
> template struct A; // error, A::f is constrained and virtual
> ```
> 
> This is perhaps a wording defect: it's not clear that `A::f()` really should 
> override `B::f()`, but that is the consequence of the current rules. I've 
> posted a question to the core reflector.
I don't really see why A::f() should override B::f() indeed - since it is not 
marked virtual nor override, shouldn't it just hide B::f()? or am I missing 
something here?


Repository:
  rC Clang

https://reviews.llvm.org/D43357



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


[PATCH] D41217: [Concepts] Concept Specialization Expressions

2018-08-07 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added inline comments.



Comment at: lib/Sema/SemaConcept.cpp:34
+  Diag(ConstraintExpression->getExprLoc(),
+   diag::err_non_bool_atomic_constraint)
+  << ConstraintExpression << ConstraintExpression->getType();

saar.raz wrote:
> rsmith wrote:
> > What justifies rejecting this prior to any use of the concept that would 
> > result in a satisfaction check?
> > 
> > (I think checking this is a good thing; what I'm wondering is whether we 
> > need to file a core issue to get the wording updated to allow us to reject 
> > such bogus concepts even if they're never used.)
> I guess this is already justified, if awkwardly (NDR) by [temp.res]p8.2
Correction - it says that IFNDR occurs when no substitution would result in a 
valid expression, so maybe this is well formed after all.
In this case it is a valid expression but not a valid constraint expression, 
maybe that's the missing word here?


Repository:
  rC Clang

https://reviews.llvm.org/D41217



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


[PATCH] D41217: [Concepts] Concept Specialization Expressions

2018-08-07 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added a comment.

@rsmith - thanks for the responses!
Will also address the comments I haven't responded to soon.




Comment at: include/clang/AST/ExprCXX.h:4420
+  /// \brief The concept named.
+  ConceptDecl *NamedConcept;
+

rsmith wrote:
> You should also track the `FoundDecl` and the optional 
> `NestedNameSpecifierLoc` (just like a `DeclRefExpr` would). Clang-based tools 
> (particularly refactoring tools) need those. There's also an optional 
> `template` keyword, but it can never matter in practice because the nested 
> name specifier can never be dependent, so it's probably not the most 
> high-priority thing to track.
Isn't the `FoundDecl` just the `NamedConcept`?



Comment at: include/clang/AST/ExprCXX.h:4423-4424
+  /// \brief The template argument list used to specialize the concept.
+  TemplateArgumentList *TemplateArgs;
+  const ASTTemplateArgumentListInfo *TemplateArgInfo;
+

rsmith wrote:
> It'd be nice if at least one of these two arrays could be tail-allocated.
Now that you mention it, TemplateArgs is never even used or set, I'll remove it.
As for TemplateArgInfo - do you mean allocate the ASTTemplateArgumentListInfo 
itself as a trailing obj or the individual TemplateArgumentLocs? the former 
seems more reasonable to me as it's convenient to have an 
ASTTemplateArgumentListInfo object around



Comment at: include/clang/AST/ExprCXX.h:4474-4481
+  void setSatisfied(bool Satisfied) {
+IsSatisfied = Satisfied;
+  }
+
+  SourceLocation getConceptNameLoc() const { return ConceptNameLoc; }
+  void setConceptNameLoc(SourceLocation Loc) {
+ConceptNameLoc = Loc;

rsmith wrote:
> Do you really need mutators for the 'satisfied' flag and the concept name 
> location?
They're here only because of ASTReader/Writer. I guess I can use a friend decl 
instead.



Comment at: lib/AST/StmtPrinter.cpp:2553
+void StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) 
{
+  OS << E->getNamedConcept()->getName();
+  printTemplateArgumentList(OS, E->getTemplateArgumentListInfo()->arguments(),

rsmith wrote:
> You should print out the nested name specifier here. (And ideally also the 
> `template` keyword, if specified...). And you should print the name of the 
> found declaration, not the name of the concept (although they can't differ 
> currently).
Are there possible upcoming changes that'll make them differ?



Comment at: lib/Sema/SemaConcept.cpp:34
+  Diag(ConstraintExpression->getExprLoc(),
+   diag::err_non_bool_atomic_constraint)
+  << ConstraintExpression << ConstraintExpression->getType();

rsmith wrote:
> What justifies rejecting this prior to any use of the concept that would 
> result in a satisfaction check?
> 
> (I think checking this is a good thing; what I'm wondering is whether we need 
> to file a core issue to get the wording updated to allow us to reject such 
> bogus concepts even if they're never used.)
I guess this is already justified, if awkwardly (NDR) by [temp.res]p8.2


Repository:
  rC Clang

https://reviews.llvm.org/D41217



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


[PATCH] D44352: [Concepts] Constrained template parameters

2018-08-06 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 159378.
saar.raz added a comment.

Split TryParseConstrainedParameter and ParseConstrainedTemplateParameter in 
preparation for requries expressions.


Repository:
  rC Clang

https://reviews.llvm.org/D44352

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/AST/TemplateBase.h
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Parse/Parser.h
  include/clang/Sema/Sema.h
  lib/AST/ASTContext.cpp
  lib/AST/ASTDumper.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/DeclTemplate.cpp
  lib/AST/ODRHash.cpp
  lib/Parse/ParseExprCXX.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Sema/SemaCXXScopeSpec.cpp
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.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.param/p10.cpp
  test/Parser/cxx-constrained-template-param-with-partial-id.cpp
  test/Parser/cxx-constrained-template-param.cpp
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -750,6 +750,10 @@
 }
 
 bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
+  if (Expr *CE = D->getConstraintExpression())
+if (Visit(MakeCXCursor(CE, StmtParent, TU, RegionOfInterest)))
+  return true;
+
   // Visit the default argument.
   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
@@ -898,6 +902,10 @@
 bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
   if (VisitDeclaratorDecl(D))
 return true;
+
+  if (Expr *CE = D->getConstraintExpression())
+if (Visit(MakeCXCursor(CE, StmtParent, TU, RegionOfInterest)))
+  return true;
   
   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
 if (Expr *DefArg = D->getDefaultArgument())
@@ -929,7 +937,11 @@
 bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
   if (VisitTemplateParameters(D->getTemplateParameters()))
 return true;
-  
+
+  if (Expr *CE = D->getConstraintExpression())
+if (Visit(MakeCXCursor(CE, StmtParent, TU, RegionOfInterest)))
+  return true;
+
   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
   VisitTemplateArgumentLoc(D->getDefaultArgument()))
 return true;
Index: test/Parser/cxx-constrained-template-param.cpp
===
--- /dev/null
+++ test/Parser/cxx-constrained-template-param.cpp
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ %s -verify
+// expected-no-diagnostics
+
+namespace type
+{
+  template
+  concept C1 = true;
+
+  template
+  using A = T[10];
+
+  using a = A;
+
+  namespace ns {
+template
+concept C2 = true;
+  }
+
+  template requires sizeof(T1) <= sizeof(T2)
+  struct B { };
+
+  using b = B;
+
+  template
+  struct C { };
+
+  using c1 = C;
+  using c2 = C;
+}
+
+namespace non_type
+{
+  template
+  concept C1 = true;
+
+  template
+  int A = v;
+
+  int& a = A<1>;
+
+  namespace ns {
+template
+concept C2 = true;
+  }
+
+  template requires sizeof(v1) <= sizeof(v2)
+  struct B { };
+
+  using b = B;
+
+  template
+  struct C { };
+
+  using c1 = C;
+  using c2 = C;
+}
+
+namespace temp
+{
+  template
+  struct test1 { };
+
+  template
+  struct test2 { };
+
+  template typename T>
+  concept C1 = true;
+
+  template
+  using A = TT;
+
+  using a = A;
+
+  namespace ns {
+template typename... TT>
+concept C2 = true;
+  }
+
+  template
+requires sizeof(TT1) <= sizeof(TT2)
+  struct B { };
+
+  using b = B;
+
+  template
+  struct C { };
+
+  using c1 = C;
+  using c2 = C;
+}
\ No newline at end of file
Index: test/Parser/cxx-constrained-template-param-with-partial-id.cpp
===
--- /dev/null
+++ test/Parser/cxx-constrained-template-param-with-partial-id.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ %s -verify
+
+template
+concept C1 = true;
+
+template // expected-error {{concept 'C1' requires more than 1 template argument; provide the remaining arguments explicitly to use it here}} expected-error{{explicit specialization of alias templates is not permitted}}
+using badA = T[10];
+
+template T>
+using A = T[10];
+
+using a = A;
+
+namespace ns {
+  template
+  concept C2 = true;
+}
+
+template // expected-error 2{{concept 'C2' requires more than 1 template argument; provide the remaining arguments explicitly to use it here}}
+requires sizeof(T1) <= sizeof(T2) // expected-error{{expected unqualified-id}}
+struct badB { 

[PATCH] D43357: [Concepts] Function trailing requires clauses

2018-08-06 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 159349.
saar.raz added a comment.
Herald added a subscriber: jfb.

- Fix bad diagnostic detection and suppression


Repository:
  rC Clang

https://reviews.llvm.org/D43357

Files:
  include/clang/AST/Decl.h
  include/clang/AST/DeclCXX.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/DeclSpec.h
  include/clang/Sema/Overload.h
  include/clang/Sema/Sema.h
  lib/AST/ASTDumper.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/Decl.cpp
  lib/AST/DeclCXX.cpp
  lib/AST/DeclPrinter.cpp
  lib/AST/DeclTemplate.cpp
  lib/AST/ODRHash.cpp
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseTentative.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaCast.cpp
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclAttr.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/CXX/concepts-ts/class.derived/class.virtual/p6.cpp
  test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p1.cpp
  test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p2.cpp
  test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p5.cpp
  test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p6.cpp
  test/CXX/concepts-ts/dcl.dcl/dcl.spec/dcl.spec.concept/p7.cpp
  test/CXX/concepts-ts/dcl.dcl/lit.cfg.py
  test/CXX/concepts-ts/dcl/dcl.dcl/dcl.spec/dcl.spec.concept/p1.cpp
  test/CXX/concepts-ts/dcl/dcl.dcl/dcl.spec/dcl.spec.concept/p2.cpp
  test/CXX/concepts-ts/dcl/dcl.dcl/dcl.spec/dcl.spec.concept/p5.cpp
  test/CXX/concepts-ts/dcl/dcl.dcl/dcl.spec/dcl.spec.concept/p6.cpp
  test/CXX/concepts-ts/dcl/dcl.dcl/dcl.spec/dcl.spec.concept/p7.cpp
  test/CXX/concepts-ts/dcl/dcl.dcl/lit.cfg.py
  test/CXX/concepts-ts/dcl/dcl.decl/p3.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/mixed-constraints.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p4.cpp
  test/CXX/concepts-ts/over/over.match/over.match.best/p1.cpp
  test/CXX/concepts-ts/over/over.over/p4.cpp

Index: test/CXX/concepts-ts/over/over.over/p4.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/over/over.over/p4.cpp
@@ -0,0 +1,56 @@
+// RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
+
+
+template
+constexpr static bool is_same_v = false;
+
+template
+constexpr static bool is_same_v = true;
+
+template
+concept AtLeast2 = sizeof(T) >= 2;
+
+template
+concept AtMost8 = sizeof(T) <= 8;
+
+int foo() requires AtLeast2 && AtMost8 {
+  return 0;
+}
+
+double foo() requires AtLeast2 {
+  return 0.0;
+}
+
+char bar() requires AtLeast2 { // expected-note {{possible target for call}}
+  return 1.0;
+}
+
+short bar() requires AtLeast2 && AtMost8 { // expected-note {{possible target for call}} expected-note {{candidate function}}
+  return 0.0;
+}
+
+int bar() requires AtMost8 && AtLeast2 { // expected-note {{possible target for call}} expected-note {{candidate function}}
+  return 0.0;
+}
+
+char baz() requires AtLeast2 {
+  return 1.0;
+}
+
+short baz() requires AtLeast2 && AtMost8 {
+  return 0.0;
+}
+
+int baz() requires AtMost8 && AtLeast2 {
+  return 0.0;
+}
+
+long baz() requires AtMost8 && AtLeast2 && AtLeast2 {
+  return 3.0;
+}
+
+void a() {
+  static_assert(is_same_v);
+  static_assert(is_same_v); // expected-error {{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} expected-error{{call to 'bar' is ambiguous}}
+  static_assert(is_same_v);
+}
\ No newline at end of file
Index: test/CXX/concepts-ts/over/over.match/over.match.best/p1.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/over/over.match/over.match.best/p1.cpp
@@ -0,0 +1,65 @@
+// RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
+
+
+template
+constexpr static bool is_same_v = false;
+
+template
+constexpr static bool is_same_v = true;
+
+namespace templates
+{
+  template
+  concept AtLeast1 = sizeof(T) >= 1;
+
+  template
+  int foo(T t) requires sizeof(T) == 4 { // expected-note {{candidate function}}
+return 0;
+  }
+
+  template
+  char foo(T t) requires AtLeast1 { // expected-note {{candidate function}}
+return 'a';
+  }
+
+  template
+  double foo(T t) requires AtLeast1 && sizeof(T) <= 2 {
+return 'a';
+  }
+
+  void bar() {
+static_assert(is_same_v); // expected-error {{call to 'foo' is ambiguous}}
+static_assert(is_same_v);
+  }
+}
+
+namespace non_template
+{
+  template
+  concept AtLeast2 = sizeof(T) >= 2;
+
+  template
+  concept AtMost8 = sizeof(T) <= 8;
+
+  int foo() requires AtLeast2 && AtMost8 {
+return 0;
+  }
+
+  double foo() requires AtLeast2 {
+return 0.0;
+  }
+
+  double baz() requires AtLeast2 && AtMost8 { // expected-note {{candidate function}}

[PATCH] D41910: [Concepts] Constrained partial specializations and function overloads.

2018-08-06 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 159331.
saar.raz added a comment.

- Fix bad handling of checking of deduced arguments in function templates


Repository:
  rC Clang

https://reviews.llvm.org/D41910

Files:
  include/clang/AST/DeclTemplate.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/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.normal/p1.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp

Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 4
+bool a = false; // expected-note{{template is declared here}}
+
+template requires sizeof(T) >= 4 && sizeof(T) <= 10
+bool a = true; // expected-error{{variable template partial specialization is not more specialized than the primary template}}
+
+template
+concept C1 = sizeof(T) >= 4;
+
+template requires C1
+bool b = false;
+
+template requires C1 && sizeof(T) <= 10
+bool b = true;
+
+template
+concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
+
+template
+bool c = false;
+
+template requires C1
+bool c = true;
+
+template
+bool d = false;
+
+template
+bool d = true; // expected-error{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+
+template requires C1
+bool e = false;
+
+template
+bool e = true; // expected-error{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+
+template
+constexpr int f = 1;
+
+template requires C1 && C2
+constexpr int f = 2;
+
+template requires C1 || C2
+constexpr int f = 3;
+
+static_assert(f == 2);
+static_assert(f == 3);
+static_assert(f == 1);
+
+
+
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 4
+bool a() { return false; } // expected-note {{candidate function [with T = unsigned int]}}
+
+template requires sizeof(T) >= 4 && sizeof(T) <= 10
+bool a() { return true; } // expected-note {{candidate function [with T = unsigned int]}}
+
+bool av = a(); // expected-error {{call to 'a' is ambiguous}}
+
+template
+concept C1 = sizeof(T) >= 4;
+
+template requires C1
+constexpr bool b() { return false; }
+
+template requires C1 && sizeof(T) <= 10
+constexpr bool b() { return true; }
+
+static_assert(b());
+static_assert(!b());
+
+template
+concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
+
+template
+bool c() { return false; }
+
+template requires C1
+bool c() { return true; }
+
+template requires C1
+constexpr bool d() { return false; }
+
+template
+constexpr bool d() { return true; }
+
+static_assert(!d());
+
+template
+constexpr int e() { return 1; }
+
+template requires C1 && C2
+constexpr int e() { return 2; }
+
+template requires C1 || C2
+constexpr int e() { return 3; }
+
+static_assert(e() == 2);
+static_assert(e() == 3);
+static_assert(e() == 1);
+
+
+
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 4
+class A{}; // expected-note{{template is declared here}}
+
+template requires sizeof(T) >= 4 && sizeof(T) <= 10
+class A{}; // expected-error{{class template partial specialization is not more specialized than the primary template}}
+
+template
+concept C1 = sizeof(T) >= 4;
+
+template requires C1
+class B{};
+
+template requires C1 && sizeof(T) <= 10
+class B{};
+
+template
+concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
+
+template
+class C{};
+
+template requires C1
+class C{};
+
+template
+class D{}; // 

[PATCH] D41910: [Concepts] Constrained partial specializations and function overloads.

2018-08-06 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 159323.
saar.raz added a comment.
Herald added a subscriber: jfb.

Adjusted to switch to ASTTemplateArgumentListInfo


Repository:
  rC Clang

https://reviews.llvm.org/D41910

Files:
  include/clang/AST/DeclTemplate.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/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.normal/p1.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp

Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/var-template-partial-specializations.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 4
+bool a = false; // expected-note{{template is declared here}}
+
+template requires sizeof(T) >= 4 && sizeof(T) <= 10
+bool a = true; // expected-error{{variable template partial specialization is not more specialized than the primary template}}
+
+template
+concept C1 = sizeof(T) >= 4;
+
+template requires C1
+bool b = false;
+
+template requires C1 && sizeof(T) <= 10
+bool b = true;
+
+template
+concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
+
+template
+bool c = false;
+
+template requires C1
+bool c = true;
+
+template
+bool d = false;
+
+template
+bool d = true; // expected-error{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+
+template requires C1
+bool e = false;
+
+template
+bool e = true; // expected-error{{variable template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+
+template
+constexpr int f = 1;
+
+template requires C1 && C2
+constexpr int f = 2;
+
+template requires C1 || C2
+constexpr int f = 3;
+
+static_assert(f == 2);
+static_assert(f == 3);
+static_assert(f == 1);
+
+
+
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/function-templates.cpp
@@ -0,0 +1,54 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 4
+bool a() { return false; } // expected-note {{candidate function [with T = unsigned int]}}
+
+template requires sizeof(T) >= 4 && sizeof(T) <= 10
+bool a() { return true; } // expected-note {{candidate function [with T = unsigned int]}}
+
+bool av = a(); // expected-error {{call to 'a' is ambiguous}}
+
+template
+concept C1 = sizeof(T) >= 4;
+
+template requires C1
+constexpr bool b() { return false; }
+
+template requires C1 && sizeof(T) <= 10
+constexpr bool b() { return true; }
+
+static_assert(b());
+static_assert(!b());
+
+template
+concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
+
+template
+bool c() { return false; }
+
+template requires C1
+bool c() { return true; }
+
+template requires C1
+constexpr bool d() { return false; }
+
+template
+constexpr bool d() { return true; }
+
+static_assert(!d());
+
+template
+constexpr int e() { return 1; }
+
+template requires C1 && C2
+constexpr int e() { return 2; }
+
+template requires C1 || C2
+constexpr int e() { return 3; }
+
+static_assert(e() == 2);
+static_assert(e() == 3);
+static_assert(e() == 1);
+
+
+
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.cpp
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 4
+class A{}; // expected-note{{template is declared here}}
+
+template requires sizeof(T) >= 4 && sizeof(T) <= 10
+class A{}; // expected-error{{class template partial specialization is not more specialized than the primary template}}
+
+template
+concept C1 = sizeof(T) >= 4;
+
+template requires C1
+class B{};
+
+template requires C1 && sizeof(T) <= 10
+class B{};
+
+template
+concept C2 = sizeof(T) > 1 && sizeof(T) <= 8;
+
+template
+class C{};
+
+template requires C1
+class C{};
+
+template
+class D{}; // 

[PATCH] D41569: [Concepts] Constraint enforcement and diagnostics

2018-08-05 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 159242.
saar.raz added a comment.
Herald added a subscriber: jfb.

- Adjusted to switch to ASTTemplateArgumentList


Repository:
  rC Clang

https://reviews.llvm.org/D41569

Files:
  include/clang/AST/ExprCXX.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  include/clang/Sema/SemaConcept.h
  include/clang/Sema/TemplateDeduction.h
  lib/AST/ExprCXX.cpp
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
  
test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp

Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/partial-specializations.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+namespace class_templates
+{
+  template requires sizeof(T) >= 4 // expected-note {{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}}
+  struct is_same { static constexpr bool value = false; };
+
+  template requires sizeof(T*) >= 4 && sizeof(T) >= 4
+  struct is_same { static constexpr bool value = true; };
+
+  static_assert(!is_same::value);
+  static_assert(!is_same::value);
+  static_assert(is_same::value);
+  static_assert(is_same::value); // expected-error {{constraints not satisfied for class template 'is_same' [with T = char, U = char]}}
+}
+
+namespace variable_templates
+{
+  template requires sizeof(T) >= 4
+  constexpr bool is_same_v = false;
+
+  template requires sizeof(T*) >= 4 && sizeof(T) >= 4
+  constexpr bool is_same_v = true;
+
+  static_assert(!is_same_v);
+  static_assert(!is_same_v);
+  static_assert(is_same_v);
+}
\ No newline at end of file
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/non-function-templates.cpp
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 2 // expected-note{{because 'sizeof(char) >= 2' (1 >= 2) evaluated to false}}
+struct A {
+  static constexpr int value = sizeof(T);
+};
+
+static_assert(A::value == 4);
+static_assert(A::value == 1); // expected-error{{constraints not satisfied for class template 'A' [with T = char]}}
+
+template
+  requires sizeof(T) != sizeof(U) // expected-note{{because 'sizeof(int) != sizeof(char [4])' (4 != 4) evaluated to false}}
+   && sizeof(T) >= 4 // expected-note{{because 'sizeof(char) >= 4' (1 >= 4) evaluated to false}}
+constexpr int SizeDiff = sizeof(T) > sizeof(U) ? sizeof(T) - sizeof(U) : sizeof(U) - sizeof(T);
+
+static_assert(SizeDiff == 3);
+static_assert(SizeDiff == 0); // expected-error{{constraints not satisfied for variable template 'SizeDiff' [with T = int, U = char [4]]}}
+static_assert(SizeDiff == 3); // expected-error{{constraints not satisfied for variable template 'SizeDiff' [with T = char, U = int]}}
+
+template
+  requires ((sizeof(Ts) == 4) || ...) // expected-note{{because 'sizeof(char) == 4' (1 == 4) evaluated to false}} expected-note{{'sizeof(long long) == 4' (8 == 4) evaluated to false}} expected-note{{'sizeof(int [20]) == 4' (80 == 4) evaluated to false}}
+constexpr auto SumSizes = (sizeof(Ts) + ...);
+
+static_assert(SumSizes == 13);
+static_assert(SumSizes == 89); // expected-error{{constraints not satisfied for variable template 'SumSizes' [with Ts = ]}}
+
+template
+concept IsBig = sizeof(T) > 100; // expected-note{{because 'sizeof(int) > 100' (4 > 100) evaluated to false}}
+
+template
+  requires IsBig // expected-note{{'int' does not satisfy 'IsBig'}}
+using BigPtr = T*;
+
+static_assert(sizeof(BigPtr)); // expected-error{{constraints not satisfied for alias template 'BigPtr' [with T = int]
+
+template requires T::value // expected-note{{because substituted constraint expression is ill-formed: type 'int' cannot be used prior to '::' because it has no members}}
+struct S { static constexpr bool value = true; };
+
+struct S2 { static constexpr bool value = true; };
+
+static_assert(S::value); // expected-error{{constraints not satisfied for class template 'S' [with T = int]}}
+static_assert(S::value);
+
+template
+struct AA
+{
+template requires sizeof(U) == sizeof(T) // expected-note{{because 'sizeof(int [2]) == sizeof(int)' (8 == 4) evaluated to false}}
+struct B
+{
+static constexpr int a = 0;
+};
+
+

[PATCH] D41284: [Concepts] Associated constraints infrastructure.

2018-08-05 Thread Saar Raz via Phabricator via cfe-commits
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] D41217: [Concepts] Concept Specialization Expressions

2018-08-05 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 159234.
saar.raz added a comment.
Herald added a subscriber: jfb.

- Switch to ASTTemplateArgumentListInfo, add ConstantEvaluated context when 
parsing constraints


Repository:
  rC Clang

https://reviews.llvm.org/D41217

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/StmtNodes.td
  include/clang/Sema/Sema.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/Expr.cpp
  lib/AST/ExprCXX.cpp
  lib/AST/ExprClassification.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/Parse/ParseExpr.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Sema/CMakeLists.txt
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaExceptionSpec.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  test/Parser/cxx-concept-declaration.cpp
  tools/libclang/CXCursor.cpp

Index: tools/libclang/CXCursor.cpp
===
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -231,6 +231,7 @@
   case Stmt::TypeTraitExprClass:
   case Stmt::CoroutineBodyStmtClass:
   case Stmt::CoawaitExprClass:
+  case Stmt::ConceptSpecializationExprClass:
   case Stmt::DependentCoawaitExprClass:
   case Stmt::CoreturnStmtClass:
   case Stmt::CoyieldExprClass:
Index: test/Parser/cxx-concept-declaration.cpp
===
--- test/Parser/cxx-concept-declaration.cpp
+++ test/Parser/cxx-concept-declaration.cpp
@@ -9,8 +9,6 @@
 
 template concept D1 = true; // expected-error {{expected template parameter}}
 
-template concept C2 = 0.f; // expected-error {{constraint expression must be 'bool'}}
-
 struct S1 {
   template concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}}
 };
@@ -29,3 +27,22 @@
 
 // TODO: Add test to prevent explicit specialization, partial specialization
 // and explicit instantiation of concepts.
+
+template concept C7 = 2; // expected-error {{atomic constraint '2' must be of type 'bool' (found 'int')}}
+template concept C8 = 2 && x; // expected-error {{atomic constraint '2' must be of type 'bool' (found 'int')}}
+template concept C9 = x || 2 || x; // expected-error {{atomic constraint '2' must be of type 'bool' (found 'int')}}
+template concept C10 = 8ull && x || x; // expected-error {{atomic constraint '8ULL' must be of type 'bool' (found 'unsigned long long')}}
+template concept C11 = sizeof(T); // expected-error {{atomic constraint 'sizeof(T)' must be of type 'bool' (found 'unsigned long')}}
+template concept C12 = T{};
+template concept C13 = (bool&&)true;
+template concept C14 = (const bool&)true;
+template concept C15 = (const bool)true;
+
+template
+struct integral_constant { static constexpr T value = v; };
+
+template  concept C16 = integral_constant::value && true;
+template  concept C17 = integral_constant::value;
+
+bool a = C16;
+bool b = C17;
Index: test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
===
--- test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
+++ test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
@@ -1,5 +1,111 @@
 // RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
-// expected-no-diagnostics
 
-template concept C = true;
-static_assert(C);
+template concept C1 = true;
+static_assert(C1);
+
+template concept C2 = sizeof(T) == 4;
+static_assert(C2);
+static_assert(!C2);
+static_assert(C2);
+static_assert(!C2);
+
+template concept C3 = sizeof(*T{}) == 4;
+static_assert(C3);
+static_assert(!C3);
+
+struct A {
+static constexpr int add(int a, int b) {
+return a + b;
+}
+};
+struct B {
+static int add(int a, int b) {
+return a + b;
+}
+};
+template
+concept C4 = U::add(1, 2) == 3; // expected-error {{substitution into constraint expression resulted in a non-constant expression 'B::add(1, 2) == 3'}}
+static_assert(C4);
+static_assert(!C4); // expected-note {{in concept specialization 'C4'}}
+
+template
+constexpr bool is_same_v = false;
+
+template
+constexpr bool is_same_v = true;
+
+template
+concept Same = is_same_v;
+
+static_assert(Same);
+static_assert(Same);
+static_assert(!Same);
+static_assert(!Same);
+static_assert(Same);
+
+static_assert(Same)>);
+static_assert(Same)>);
+static_assert(Same)>);
+static_assert(Same)>);
+
+template concept C5 = T{}; // expected-error {{atomic constraint 'int{}' must be of type 'bool' (found 'int')}}
+constexpr bool x = C5; // expected-note {{in concept specialization 'C5'}}
+
+template
+concept IsEven = (x % 

[PATCH] D44352: [Concepts] Constrained template parameters

2018-05-16 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 147190.
saar.raz added a comment.

Adjusted to changes in dependent patches.


Repository:
  rC Clang

https://reviews.llvm.org/D44352

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/AST/TemplateBase.h
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Parse/Parser.h
  include/clang/Sema/Sema.h
  lib/AST/ASTContext.cpp
  lib/AST/ASTDumper.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/DeclTemplate.cpp
  lib/AST/ODRHash.cpp
  lib/Parse/ParseExprCXX.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Sema/SemaCXXScopeSpec.cpp
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateDeduction.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.param/p10.cpp
  test/Parser/cxx-constrained-template-param-with-partial-id.cpp
  test/Parser/cxx-constrained-template-param.cpp
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -750,6 +750,10 @@
 }
 
 bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
+  if (Expr *CE = D->getConstraintExpression())
+if (Visit(MakeCXCursor(CE, StmtParent, TU, RegionOfInterest)))
+  return true;
+
   // Visit the default argument.
   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
 if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
@@ -898,6 +902,10 @@
 bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
   if (VisitDeclaratorDecl(D))
 return true;
+
+  if (Expr *CE = D->getConstraintExpression())
+if (Visit(MakeCXCursor(CE, StmtParent, TU, RegionOfInterest)))
+  return true;
   
   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
 if (Expr *DefArg = D->getDefaultArgument())
@@ -929,7 +937,11 @@
 bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
   if (VisitTemplateParameters(D->getTemplateParameters()))
 return true;
-  
+
+  if (Expr *CE = D->getConstraintExpression())
+if (Visit(MakeCXCursor(CE, StmtParent, TU, RegionOfInterest)))
+  return true;
+
   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
   VisitTemplateArgumentLoc(D->getDefaultArgument()))
 return true;
Index: test/Parser/cxx-constrained-template-param.cpp
===
--- /dev/null
+++ test/Parser/cxx-constrained-template-param.cpp
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ %s -verify
+// expected-no-diagnostics
+
+namespace type
+{
+  template
+  concept C1 = true;
+
+  template
+  using A = T[10];
+
+  using a = A;
+
+  namespace ns {
+template
+concept C2 = true;
+  }
+
+  template requires sizeof(T1) <= sizeof(T2)
+  struct B { };
+
+  using b = B;
+
+  template
+  struct C { };
+
+  using c1 = C;
+  using c2 = C;
+}
+
+namespace non_type
+{
+  template
+  concept C1 = true;
+
+  template
+  int A = v;
+
+  int& a = A<1>;
+
+  namespace ns {
+template
+concept C2 = true;
+  }
+
+  template requires sizeof(v1) <= sizeof(v2)
+  struct B { };
+
+  using b = B;
+
+  template
+  struct C { };
+
+  using c1 = C;
+  using c2 = C;
+}
+
+namespace temp
+{
+  template
+  struct test1 { };
+
+  template
+  struct test2 { };
+
+  template