[PATCH] D40381: Parse concept definition
Saar Raz via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Nov 23 13:27:48 PST 2017
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<FunctionTemplateDecl>(Template) ||
isa<VarTemplateDecl>(Template)) {
// We might have a substituted template template parameter pack. If so,
----------------
Add
```
|| isa<ConceptDecl>
```
================
Comment at: lib/Sema/SemaTemplate.cpp:3936
+ if (R.getAsSingle<ConceptDecl>()) {
+ 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
More information about the cfe-commits
mailing list