From: Faisal Vali Date: Wed, 25 Apr 2018 02:42:26 +0000 (+0000) Subject: [c++2a] [concepts] Add rudimentary parsing support for template concept declarations X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=45d663da5615045d3c2da1b97ef06319055deb42;p=clang [c++2a] [concepts] Add rudimentary parsing support for template concept declarations This patch is a tweak of changyu's patch: https://reviews.llvm.org/D40381. It differs in that the recognition of the 'concept' token is moved into the machinery that recognizes declaration-specifiers - this allows us to leverage the attribute handling machinery more seamlessly. See the test file to get a sense of the basic parsing that this patch supports. There is much more work to be done before concepts are usable... Thanks Changyu! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@330794 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 9c68352e76..1fe95f4a59 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -3015,6 +3015,46 @@ public: static bool classofKind(Kind K) { return K == VarTemplate; } }; +/// \brief Represents a C++2a ([temp] p1) concept-definition. +class ConceptDecl : public TemplateDecl { +protected: + Expr *ConstraintExpr; + + ConceptDecl(DeclContext *DC, + SourceLocation NameLoc, DeclarationName Name, + TemplateParameterList *Params, + Expr *ConstraintExpr) + : TemplateDecl(nullptr, Concept, DC, NameLoc, Name, Params), + ConstraintExpr(ConstraintExpr) {}; +public: + static ConceptDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation NameLoc, DeclarationName Name, + TemplateParameterList *Params, + Expr *ConstraintExpr); + static ConceptDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + Expr *getConstraintExpr() const { + return ConstraintExpr; + } + + void setConstraintExpr(Expr *CE) { + ConstraintExpr = CE; + } + + SourceRange getSourceRange() const override LLVM_READONLY { + return SourceRange(getTemplateParameters()->getTemplateLoc(), + getConstraintExpr()->getLocEnd()); + } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return classofKind(D->getKind()); } + static bool classofKind(Kind K) { return K == Concept; } + + friend class ASTReader; + friend class ASTDeclReader; + friend class ASTDeclWriter; +}; + inline NamedDecl *getAsNamedDecl(TemplateParameter P) { if (auto *PD = P.dyn_cast()) return PD; diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 57641793f8..d9cc89b126 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1722,6 +1722,13 @@ DEF_TRAVERSE_TMPL_DECL(Class) DEF_TRAVERSE_TMPL_DECL(Var) DEF_TRAVERSE_TMPL_DECL(Function) +DEF_TRAVERSE_DECL(ConceptDecl, { + TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); + TRY_TO(TraverseStmt(D->getConstraintExpr())); + // FIXME: Traverse all the concept specializations (once we implement forming + // template-ids with them). +}) + DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, { // D is the "T" in something like // template