[PATCH] D40381: Parse concept definition

Faisal Vali via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sun Dec 17 08:55:47 PST 2017


faisalv added a comment.

Thanks for working on this! :)



================
Comment at: include/clang/AST/DeclTemplate.h:3035
+  SourceRange getSourceRange() const override LLVM_READONLY {
+    return SourceRange(getLocation(), getLocation());
+  }
----------------
why not just fix it now?
  return SourceRange(getTemplateParameters()->getTemplateLoc(), ConstraintExpr->getLocEnd(); 

?


================
Comment at: include/clang/AST/RecursiveASTVisitor.h:1725
 
+DEF_TRAVERSE_DECL(ConceptDecl, {})
+
----------------
Perhaps something along these lines?
  DEF_TRAVERSE_DECL(ConceptDecl, {    

    TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
    
    TRY_TO(TraverseStmt(D->getConstraintExpr()));
    // FIXME: Traverse all the concept specializations (one we implement forming template-ids with them).
  })



================
Comment at: include/clang/Sema/Sema.h:6196
+                         const TemplateArgumentListInfo *TemplateArgs);
+
   ExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS,
----------------
Have you considered just deferring formation of concept template-ids to the next patch (especially since it might require introduction of another AST node ConceptSpecializationDecl.  We could just focus on handling concept declarations/definitions in this one (and emit an unimplemented error if someone tries to form a template-id with a concept within BuildTemplateId etc.) - but perhaps consider making sure we handle name clashes/redeclarations with any other parsed names in the same namespace (within this patch)?


================
Comment at: lib/AST/DeclBase.cpp:773
+      return IDNS_Ordinary | IDNS_Tag;
+
     // Never have names.
----------------
Pls consider just lumping this case with 'Binding/VarTemplate' (which by the way also includes a comment for why we have to add the ugly IDNS_Tag hack here (personally i think we should refactor this functionality, currently it seems split between this and SemaLookup.cpp:getIDNS and would benefit from some sort of well-designed cohesion - but that's another (low-priority) patch)


================
Comment at: lib/CodeGen/CGDecl.cpp:108
   case Decl::Empty:
+  case Decl::Concept:
     // None of these decls require codegen support.
----------------
You would need to add this to EmitTopLevelDecl too to handle global-namespace concept declarations.


================
Comment at: lib/Parse/ParseTemplate.cpp:368
+
+  if (!TryConsumeToken(tok::equal)) {
+    Diag(Tok.getLocation(), diag::err_expected) << "equal";
----------------
I think we should diagnose qualified-name errors here much more gracefully than we do.

i.e. template<class T> concept N::C = ...  

- perhaps try and parse a scope-specifier, and if found emit a diagnostic such as concepts must be defined within their namespace ...


================
Comment at: lib/Sema/SemaTemplate.cpp:3899
+  // constraint expressions right now.
+  return Template->getConstraintExpr();
+}
----------------
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?


================
Comment at: lib/Sema/SemaTemplate.cpp:3923
   bool InstantiationDependent;
-  if (R.getAsSingle<VarTemplateDecl>() &&
-      !TemplateSpecializationType::anyDependentTemplateArguments(
-           *TemplateArgs, InstantiationDependent)) {
+  bool DependentArguments =
+    TemplateSpecializationType::anyDependentTemplateArguments(
----------------
const bool, no?


================
Comment at: lib/Sema/SemaTemplate.cpp:7692
+                              MultiTemplateParamsArg TemplateParameterLists,
+                                   IdentifierInfo *Name, SourceLocation L,
+                                   Expr *ConstraintExpr) {
----------------
Rename L as NameLoc?


================
Comment at: lib/Sema/SemaTemplate.cpp:7706
+  }
+
+  ConceptDecl *NewDecl = ConceptDecl::Create(Context, DC, L, Name,
----------------
Perhaps add a lookup check here? (or a fixme that we are deferring to the next patch), something along these *pseudo-code* lines:
   LookupResult Previous(*this, DeclarationNameInfo(DeclarationName(Name),NameLoc), LookupOrdinaryName);
   LookupName(Previous, S);
   if (Previous.getRepresentativeDecl())    ... if the decl is a concept - give error regarding only one definition allowed in a TU, if a different kind of decl then declared w a different symbol type of error?


================
Comment at: lib/Sema/SemaTemplate.cpp:7713
+
+  if (!ConstraintExpr->isTypeDependent() &&
+      ConstraintExpr->getType() != Context.BoolTy) {
----------------
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)?


================
Comment at: lib/Sema/SemaTemplate.cpp:7735
+  ActOnDocumentableDecl(NewDecl);
+  CurContext->addDecl(NewDecl);
+  return NewDecl;
----------------
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);


================
Comment at: test/Parser/cxx-concept-declaration.cpp:1
 
 // Support parsing of concepts
----------------
Name this file starting with cxx2a- please.


https://reviews.llvm.org/D40381





More information about the cfe-commits mailing list