[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{}; // expected-n

[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{}; // expected-note{{pre

[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] 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] 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] 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] 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] 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{}; // expected-note{{previ

[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
+constexp

[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>
+conc

[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-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)>);
+static_assert(Same)>)

[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] 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> requ

[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)>);
+static_assert(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] 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
+
+temp

[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] 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] 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 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;
+
+static_a

[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] 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] D41910: [Concepts] Constrained partial specializations and function overloads.

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

- Adjusted constraint normalization to piecewise constraint substitution
- Normalized constraints are now represented as described in the standard (a 
non-substituted expression along with a list of "template arguments").


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
+con

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

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

- Fixed handling of empty/non-expression after trailing requires keyword.
- Unified satisfaction check for templated/non-templated constraint exprs


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() req

[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 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}}
+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)
+struct badB { };
+
+template T1, ::ns::C2 T2>
+  requires sizeof(T1) <= sizeof(T2)
+struct B { };
+
+using b = B;
+
+template // expected-error {{concept 'C2' requires more than 1 template argument; provide the 

[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] 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] 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;
+};
+
+temp

[PATCH] D41217: [Concepts] Concept Specialization Expressions

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

- Addressed comments: Added semantic tests for value and template concepts, 
removed extra period and modified CSE ctor to fit in nicer.


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/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,12 @@
 
 // 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;
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,69 @@
 // 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;
+static_assert(C4);
+static_assert(!C4); // expected-error {{concept specialization 'C4' resulted in a non-constant expression 'B::add(1, 2) == 3'}}
+
+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 % 2) == 0;
+
+static_assert(IsEven<20>);
+static_assert(!IsEven<11>);
+
+template typename P>
+concept IsTypePredicate = is_same_v::value), const bool>
+  && is_same_v::value), const bool>
+  && is_same_v::value), const bool>;
+
+template struct T1 {};
+template struct T2 { static constexpr bool value

[PATCH] D43357: Function trailing requires clauses now parsed, supported in overload resolution and when calling, referencing and taking the address of functions or function templates.Does not directl

2018-02-15 Thread Saar Raz via Phabricator via cfe-commits
saar.raz created this revision.
saar.raz added reviewers: nwilson, hubert.reinterpretcast, changyu, rsmith, 
faisalv, Quuxplusone.
Herald added a subscriber: cfe-commits.

Depends on https://reviews.llvm.org/D41910.


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/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 { // ex

[PATCH] D41217: [Concepts] Concept Specialization Expressions

2017-12-13 Thread Saar Raz via Phabricator via cfe-commits
saar.raz created this revision.
saar.raz added reviewers: changyu, rsmith, hubert.reinterpretcast, nwilson.
Herald added a subscriber: cfe-commits.

Part of the P0734r0 Concepts implementation effort. Added Concept 
Specialization Expressions and tests thereof. Also added constraint expression 
type verification. This diff depends on https://reviews.llvm.org/D40381.


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/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,12 @@
 
 // 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;
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,52 @@
 // 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;
+static_assert(C4);
+static_assert(!C4); // expected-error {{concept specialization 'C4' resulted in a non-constant expression 'B::add(1, 2) == 3'}}
+
+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'}}
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1018,6 +1018,7 @@
 case Stmt::CUDAKernelCallExprClass:
 case Stmt:

[PATCH] D41217: [Concepts] Concept Specialization Expressions

2017-12-14 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 126950.
saar.raz added a comment.

- Fixed indentation problems


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/DeclNodes.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/StmtNodes.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/DeclTemplate.cpp
  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/CGDecl.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Parse/ParseExpr.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Sema/SemaExceptionSpec.cpp
  lib/Sema/SemaExprCXX.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.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/CIndex.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: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -5951,6 +5951,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-concept-declaration.cpp
===
--- test/Parser/cxx-concept-declaration.cpp
+++ test/Parser/cxx-concept-declaration.cpp
@@ -1,7 +1,38 @@
 
 // Support parsing of concepts
-// Disabled for now.
-// expected-no-diagnostics
 
-// RUN:  %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
-// template concept C1 = true;
+// RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
+template concept C1 = true;
+
+// TODO: Following line should fail.
+template concept C1 = true;
+
+template concept D1 = true; // expected-error {{expected template parameter}}
+
+struct S1 {
+  template concept C1 = true; // expected-error {{concept declarations may only appear in global or namespace scope}}
+};
+
+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}}
+
+// TODO: Last of the following two lines should fail.
+struct C6 {};
+template concept C6 = true;
+
+// 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;
Index: test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
@@ -0,0 +1,52 @@
+// RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
+
+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)

[PATCH] D41217: [Concepts] Concept Specialization Expressions

2017-12-14 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 126953.
saar.raz added a comment.

Previous updated diff mistakenly included https://reviews.llvm.org/D40381, 
fixed that.


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/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,12 @@
 
 // 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;
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,52 @@
 // 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;
+static_assert(C4);
+static_assert(!C4); // expected-error {{concept specialization 'C4' resulted in a non-constant expression 'B::add(1, 2) == 3'}}
+
+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'}}
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1018,6 +1018,7 @@
 case Stmt::CUDAKernelCallExprClass:
 case Stmt::OpaqueValueExprClass:
 case Stmt::AsTypeExprClass:
+case Stmt::ConceptSpecializationExprClass:
   // Fall through.
 
 // Cases we intentionally don't evaluate, since they don't need
Index: l

[PATCH] D41217: [Concepts] Concept Specialization Expressions

2017-12-14 Thread Saar Raz via Phabricator via cfe-commits
saar.raz marked 2 inline comments as done.
saar.raz added a comment.

Fixed indentations.


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] D41284: Associated constraint infrastructure.

2017-12-15 Thread Saar Raz via Phabricator via cfe-commits
saar.raz created this revision.
saar.raz added reviewers: changyu, hubert.reinterpretcast, rsmith, nwilson.
Herald added a subscriber: cfe-commits.

Added code to correctly calculate the associated constraints of a template. 
Depends on https://reviews.llvm.org/D41217.


Repository:
  rC Clang

https://reviews.llvm.org/D41284

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/RecursiveASTVisitor.h
  lib/AST/DeclTemplate.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp

Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -1402,6 +1402,12 @@
 Record.AddDeclRef(D->getInstantiatedFromMemberTemplate());
 if (D->getInstantiatedFromMemberTemplate())
   Record.push_back(D->isMemberSpecialization());
+
+Expr *AssociatedConstraints = D->getAssociatedConstraints();
+Record.push_back(AssociatedConstraints != nullptr);
+if (AssociatedConstraints) {
+  Record.AddStmt(AssociatedConstraints);
+}
   }
   
   VisitTemplateDecl(D);
@@ -1463,6 +1469,11 @@
   if (D->getPreviousDecl() == nullptr) {
 Record.AddDeclRef(D->getInstantiatedFromMember());
 Record.push_back(D->isMemberSpecialization());
+Expr *AssociatedConstraints = D->getAssociatedConstraints();
+Record.push_back(AssociatedConstraints != nullptr);
+if (AssociatedConstraints) {
+  Record.AddStmt(AssociatedConstraints);
+}
   }
 
   Code = serialization::DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION;
@@ -1523,6 +1534,11 @@
   if (D->getPreviousDecl() == nullptr) {
 Record.AddDeclRef(D->getInstantiatedFromMember());
 Record.push_back(D->isMemberSpecialization());
+Expr *AssociatedConstraints = D->getAssociatedConstraints();
+Record.push_back(AssociatedConstraints != nullptr);
+if (AssociatedConstraints) {
+  Record.AddStmt(AssociatedConstraints);
+}
   }
 
   Code = serialization::DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION;
Index: lib/Serialization/ASTWriter.cpp
===
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -5850,10 +5850,16 @@
   AddSourceLocation(TemplateParams->getTemplateLoc());
   AddSourceLocation(TemplateParams->getLAngleLoc());
   AddSourceLocation(TemplateParams->getRAngleLoc());
-  // TODO: Concepts
+
   Record->push_back(TemplateParams->size());
   for (const auto &P : *TemplateParams)
-AddDeclRef(P);
+AddDeclRef(P); // TODO: Concepts - constrained parameters.
+  if (const Expr *RequiresClause = TemplateParams->getRequiresClause()) {
+Record->push_back(true);
+AddStmt(const_cast(RequiresClause));
+  } else {
+Record->push_back(false);
+  }
 }
 
 /// \brief Emit a template argument list.
Index: lib/Serialization/ASTReaderDecl.cpp
===
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -1965,7 +1965,6 @@
   DeclID PatternID = ReadDeclID();
   NamedDecl *TemplatedDecl = cast_or_null(Reader.GetDecl(PatternID));
   TemplateParameterList *TemplateParams = Record.readTemplateParameterList();
-  // FIXME handle associated constraints
   D->init(TemplatedDecl, TemplateParams);
 
   return PatternID;
@@ -1991,6 +1990,7 @@
 
   // If this is the first declaration of the template, fill in the information
   // for the 'common' pointer.
+  Expr *AssociatedConstraints = nullptr;
   if (ThisDeclID == Redecl.getFirstID()) {
 if (RedeclarableTemplateDecl *RTD
   = ReadDeclAs()) {
@@ -2000,11 +2000,23 @@
   if (Record.readInt())
 D->setMemberSpecialization();
 }
+bool HasAssociatedConstraints = Record.readInt();
+if (HasAssociatedConstraints) {
+   AssociatedConstraints = Record.readExpr();
+}
   }
 
   DeclID PatternID = VisitTemplateDecl(D);
   D->IdentifierNamespace = Record.readInt();
 
+  D->TemplateParams.setInt(true);
+  if (AssociatedConstraints) {
+auto *CTDI = new (Reader.getContext()) ConstrainedTemplateDeclInfo;
+CTDI->setTemplateParameters(D->getTemplateParameters());
+CTDI->setAssociatedConstraints(AssociatedConstraints);
+D->TemplateParams.setPointer(CTDI);
+  }
+
   mergeRedeclarable(D, Redecl, PatternID);
 
   // If we merged the template with a prior declaration chain, merge the common
@@ -2132,14 +2144,24 @@
 ClassTemplatePartialSpecializationDecl *D) {
   RedeclarableResult Redecl = VisitClassTemplateSpecializationDeclImpl(D);
 
-  D->TemplateParams = Record.readTemplateParameterList();
+  TemplateParameterList *Params = Record.readTemplateParameterList();
+  D->TemplateParams.setPointer(Params);
   D->ArgsAsWritten = Record.readASTTemplateArgumentListInf

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

2017-12-15 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 127163.
saar.raz added a comment.

- Added requires clause matching for all kinds of template redeclarations 
instead of just classes.


Repository:
  rC Clang

https://reviews.llvm.org/D41284

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Sema/Sema.h
  lib/AST/DeclTemplate.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp

Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+namespace nodiag {
+
+struct B {
+template  requires bool(T())
+static int A;
+};
+
+template  requires bool(U())
+int B::A = int(U());
+
+} // end namespace nodiag
+
+namespace diag {
+
+struct B {
+template  requires bool(T()) // expected-note{{previous template declaration is here}}
+static int A;
+};
+
+template  requires !bool(U())  // expected-error{{associated constraints differ in template redeclaration}}
+int B::A = int(U());
+
+} // end namespace diag
\ No newline at end of file
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
===
--- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
@@ -1,65 +1,52 @@
-// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
 
 namespace nodiag {
 
 template  requires bool(T())
-struct A;
+int A();
 template  requires bool(U())
-struct A;
+int A();
 
 } // end namespace nodiag
 
 namespace diag {
 
 template  requires true // expected-note{{previous template declaration is here}}
-struct A;
-template  struct A; // expected-error{{associated constraints differ in template redeclaration}}
+int A();
+template  int A(); // expected-error{{associated constraints differ in template redeclaration}}
 
-template  struct B; // expected-note{{previous template declaration is here}}
+template  int B(); // expected-note{{previous template declaration is here}}
 template  requires true // expected-error{{associated constraints differ in template redeclaration}}
-struct B;
+int B();
 
 template  requires true // expected-note{{previous template declaration is here}}
-struct C;
+int C();
 template  requires !0 // expected-error{{associated constraints differ in template redeclaration}}
-struct C;
+int C();
 
 } // end namespace diag
 
 namespace nodiag {
 
 struct AA {
   template  requires someFunc(T())
-  struct A;
+  int A();
 };
 
 template  requires someFunc(T())
-struct AA::A { };
-
-struct AAF {
-  template  requires someFunc(T())
-  friend struct AA::A;
-};
+int AA::A() { return sizeof(T); }
 
 } // end namespace nodiag
 
 namespace diag {
 
 template 
 struct TA {
-  template  class TT> requires TT::happy // expected-note 2{{previous template declaration is here}}
-  struct A;
-
-  struct AF;
+  template  class TT> requires TT::happy // expected-note{{previous template declaration is here}}
+  int A();
 };
 
 template 
-template  class TT> struct TA::A { }; // expected-error{{associated constraints differ in template redeclaration}}
-
-template 
-struct TA::AF {
-  template  class TT> requires TT::happy // expected-error{{associated constraints differ in template redeclaration}}
-  friend struct TA::A;
-};
+template  class TT> int TA::A() { return sizeof(TT); } // expected-error{{associated constraints differ in template redeclaration}}
 
 } // end namespace diag
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
===
--- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
 
 namespace nodiag {
 
@@ -33,7 +33,7 @@
   struct A;
 };
 
-template  requires someFunc(T())
+template  requires someFunc(U())
 struct AA::A { };
 
 struct AAF {
@@ -47,18 +47,26 @@
 
 template 
 struct TA {
-  template  class TT> requires TT::happy // expected-note 2{{previous template declaration is here}}
+  template  class TT> r

[PATCH] D41217: [Concepts] Concept Specialization Expressions

2017-12-17 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added inline comments.



Comment at: lib/Parse/ParseExpr.cpp:223
 ExprResult Parser::ParseConstraintExpression() {
-  // FIXME: this may erroneously consume a function-body as the braced
-  // initializer list of a compound literal
-  //
-  // FIXME: this may erroneously consume a parenthesized rvalue reference
-  // declarator as a parenthesized address-of-label expression
-  ExprResult LHS(ParseCastExpression(/*isUnaryExpression=*/false));
-  ExprResult Res(ParseRHSOfBinaryExpression(LHS, prec::LogicalOr));
-
+  ExprResult Res(ParseExpression());
+  if (Res.isUsable() && !Actions.CheckConstraintExpression(Res.get())) {

faisalv wrote:
> Are you sure this only accepts logical-or-epxressions? Unlike Hubert's 
> initial implementation here, this seems to parse any expression (i.e 
> including unparenthesized commas and assignments)? What am I missing?
> 
Mm.. Good point, I was under the false assumption that this was equivalent - 
I'll fix it back, thanks :) 


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] D40381: Parse concept definition

2017-12-17 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added inline comments.



Comment at: lib/Sema/SemaTemplate.cpp:3899
+  // constraint expressions right now.
+  return Template->getConstraintExpr();
+}

faisalv wrote:
> I don't think we want to just return the constraint expr? I think we would 
> need to create another conceptspecializationDecl node and nest it within a 
> DeclRefExpr?  But once again, I think we should defer this to another patch - 
> no?
This was meant as a placeholder. The next patch (D41217) replaces this 
function, I don't think it is that much of a big deal what happens here in this 
patch.



Comment at: lib/Sema/SemaTemplate.cpp:7713
+
+  if (!ConstraintExpr->isTypeDependent() &&
+  ConstraintExpr->getType() != Context.BoolTy) {

faisalv wrote:
> Consider refactoring these checks on constraint expressions into a separate 
> function checkConstraintExpression (that we can also call from other contexts 
> such as requires-clauses and nested requires expressions)?
I did that in the upcoming patches, no need to do it here as well.


https://reviews.llvm.org/D40381



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


[PATCH] D41569: Summary:Constraint enforcement and diagnostics

2017-12-24 Thread Saar Raz via Phabricator via cfe-commits
saar.raz created this revision.
saar.raz added reviewers: hubert.reinterpretcast, rsmith, nwilson, changyu, 
faisalv.
Herald added a subscriber: cfe-commits.

- Associated constraints (requires clauses, currently) are now enforced when 
instantiating/specializing templates and when considering partial 
specializations and function overloads.
- Elaborated diagnostics give helpful insight as to why the constraints were 
not satisfied.

This patch depends upon https://reviews.llvm.org/D41284


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/TemplateDeduction.h
  lib/AST/ExprCXX.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 {{'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], because:}}
+}
+
+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,42 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+template requires sizeof(T) >= 2 // expected-note{{'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], because:}}
+
+template
+  requires sizeof(T) != sizeof(U) // expected-note{{'sizeof(int) != sizeof(char [4])' (4 != 4) evaluated to false}}
+   && sizeof(T) >= 4 // expected-note{{'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]], because:}}
+static_assert(SizeDiff == 3); // expected-error{{constraints not satisfied for variable template 'SizeDiff' [with T = char, U = int], because:}}
+
+template
+  requires ((sizeof(Ts) == 4) || ...) // expected-note{{'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 = ], because:}}
+
+template
+concept IsBig = sizeof(T) > 100; // expected-note{{'sizeof(int) > 100' (4 > 100) evaluated to false}}
+
+template
+  requires IsBig // expected-note{{'int' does not satisfy 'IsBig', because:}}
+using BigPtr = T*;
+
+static_assert(sizeof(BigPtr)); // expected-error{{constraints not satisfied for alias template 'BigPtr' [with T = int], because:
+
+template requires T::value // expected-note{{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 te

[PATCH] D41217: [Concepts] Concept Specialization Expressions

2017-12-24 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 128121.
saar.raz added a comment.

Reverted to original constraint parsing code.


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/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,12 @@
 
 // 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;
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,52 @@
 // 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;
+static_assert(C4);
+static_assert(!C4); // expected-error {{concept specialization 'C4' resulted in a non-constant expression 'B::add(1, 2) == 3'}}
+
+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'}}
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1018,6 +1018,7 @@
 case Stmt::CUDAKernelCallExprClass:
 case Stmt::OpaqueValueExprClass:
 case Stmt::AsTypeExprClass:
+case Stmt::ConceptSpecializationExprClass:
   // Fall through.
 
 // Cases we intentionally don't evaluate, since they don't need
Index: lib/Serialization/ASTWriterStmt.cpp
===

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

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

- Fixed wrong if that would cause valid instantiated requires clauses to not be 
accepted.


Repository:
  rC Clang

https://reviews.llvm.org/D41284

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Sema/Sema.h
  lib/AST/DeclTemplate.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp

Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+namespace nodiag {
+
+struct B {
+template  requires bool(T())
+static int A;
+};
+
+template  requires bool(U())
+int B::A = int(U());
+
+} // end namespace nodiag
+
+namespace diag {
+
+struct B {
+template  requires bool(T()) // expected-note{{previous template declaration is here}}
+static int A;
+};
+
+template  requires !bool(U())  // expected-error{{associated constraints differ in template redeclaration}}
+int B::A = int(U());
+
+} // end namespace diag
\ No newline at end of file
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
===
--- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
@@ -1,65 +1,52 @@
-// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
 
 namespace nodiag {
 
 template  requires bool(T())
-struct A;
+int A();
 template  requires bool(U())
-struct A;
+int A();
 
 } // end namespace nodiag
 
 namespace diag {
 
 template  requires true // expected-note{{previous template declaration is here}}
-struct A;
-template  struct A; // expected-error{{associated constraints differ in template redeclaration}}
+int A();
+template  int A(); // expected-error{{associated constraints differ in template redeclaration}}
 
-template  struct B; // expected-note{{previous template declaration is here}}
+template  int B(); // expected-note{{previous template declaration is here}}
 template  requires true // expected-error{{associated constraints differ in template redeclaration}}
-struct B;
+int B();
 
 template  requires true // expected-note{{previous template declaration is here}}
-struct C;
+int C();
 template  requires !0 // expected-error{{associated constraints differ in template redeclaration}}
-struct C;
+int C();
 
 } // end namespace diag
 
 namespace nodiag {
 
 struct AA {
   template  requires someFunc(T())
-  struct A;
+  int A();
 };
 
 template  requires someFunc(T())
-struct AA::A { };
-
-struct AAF {
-  template  requires someFunc(T())
-  friend struct AA::A;
-};
+int AA::A() { return sizeof(T); }
 
 } // end namespace nodiag
 
 namespace diag {
 
 template 
 struct TA {
-  template  class TT> requires TT::happy // expected-note 2{{previous template declaration is here}}
-  struct A;
-
-  struct AF;
+  template  class TT> requires TT::happy // expected-note{{previous template declaration is here}}
+  int A();
 };
 
 template 
-template  class TT> struct TA::A { }; // expected-error{{associated constraints differ in template redeclaration}}
-
-template 
-struct TA::AF {
-  template  class TT> requires TT::happy // expected-error{{associated constraints differ in template redeclaration}}
-  friend struct TA::A;
-};
+template  class TT> int TA::A() { return sizeof(TT); } // expected-error{{associated constraints differ in template redeclaration}}
 
 } // end namespace diag
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
===
--- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
 
 namespace nodiag {
 
@@ -33,7 +33,7 @@
   struct A;
 };
 
-template  requires someFunc(T())
+template  requires someFunc(U())
 struct AA::A { };
 
 struct AAF {
@@ -47,18 +47,26 @@
 
 template 
 struct TA {
-  template  class TT> requires TT::happy // expected-note 2{{previous template declaration is here}}
+  template  class TT> requires T

[PATCH] D41569: Summary:Constraint enforcement and diagnostics

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

- Better handling of diagnostics in ConceptSpecializationExprs, correctly 
written to and read from module files.
- Modified Error messages according to some user feedback

Updating D41569: Summary:
=

Constraint enforcement and diagnostics


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/TemplateDeduction.h
  lib/AST/ExprCXX.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]) 

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

2018-01-10 Thread Saar Raz via Phabricator via cfe-commits
saar.raz created this revision.
saar.raz added reviewers: hubert.reinterpretcast, rsmith, nwilson, changyu, 
faisalv.
Herald added a subscriber: cfe-commits.

Added support for constraint satisfaction checking and partial ordering of 
constraints in constrained partial specialization and function template 
overloads. Depends on https://reviews.llvm.org/D41569.


Repository:
  rC Clang

https://reviews.llvm.org/D41910

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/Sema/Sema.h
  lib/AST/DeclTemplate.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.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,53 @@
+// 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
+clas

[PATCH] D40381: Parse concept definition

2018-03-10 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added inline comments.



Comment at: lib/Parse/ParseTemplate.cpp:161
   // Parse the actual template declaration.
-  return ParseSingleDeclarationAfterTemplate(Context,
- ParsedTemplateInfo(&ParamLists,
- isSpecialization,
- 
LastParamListWasEmpty),
- ParsingTemplateParams,
- DeclEnd, AS, AccessAttrs);
+  if (!TryConsumeToken(tok::kw_concept))
+return ParseSingleDeclarationAfterTemplate(Context,

Perhaps add a LangOpts.ConceptsTS check here?


https://reviews.llvm.org/D40381



___
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-03-10 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 137906.
saar.raz added a comment.

- Fixed incorrect checking of atomic constraint types.


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/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,69 @@
 // 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;
+static_assert(C4);
+static_assert(!C4); // expected-error {{concept specialization 'C4' resulted in a non-constant expression 'B::add(1, 2) == 3'}}
+
+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 % 2) == 0;
+
+static_assert(IsEven<20>);
+static_assert(!IsEven<11>);
+
+template typename P>
+concept IsTypePredicate = is_same_v::value), const bool>
+

[PATCH] D41569: Summary:Constraint enforcement and diagnostics

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

Fixed crash caused by substitution of pack expansion into non-pack parameters 
in constraint expressions.

Updating D41569: Summary:
=

Constraint enforcement and diagnostics


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/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 f

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

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

- Correct handling of non-substitutable concept specialization expressions.


Repository:
  rC Clang

https://reviews.llvm.org/D41910

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/Sema/Sema.h
  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.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,75 @@
+// 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{}; // expected-note{{previous definition is here}}
+
+template
+class D{}; // expected-error{{class template partial specialization does not specialize any te

[PATCH] D44352: [Concepts] Constrained template parameters

2018-03-10 Thread Saar Raz via Phabricator via cfe-commits
saar.raz created this revision.
saar.raz added reviewers: nwilson, hubert.reinterpretcast, changyu, rsmith, 
faisalv, Quuxplusone.
Herald added a subscriber: cfe-commits.

Added support for constrained template parameters, both simple and with partial 
template arguments. Depends on https://reviews.llvm.org/D43357.


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}}
+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)
+struct bad

[PATCH] D40381: Parse concept definition

2018-03-10 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added inline comments.



Comment at: lib/Parse/ParseTemplate.cpp:383
+
+  if (!Tok.is(tok::identifier)) {
+Diag(Tok.getLocation(), diag::err_expected) << tok::identifier;

We could accept 'bool' here to be nice to people coming in from the old 
Concepts TS version of these decls - and emit a proper warning.


https://reviews.llvm.org/D40381



___
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-03-14 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added inline comments.



Comment at: lib/AST/ExprCXX.cpp:1478
+  {
+// We do not want error diagnostics escaping here.
+Sema::SFINAETrap Trap(S);

faisalv wrote:
> Hubert: This needs a TODO: the idea is not to drop SFINAE errors, but to 
> avoid instantiation that may trigger errors not in the immediate context of 
> instantiation. The substitution needs to happen piecewise.
Could you elaborate/give an example where this handling is inappropriate?


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-03-14 Thread Saar Raz via Phabricator via cfe-commits
saar.raz updated this revision to Diff 138497.
saar.raz added a comment.

Addressed most comments.


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/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,69 @@
 // 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;
+static_assert(C4);
+static_assert(!C4); // expected-error {{concept specialization 'C4' resulted in a non-constant expression 'B::add(1, 2) == 3'}}
+
+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 % 2) == 0;
+
+static_assert(IsEven<20>);
+static_assert(!IsEven<11>);
+
+template typename P>
+concept IsTypePredicate = is_same_v::value), const bool>
+  && is_same_v::value), co

[PATCH] D41217: [Concepts] Concept Specialization Expressions

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

Applied missing clang-format.


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/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,69 @@
 // 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;
+static_assert(C4);
+static_assert(!C4); // expected-error {{concept specialization 'C4' resulted in a non-constant expression 'B::add(1, 2) == 3'}}
+
+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 % 2) == 0;
+
+static_assert(IsEven<20>);
+static_assert(!IsEven<11>);
+
+template typename P>
+concept IsTypePredicate = is_same_v::value), const bool>
+  && is_same_v::value

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

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

Fixed reference to TemplateParams member in assertion.


Repository:
  rC Clang

https://reviews.llvm.org/D41284

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Sema/Sema.h
  lib/AST/DeclTemplate.cpp
  lib/Sema/SemaConcept.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
  test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp

Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp
===
--- /dev/null
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/var-template-decl.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
+
+namespace nodiag {
+
+struct B {
+template  requires bool(T())
+static int A;
+};
+
+template  requires bool(U())
+int B::A = int(U());
+
+} // end namespace nodiag
+
+namespace diag {
+
+struct B {
+template  requires bool(T()) // expected-note{{previous template declaration is here}}
+static int A;
+};
+
+template  requires !bool(U())  // expected-error{{associated constraints differ in template redeclaration}}
+int B::A = int(U());
+
+} // end namespace diag
\ No newline at end of file
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
===
--- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
@@ -1,65 +1,52 @@
-// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
 
 namespace nodiag {
 
 template  requires bool(T())
-struct A;
+int A();
 template  requires bool(U())
-struct A;
+int A();
 
 } // end namespace nodiag
 
 namespace diag {
 
 template  requires true // expected-note{{previous template declaration is here}}
-struct A;
-template  struct A; // expected-error{{associated constraints differ in template redeclaration}}
+int A();
+template  int A(); // expected-error{{associated constraints differ in template redeclaration}}
 
-template  struct B; // expected-note{{previous template declaration is here}}
+template  int B(); // expected-note{{previous template declaration is here}}
 template  requires true // expected-error{{associated constraints differ in template redeclaration}}
-struct B;
+int B();
 
 template  requires true // expected-note{{previous template declaration is here}}
-struct C;
+int C();
 template  requires !0 // expected-error{{associated constraints differ in template redeclaration}}
-struct C;
+int C();
 
 } // end namespace diag
 
 namespace nodiag {
 
 struct AA {
   template  requires someFunc(T())
-  struct A;
+  int A();
 };
 
 template  requires someFunc(T())
-struct AA::A { };
-
-struct AAF {
-  template  requires someFunc(T())
-  friend struct AA::A;
-};
+int AA::A() { return sizeof(T); }
 
 } // end namespace nodiag
 
 namespace diag {
 
 template 
 struct TA {
-  template  class TT> requires TT::happy // expected-note 2{{previous template declaration is here}}
-  struct A;
-
-  struct AF;
+  template  class TT> requires TT::happy // expected-note{{previous template declaration is here}}
+  int A();
 };
 
 template 
-template  class TT> struct TA::A { }; // expected-error{{associated constraints differ in template redeclaration}}
-
-template 
-struct TA::AF {
-  template  class TT> requires TT::happy // expected-error{{associated constraints differ in template redeclaration}}
-  friend struct TA::A;
-};
+template  class TT> int TA::A() { return sizeof(TT); } // expected-error{{associated constraints differ in template redeclaration}}
 
 } // end namespace diag
Index: test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
===
--- test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.decl/class-template-decl.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++14 -fconcepts-ts -x c++ -verify %s
+// RUN: %clang_cc1 -std=c++2a -fconcepts-ts -x c++ -verify %s
 
 namespace nodiag {
 
@@ -33,7 +33,7 @@
   struct A;
 };
 
-template  requires someFunc(T())
+template  requires someFunc(U())
 struct AA::A { };
 
 struct AAF {
@@ -47,18 +47,26 @@
 
 template 
 struct TA {
-  template  class TT> requires TT::happy // expected-note 2{{previous template declaration is here}}
+  template  class TT> requires TT::happy 

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

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

Adjusted to changes in https://reviews.llvm.org/D41217


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/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;
+};
+
+template requires sizeof(U) == sizeof(T) // expected-note{{becau

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

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

Fixed SpecializedConcept reference to NamedConcept.


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/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;
+};
+
+template requires sizeof(U) == sizeof(T) // expected-note{{because 

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

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

Fixed another SpecializedConcept reference to NamedConcept.


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/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;
+};
+
+template requires sizeof(U) == sizeof(T) // expected-note{{

[PATCH] D44352: [Concepts] Constrained template parameters

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

Fixed test.


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}}
+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)
+struct badB { };
+
+template T1, ::ns::C2 T2>
+  requires sizeof(T1) <= sizeof(T2)
+struct B { };
+
+using b = B;
+
+template // expected-error {{concept 'C2' requires more than 1 template argument; provide the remaining arguments explicitly

[PATCH] D41217: [Concepts] Concept Specialization Expressions

2018-03-16 Thread Saar Raz via Phabricator via cfe-commits
saar.raz added inline comments.



Comment at: lib/AST/ExprCXX.cpp:1478
+  {
+// We do not want error diagnostics escaping here.
+Sema::SFINAETrap Trap(S);

hubert.reinterpretcast wrote:
> saar.raz wrote:
> > faisalv wrote:
> > > Hubert: This needs a TODO: the idea is not to drop SFINAE errors, but to 
> > > avoid instantiation that may trigger errors not in the immediate context 
> > > of instantiation. The substitution needs to happen piecewise.
> > Could you elaborate/give an example where this handling is inappropriate?
> Determining satisfaction requires normalization (lazy normalization should be 
> considered).
> The determination of satisfaction then proceeds by handling the left-hand 
> side of conjunction and disjunction constraints before possibly substituting 
> into the right-hand side; i.e., there is short-circuiting behaviour.
> 
> Example:
> ```
> template 
> concept C = true;
> 
> template 
> struct Q { static constexpr T value = nullptr; };
> 
> template 
> requires C || T::value
> struct A { };
> 
> template 
> requires C || Q::value
> struct B { };
> 
> A a; // okay
> B b; // okay
> ```
> 
OK I see your point. You said this should be a TODO - do you think this should 
be delayed to a further patch (namely D41569, where we actually deal with 
diagnostics and stuff)?
About lazy normalization, I tend to think it is not a good idea - you'll 
probably check satisfaction for every defined constraint expression at some 
point, and do that many more times than you'd define a new one


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] 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] 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 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)&T::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 (&t))) { } // expected-error {{called object type 'bool' is not a fu

[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}}
+
+temp

[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 = integral_const

[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] 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] 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 -s

[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
===
--- /dev

[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)&T::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 (&t))) { } // expected-error {{called object type 'bool' is not a function or function pointer}}
-};
Index: test/Parser/cxx2a-concept-declaration.cpp
=

[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;
 };
 
-t

[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
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.constr/non-function-templates.cpp

[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
+++ test/CXX/concepts-ts/temp/temp.constr/temp.constr.order/class-template-partial-specializations.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 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++ -v

[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] 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)&T::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 (&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-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] 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 constra

[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 'v1

[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 co

[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 constraint

[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 {
-  template

[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{} // exp

[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;
+
+  static_assert(v1)

[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{} // expected

[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] 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] 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] 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] 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] 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] 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] 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] D40381: Parse concept definition

2017-11-23 Thread Saar Raz via Phabricator via cfe-commits
saar.raz requested changes to this revision.
saar.raz added a comment.
This revision now requires changes to proceed.

Also add:
In ASTDumper

  +void VisitConceptTemplateDecl(const ConceptTemplateDecl *D);

Implementation:

  void ASTDumper::VisitConceptTemplateDecl(const ConceptTemplateDecl *D) {
dumpName(D);
dumpTemplateParameters(D->getTemplateParameters());
VisitExpr(D->getConstraintExpression());
  }

Address the other issues I've mentioned in the inline comments and we're good! 
Great job :)




Comment at: include/clang/AST/DeclTemplate.h:3023
+ Expr *ConstraintExpr);
+
+  Expr *getConstraintExpr() const {

Add CreateDeserialized.



Comment at: include/clang/AST/DeclTemplate.h:3027
+  }
+
+  // TODO: Should do source range properly.

Add setConstraintExpr (for use when calling CreateDeserialized, see 
ASTDeclReader)



Comment at: include/clang/Parse/Parser.h:2787
AccessSpecifier AS = AS_none);
+  // C++ 17: Template, concept definition [temp]
+  Decl *

C++2a



Comment at: lib/Parse/ParseTemplate.cpp:374
+
+  ExprResult ConstraintExpr = ParseConstraintExpression();
+

Add a check to ParseConstraintExpression that the type is either dependent or 
bool, and add an apropriate diagnostic.

```
if (!ConstraintExpr->isTypeDependent() && ConstraintExpr->getType() != 
Context.BoolTy) {
  Diag(Init->getSourceRange().getBegin(),
   diag::err_concept_initialized_with_non_bool_type) << Init->getType();
  Concept->setInvalidDecl();
  return;
}
```



Comment at: lib/Sema/SemaTemplate.cpp:2935
   if (!Template || isa(Template) ||
   isa(Template)) {
 // We might have a substituted template template parameter pack. If so,

Add

```
 || isa

```



Comment at: lib/Sema/SemaTemplate.cpp:3936
 
+  if (R.getAsSingle()) {
+return CheckConceptTemplateId(SS, R.getLookupNameInfo(),

We're gonna want to check
```
!TemplateSpecializationType::anyDependentTemplateArguments(*TemplateArgs, 
InstantiationDependent)
``` 
here as well - so that we can instantiate a ConceptSpecializationExpr later 
when we have it (we're not gonna want to instantiate a 
ConceptSpecializationExpr with dependent arguments.



Comment at: lib/Sema/SemaTemplate.cpp:7698
+
+  // TODO: Maybe we should check TemplateParameterLists for nullptr?
+  Decl *NewDecl = ConceptDecl::Create(Context, DC, L, Name,

Check that !DC->isFileContext() (Concepts may only be defined at namespace 
scope)



Comment at: lib/Sema/SemaTemplate.cpp:7700
+  Decl *NewDecl = ConceptDecl::Create(Context, DC, L, Name,
+  TemplateParameterLists[0],
+  ConstraintExpr);

I think it would be better to just check that TemplateParameterLists.size() != 
1 - it can't happen in a valid situation anyway, you'd want a diagnostic there.



Comment at: lib/Sema/SemaTemplate.cpp:7702
+  ConstraintExpr);
+  ActOnDocumentableDecl(NewDecl);
+  CurContext->addDecl(NewDecl);

Check that c->getAssociatedConstraints() == nullptr ([temp.concept]p4 A concept 
shall not have associated constraints).
Add a TODO to make a test for that once we have actual associated constraints.



Comment at: lib/Sema/SemaTemplateInstantiateDecl.cpp:3099
+Decl *TemplateDeclInstantiator::VisitConceptDecl(ConceptDecl *D) {
+  // TODO: Do something here?
+  return nullptr;

Yes - 

```
llvm_unreachable("Concept definitions cannot reside inside a template");
```



Comment at: lib/Serialization/ASTReaderDecl.cpp:1975
+void ASTDeclReader::VisitConceptDecl(ConceptDecl *D) {
+  VisitTemplateDecl(D);
+}

Add here:

```
  D->setConstraintExpression(Record.readExpr());
```
And in ASTDeclWriter, a method VisitConceptDecl:
```
void ASTDeclWriter::VisitConceptTemplateDecl(ConceptTemplateDecl *D) {
  VisitTemplateDecl(D);
  Record.AddStmt(D->getConstraintExpression());
  Code = serialization::DECL_CONCEPT;
}
```
And call it in the appropriate places.



Comment at: lib/Serialization/ASTReaderDecl.cpp:3503
 break;
   case DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION:
 D = ClassScopeFunctionSpecializationDecl::CreateDeserialized(Context, ID);

Add a case: DECL_CONCEPT, also create that enum member.


https://reviews.llvm.org/D40381



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


[PATCH] D40381: Parse concept definition

2017-11-24 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:1
+// RUN:  %clang_cc1 -std=c++1z -fconcepts-ts -fcxx-exceptions -x c++ -verify %s
+// expected-no-diagnostics

Rakete wrote:
> There is no `-fconcepts-ts` flag AFAIK. Also, why `-fcxx-exceptions`, it's 
> not needed here. The `-x c++` part too. It should also be `-std=c++2a`.
There is a -fconcepts-ts flag (clang -Xclang -fconcepts-ts), I believe now that 
there is no more Concepts TS the flag should be removed as well and all 
concepts-related code be put under C++2a ifs.


https://reviews.llvm.org/D40381



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


[PATCH] D40381: Parse concept definition

2017-11-24 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:1
+// RUN:  %clang_cc1 -std=c++1z -fconcepts-ts -fcxx-exceptions -x c++ -verify %s
+// expected-no-diagnostics

hubert.reinterpretcast wrote:
> saar.raz wrote:
> > Rakete wrote:
> > > There is no `-fconcepts-ts` flag AFAIK. Also, why `-fcxx-exceptions`, 
> > > it's not needed here. The `-x c++` part too. It should also be 
> > > `-std=c++2a`.
> > There is a -fconcepts-ts flag (clang -Xclang -fconcepts-ts), I believe now 
> > that there is no more Concepts TS the flag should be removed as well and 
> > all concepts-related code be put under C++2a ifs.
> This was discussed with Richard, Faisal, and Aaron Ballman before. We would 
> like to use -Xclang -fconcepts until there is enough of an implementation. 
> When we are ready, then we switch to having it directly under C++2a. There is 
> no reason why dealing with the option cannot be done as a separate patch, so 
> I don't think we need to hold up this one for that work.
OK, wasn't aware this was discussed before.
I agree then, leave the -fconcepts-ts for now.


https://reviews.llvm.org/D40381



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


[PATCH] D40381: Parse concept definition

2017-11-26 Thread Saar Raz via Phabricator via cfe-commits
saar.raz requested changes to this revision.
saar.raz added a comment.
This revision now requires changes to proceed.

Do the requested clang-formatting as shown by hubert, other than that looks 
good to me :)


https://reviews.llvm.org/D40381



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://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] 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] 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] 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 &Satisfaction) {
-  return ::CheckConstraintSatisfaction(*this, Template, ConstraintExprs,
-   TemplateArgs, TemplateIDRange,
-   Satisfaction);
-}
+bool Sema::CheckConstraintSatisfaction(
+NamedDecl *Template, ArrayRef ConstraintExprs,
+ArrayRef TemplateArgs, SourceRange TemplateIDRange,
+ConstraintSatisfaction &Satisfaction) {
+  if (ConstraintExprs.empty()) {
+Satisfaction.IsSatisfied = true;
+return false;
+  }
 
-bool
-Sema::CheckConstraintSatisfaction(ClassTemplatePartialSpecializationDecl* Part,
-  ArrayRef ConstraintExprs,
-  ArrayRef TemplateArgs,
-  SourceRange TemplateIDRange,
-  ConstraintSatisfaction &Satisfaction) {
-  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 &Satisfaction) {
-  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 *Cons

  1   2   >