[PATCH] D41217: [Concepts] Concept Specialization Expressions

2017-12-13 Thread changyu via Phabricator via cfe-commits
changyu added inline comments.



Comment at: lib/AST/ExprCXX.cpp:1481
+if (E.isInvalid() || Trap.hasErrorOccurred()) {
+// C++2a [temp.constr.atomic]p1
+//   ...If substitution results in an invalid type or expression, the

You have four spaces of indenting here.



Comment at: lib/Parse/ParseExpr.cpp:225
+  if (Res.isUsable() && !Actions.CheckConstraintExpression(Res.get())) {
+  return ExprError();
+  }

Indenting.


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-21 Thread changyu via Phabricator via cfe-commits
changyu marked 6 inline comments as done.
changyu added inline comments.



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

faisalv wrote:
> Why not use 'PushOnScopeChains' onto the enclosing scope?
> Something along these lines:
>assert(S->isTemplateParamScope() && S->getParent() && 
> !S->getParent()->isTemplateParamScope() && "...");
>PushOnScopeChains(NewDecl, S->getParent(),/*AddToContext*/true);
The condition
```
S->isTemplateParamScope()
```
fails in this case
```
template concept D1 = true; // expected-error {{expected template 
parameter}}
```

`ParseTemplateDeclarationOrSpecialization` calls `ParseTemplateParameters` 
which eventually calls `ParseNonTypeTemplateParameter`. 
`ParseNonTypeTemplateParameter` prints the diag and fails but does not cause 
`ParseTemplateParameters` to fail (I'm not sure why).  
`ParseTemplateDeclarationOrSpecialization` proceeds to parse the concept 
definition, and we get this

```
/home/changyu/test.cpp:1:10: error: expected template parameter
template concept D1 = true; // expected-error {{expected template 
parameter}}
 ^
clang: /home/changyu/git/llvm/tools/clang/lib/Sema/SemaTemplate.cpp:7747: 
clang::Decl* clang::Sema::ActOnConceptDefinition(clang::Scope*, 
clang::MultiTemplateParamsArg, clang::IdentifierInfo*, clang::SourceLocation, 
clang::Expr*): Assertion `S->isTemplateParamScope() && "Not in template param 
scope?"' failed.
```

What should we do?


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-12-23 Thread changyu via Phabricator via cfe-commits
changyu marked 27 inline comments as done.
changyu added inline comments.



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

faisalv wrote:
> saar.raz wrote:
> > 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.
> Once again - relying on a future patch (especially without a clear FIXME) to 
> tweak the architectural/factorization issues that you have been made aware of 
> (and especially those, such as this, that do not require too much effort), is 
> not practice I would generally encourage.  
> 
> So changyu, if you agree that these suggestions would improve the quality of 
> the patch and leave clang in a more robust state (maintenance-wise or 
> execution-wise), then please make the changes.  If not, please share your 
> thoughts as to why these suggestions would either not be an improvement or be 
> inconsistent with the theme of this patch.
> 
> Thanks!
I removed it here since Saar fixed it in his patch.


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-12-23 Thread changyu via Phabricator via cfe-commits
changyu updated this revision to Diff 128094.
changyu marked an inline comment as done.

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/DeclTemplate.cpp
  lib/CodeGen/CGDecl.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/Parse/ParseTemplate.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/cxx2a-concept-declaration.cpp
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -5906,6 +5906,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,37 @@
+
+// Support parsing of concepts
+
+// RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
+template concept C1 = true;
+
+template concept C1 = true; // expected-error {{redefinition of 'C1'}}
+
+template concept D1 = true; // expected-error {{expected template parameter}}
+
+template<> concept D1 = true;  // expected-error {{expected template parameter}}
+
+// TODO:
+// 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}}
+};
+
+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 {};
+template concept C6 = true; // expected-error {{redefinition of 'C6' as different kind of symbol}}
+
+namespace thing {};
+
+template concept thing::C7 = true;  // expected-error {{concepts must be defined within their namespace}}
+
+
+// TODO: Add test to prevent explicit specialization, partial specialization
+// and explicit instantiation of concepts.
Index: test/Parser/cxx-concept-declaration.cpp
===
--- test/Parser/cxx-concept-declaration.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-
-// 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;
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,6 @@
+// RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
+// expected-no-diagnostics
+
+// TODO: Make this work.
+// template concept C = true;
+// static_assert(C);
Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -101,6 +101,7 @@
 void VisitBindingDecl(BindingDecl *D);
 void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
 void VisitTemplateDecl(TemplateDecl *D);
+void VisitConceptDecl(ConceptDecl *D);
 void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
 void VisitClassTemplateDecl(ClassTemplateDecl *D);
 void VisitVarTemplateDecl(VarTemplateDecl *D);
@@ -1385,6 +1386,12 @@
   Record.AddTemplateParameterList(D->getTemplateParameters());
 }
 
+void ASTDeclWriter::VisitConceptDecl(ConceptDecl *D) {
+  VisitTemplateDecl(D);
+  Record.AddStmt(D->getConstraintExpr());
+  Code = serialization::DECL_CONCEPT;
+}
+
 void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
   VisitRedeclarable(D);
 
Index: lib/Serialization/ASTWriter.cpp
===
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -1277,6 +1277,7 @@
   RECORD(DECL_TEMPLATE_TYPE_PARM);
   RECORD(DECL_NON_TYPE_TEMPLATE_PARM);
   RECORD(DECL_TEMPLATE_TEMPLATE_PARM);
+  RECORD(DECL_CONCEPT);
   RECORD(DECL_TYPE_ALIAS_TEMPLATE);
   RECORD(DECL_STATIC_ASSERT);

[PATCH] D40381: Parse concept definition

2017-12-24 Thread changyu via Phabricator via cfe-commits
changyu added a comment.

I don't have commit privilege. And also there's one more problem we might want 
to address first.

Thank you.




Comment at: lib/Parse/ParseTemplate.cpp:181
+TemplateParameterList *TPL = ParamLists[0];
+if (TPL->getLAngleLoc().getLocWithOffset(1) == TPL->getRAngleLoc()) {
+  Diag(TPL->getTemplateLoc(),

There's one problem here.

​I added this `if` in attempt to catch the following case (but it's wrong)
```
​template<> concept D1 = true;  // expected-error {{expected template 
parameter}}
```
The problem is I'm not sure how to differentiate between the above situation 
and the following
```
​template concept D1 = true; // expected-error {{expected 
template parameter}}
```
Both have an empty template parameter list​. The latter case has diagnostic 
printed by `ParseNonTypeTemplateParameter` while the former has not (so we try 
to catch it here).

What should we do?



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-12-24 Thread changyu via Phabricator via cfe-commits
changyu updated this revision to Diff 128123.
changyu marked 2 inline comments as done.

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/DeclTemplate.cpp
  lib/CodeGen/CGDecl.cpp
  lib/CodeGen/CodeGenModule.cpp
  lib/Parse/ParseTemplate.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/cxx2a-concept-declaration.cpp
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -5906,6 +5906,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,43 @@
+
+// Support parsing of concepts
+
+// RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
+template concept C1 = true;
+
+template concept C1 = true; // expected-error {{redefinition of 'C1'}}
+
+// The following case shouldn't give error about explicit specialization.
+// But the way we parse template parameters in ParseTemplateParameters right
+// now doesn't allow us to distinguish between a template parameter list with
+// an invalid template parameter and a template parameter list with with no
+// parameters.
+// TODO: Fix that.
+template concept D1 = true; // expected-error {{expected template parameter}} expected-error {{concept maybe not be explicitly specialized}}
+
+template<> concept D1 = true;  // expected-error {{concept maybe not be explicitly specialized}}
+
+// TODO: Saar's patch should have this working.
+// 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}}
+};
+
+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 {};
+template concept C6 = true; // expected-error {{redefinition of 'C6' as different kind of symbol}}
+
+namespace thing {};
+
+template concept thing::C7 = true;  // expected-error {{concepts must be defined within their namespace}}
+
+
+// TODO: Add test to prevent explicit specialization, partial specialization
+// and explicit instantiation of concepts.
Index: test/Parser/cxx-concept-declaration.cpp
===
--- test/Parser/cxx-concept-declaration.cpp
+++ /dev/null
@@ -1,7 +0,0 @@
-
-// 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;
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,6 @@
+// RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
+// expected-no-diagnostics
+
+// TODO: Make this work.
+// template concept C = true;
+// static_assert(C);
Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -101,6 +101,7 @@
 void VisitBindingDecl(BindingDecl *D);
 void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
 void VisitTemplateDecl(TemplateDecl *D);
+void VisitConceptDecl(ConceptDecl *D);
 void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
 void VisitClassTemplateDecl(ClassTemplateDecl *D);
 void VisitVarTemplateDecl(VarTemplateDecl *D);
@@ -1385,6 +1386,12 @@
   Record.AddTemplateParameterList(D->getTemplateParameters());
 }
 
+void ASTDeclWriter::VisitConceptDecl(ConceptDecl *D) {
+  VisitTemplateDecl(D);
+  Record.AddStmt(D->getConstraintExpr());
+  Code = serialization::DECL_CONCEPT;
+}
+
 void ASTDeclWriter::VisitRedeclarableTemplateDecl(Rede

[PATCH] D40381: Parse concept definition

2017-12-24 Thread changyu via Phabricator via cfe-commits
changyu added a comment.

I moved some template param checks from 
`Parser::ParseTemplateDeclarationOrSpecialization` to 
`Parser::ParseConceptDefinition` and `Sema::ActOnConceptDefinition`.




Comment at: lib/Parse/ParseTemplate.cpp:181
+TemplateParameterList *TPL = ParamLists[0];
+if (TPL->getLAngleLoc().getLocWithOffset(1) == TPL->getRAngleLoc()) {
+  Diag(TPL->getTemplateLoc(),

faisalv wrote:
> changyu wrote:
> > There's one problem here.
> > 
> > ​I added this `if` in attempt to catch the following case (but it's wrong)
> > ```
> > ​template<> concept D1 = true;  // expected-error {{expected template 
> > parameter}}
> > ```
> > The problem is I'm not sure how to differentiate between the above 
> > situation and the following
> > ```
> > ​template concept D1 = true; // expected-error {{expected 
> > template parameter}}
> > ```
> > Both have an empty template parameter list​. The latter case has diagnostic 
> > printed by `ParseNonTypeTemplateParameter` while the former has not (so we 
> > try to catch it here).
> > 
> > What should we do?
> > 
> 
> I was thinking that we would just emit a (redundant in the case of a bad 
> template parameter) message in Sema if the template-parameters are empty that 
> explicit specializations are not allowed here.  while it would be a little 
> misleading in the invalid template parameter case - to fix this robustly 
> would require some fine-tuning and correcting some of the 
> handshaking/error-propagation between the parsing of the template parameters 
> and the code that calls it, I think.  I would vote for not holding up this 
> patch for that, unless you feel strongly you'd like to fix that behavior - 
> then we can try and work on that first?
> 
> Thoughts?
> 
> 
Sure, let's fix that in another patch. I added a note for this in 
cxx2a-concept-declaration.cpp.


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-22 Thread changyu via Phabricator via cfe-commits
changyu created this revision.

Per p0734r0.


https://reviews.llvm.org/D40381

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Basic/DeclNodes.td
  include/clang/Basic/TemplateKinds.h
  include/clang/Parse/Parser.h
  include/clang/Sema/Sema.h
  lib/AST/ASTDumper.cpp
  lib/AST/DeclBase.cpp
  lib/AST/DeclTemplate.cpp
  lib/CodeGen/CGDecl.cpp
  lib/Parse/ParseTemplate.cpp
  lib/Sema/SemaTemplate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReaderDecl.cpp
  test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp
  test/Parser/cxx-concept-declaration.cpp
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -5906,6 +5906,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,7 @@
 
 // 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;
+template concept C1 = true;
+
+template concept D1 = true; // expected-error {{expected template parameter}}
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,5 @@
+// RUN:  %clang_cc1 -std=c++1z -fconcepts-ts -fcxx-exceptions -x c++ -verify %s
+// expected-no-diagnostics
+
+template concept C = true;
+static_assert(C);
Index: lib/Serialization/ASTReaderDecl.cpp
===
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -337,6 +337,7 @@
 void VisitBindingDecl(BindingDecl *BD);
 void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
 DeclID VisitTemplateDecl(TemplateDecl *D);
+void VisitConceptDecl(ConceptDecl *D);
 RedeclarableResult VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
 void VisitClassTemplateDecl(ClassTemplateDecl *D);
 void VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D);
@@ -1970,6 +1971,10 @@
   return PatternID;
 }
 
+void ASTDeclReader::VisitConceptDecl(ConceptDecl *D) {
+  VisitTemplateDecl(D);
+}
+
 ASTDeclReader::RedeclarableResult
 ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
   RedeclarableResult Redecl = VisitRedeclarable(D);
Index: lib/Serialization/ASTCommon.cpp
===
--- lib/Serialization/ASTCommon.cpp
+++ lib/Serialization/ASTCommon.cpp
@@ -313,6 +313,7 @@
   case Decl::BuiltinTemplate:
   case Decl::Decomposition:
   case Decl::Binding:
+  case Decl::Concept:
 return false;
 
   // These indirectly derive from Redeclarable but are not actually
Index: lib/Sema/SemaTemplateInstantiateDecl.cpp
===
--- lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -3095,6 +3095,11 @@
   return nullptr;
 }
 
+Decl *TemplateDeclInstantiator::VisitConceptDecl(ConceptDecl *D) {
+  // TODO: Do something here?
+  return nullptr;
+}
+
 Decl *TemplateDeclInstantiator::VisitDecl(Decl *D) {
   llvm_unreachable("Unexpected decl");
 }
Index: lib/Sema/SemaTemplate.cpp
===
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -232,9 +232,11 @@
 } else {
   assert(isa(TD) || isa(TD) ||
  isa(TD) || isa(TD) ||
- isa(TD));
+ isa(TD) || isa(TD));
   TemplateKind =
-  isa(TD) ? TNK_Var_template : TNK_Type_template;
+  isa(TD) ? TNK_Var_template :
+  isa(TD) ? TNK_Concept_template :
+  TNK_Type_template;
 }
   }
 
@@ -3884,6 +3886,24 @@
   /*FoundD=*/nullptr, TemplateArgs);
 }
 
+ExprResult
+Sema::CheckConceptTemplateId(const CXXScopeSpec &SS,
+ const DeclarationNameInfo &NameInfo,
+ ConceptDecl *Template, SourceLocation TemplateLoc,
+ const TemplateArgumentListInfo *TemplateArgs) {
+
+  // DeclResult Decl = CheckVarTemplateId(Template, TemplateLoc, NameInfo.getLoc(),
+  //  *TemplateArgs);
+  // if (Decl.isInvalid())
+  //   return ExprError();
+
+  // // Build an ordinary singleton decl ref.
+  // return BuildDeclarationNameExpr(SS, NameInfo, cast(Decl.get()),
+  //   

[PATCH] D40381: Parse concept definition

2017-11-22 Thread changyu via Phabricator via cfe-commits
changyu added a comment.

I should add that this depends on

https://reviews.llvm.org/D40380


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-25 Thread changyu via Phabricator via cfe-commits
changyu planned changes to this revision.
changyu marked 22 inline comments as done.
changyu added inline comments.



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

saar.raz wrote:
> 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;
> }
> ```
I'm guessing you meant for this to be in `class Sema` so I added this to 
`Sema::ActOnConceptDefinition`. Also what is `Init` here?



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

hubert.reinterpretcast wrote:
> changyu wrote:
> > saar.raz wrote:
> > > 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;
> > > }
> > > ```
> > I'm guessing you meant for this to be in `class Sema` so I added this to 
> > `Sema::ActOnConceptDefinition`. Also what is `Init` here?
> I think that would still need a TODO to instead walk the constraint 
> expression for atomic constraints and diagnose those.
> ```
> template 
> concept C = 1 || T::value; // error
> ```
Why is that an error? [temp.constr.normal] in p0734r0 seems to say it's valid?



Comment at: lib/Sema/SemaTemplate.cpp:3903
+  // /*FoundD=*/nullptr, TemplateArgs);
+  return Template->getConstraintExpr();
+  return true;

hubert.reinterpretcast wrote:
> Add more comments here. It looks like this allows us to get id-expressions 
> naming concepts defined with non-dependent `bool` constraint expressions to 
> "work" for now?
That's pretty much it.



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

Rakete wrote:
> saar.raz wrote:
> > 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.
> No braces here please.
I'm following the style of the surrounding code here. I can remove the braces 
if you insist though.



Comment at: lib/Sema/SemaTemplate.cpp:7693
+Decl *Sema::ActOnConceptDefinition(Scope *S,
+  MultiTemplateParamsArg TemplateParameterLists,
+   IdentifierInfo *Name, SourceLocation L,

Rakete wrote:
> Did you run this through clang-format?
No, when I run the file through clang-format (with no arguments except the 
file), it reformats the whole file. How should I be running clang-format?


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-25 Thread changyu via Phabricator via cfe-commits
changyu updated this revision to Diff 124268.
changyu marked 2 inline comments as done.

https://reviews.llvm.org/D40381

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Basic/DeclNodes.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/DeclTemplate.cpp
  lib/CodeGen/CGDecl.cpp
  lib/Parse/ParseTemplate.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
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -5906,6 +5906,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,31 @@
 
 // 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}}
+
+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}}
+};
+
+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.
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,5 @@
+// RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
+// expected-no-diagnostics
+
+template concept C = true;
+static_assert(C);
Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -101,6 +101,7 @@
 void VisitBindingDecl(BindingDecl *D);
 void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
 void VisitTemplateDecl(TemplateDecl *D);
+void VisitConceptDecl(ConceptDecl *D);
 void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
 void VisitClassTemplateDecl(ClassTemplateDecl *D);
 void VisitVarTemplateDecl(VarTemplateDecl *D);
@@ -1385,6 +1386,12 @@
   Record.AddTemplateParameterList(D->getTemplateParameters());
 }
 
+void ASTDeclWriter::VisitConceptDecl(ConceptDecl *D) {
+  VisitTemplateDecl(D);
+  Record.AddStmt(D->getConstraintExpr());
+  Code = serialization::DECL_CONCEPT;
+}
+
 void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
   VisitRedeclarable(D);
 
Index: lib/Serialization/ASTWriter.cpp
===
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -1277,6 +1277,7 @@
   RECORD(DECL_TEMPLATE_TYPE_PARM);
   RECORD(DECL_NON_TYPE_TEMPLATE_PARM);
   RECORD(DECL_TEMPLATE_TEMPLATE_PARM);
+  RECORD(DECL_CONCEPT);
   RECORD(DECL_TYPE_ALIAS_TEMPLATE);
   RECORD(DECL_STATIC_ASSERT);
   RECORD(DECL_CXX_BASE_SPECIFIERS);
Index: lib/Serialization/ASTReaderDecl.cpp
===
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -337,6 +337,7 @@
 void VisitBindingDecl(BindingDecl *BD);
 void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
 DeclID VisitTemplateDecl(TemplateDecl *D);
+void VisitConceptDecl(ConceptDecl *D);
 RedeclarableResult VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
 void VisitClassTemplateDecl(ClassTemplateDecl *D);
 void V

[PATCH] D40381: Parse concept definition

2017-11-25 Thread changyu via Phabricator via cfe-commits
changyu added inline comments.



Comment at: include/clang/Sema/Sema.h:6194
+SourceLocation TemplateLoc,
+const TemplateArgumentListInfo *TemplateArgs);
+

hubert.reinterpretcast wrote:
> Indentation issue here too.
That last line is 79 characters long.


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 changyu via Phabricator via cfe-commits
changyu updated this revision to Diff 124319.
changyu added a comment.

- Fixed indent issues.
- Moved TODO on boolean atomic constraints to ActOnConceptDefinition where we 
are currently checking for boolean constraint expression


https://reviews.llvm.org/D40381

Files:
  include/clang/AST/DeclTemplate.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Basic/DeclNodes.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/DeclTemplate.cpp
  lib/CodeGen/CGDecl.cpp
  lib/Parse/ParseTemplate.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
  tools/libclang/CIndex.cpp

Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -5906,6 +5906,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,31 @@
 
 // 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}}
+
+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}}
+};
+
+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.
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,5 @@
+// RUN:  %clang_cc1 -std=c++2a -fconcepts-ts -verify %s
+// expected-no-diagnostics
+
+template concept C = true;
+static_assert(C);
Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -101,6 +101,7 @@
 void VisitBindingDecl(BindingDecl *D);
 void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
 void VisitTemplateDecl(TemplateDecl *D);
+void VisitConceptDecl(ConceptDecl *D);
 void VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D);
 void VisitClassTemplateDecl(ClassTemplateDecl *D);
 void VisitVarTemplateDecl(VarTemplateDecl *D);
@@ -1385,6 +1386,12 @@
   Record.AddTemplateParameterList(D->getTemplateParameters());
 }
 
+void ASTDeclWriter::VisitConceptDecl(ConceptDecl *D) {
+  VisitTemplateDecl(D);
+  Record.AddStmt(D->getConstraintExpr());
+  Code = serialization::DECL_CONCEPT;
+}
+
 void ASTDeclWriter::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) {
   VisitRedeclarable(D);
 
Index: lib/Serialization/ASTWriter.cpp
===
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -1277,6 +1277,7 @@
   RECORD(DECL_TEMPLATE_TYPE_PARM);
   RECORD(DECL_NON_TYPE_TEMPLATE_PARM);
   RECORD(DECL_TEMPLATE_TEMPLATE_PARM);
+  RECORD(DECL_CONCEPT);
   RECORD(DECL_TYPE_ALIAS_TEMPLATE);
   RECORD(DECL_STATIC_ASSERT);
   RECORD(DECL_CXX_BASE_SPECIFIERS);
Index: lib/Serialization/ASTReaderDecl.cpp
===
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -337,6 +337,7 @@
 void VisitBindingDecl(BindingDecl *BD);
 void VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
 DeclID VisitTemplateDecl(TemplateDecl *D);
+void VisitConceptDecl(ConceptDecl *D);
 Re