[PATCH] D41217: [Concepts] Concept Specialization Expressions
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
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
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
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
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
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
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
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
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
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
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
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
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