From fa50bf0cf89f59254ae0969e936c597ec1da78b9 Mon Sep 17 00:00:00 2001 From: Saar Raz Date: Wed, 10 Jul 2019 21:25:49 +0000 Subject: [PATCH] [Concepts] Concept definitions (D40381) First in a series of patches to land C++2a Concepts support. This patch adds AST and parsing support for concept-declarations. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@365699 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ASTNodeTraverser.h | 5 + include/clang/AST/DeclTemplate.h | 36 +++++++ include/clang/AST/RecursiveASTVisitor.h | 5 + include/clang/AST/TextNodeDumper.h | 1 + include/clang/Basic/DeclNodes.td | 1 + include/clang/Basic/DiagnosticParseKinds.td | 10 +- include/clang/Basic/DiagnosticSemaKinds.td | 55 +++++------ include/clang/Basic/TemplateKinds.h | 4 +- include/clang/Parse/Parser.h | 4 + include/clang/Sema/Sema.h | 13 +++ include/clang/Serialization/ASTBitCodes.h | 5 +- lib/AST/ASTStructuralEquivalence.cpp | 20 ++++ lib/AST/DeclBase.cpp | 1 + lib/AST/DeclPrinter.cpp | 9 +- lib/AST/DeclTemplate.cpp | 20 ++++ lib/AST/TextNodeDumper.cpp | 4 + lib/CodeGen/CGDecl.cpp | 1 + lib/CodeGen/CodeGenModule.cpp | 1 + lib/Index/IndexDecl.cpp | 4 +- lib/Parse/ParseTemplate.cpp | 94 ++++++++++++++++++ lib/Sema/SemaDecl.cpp | 2 + lib/Sema/SemaDeclCXX.cpp | 2 +- lib/Sema/SemaLookup.cpp | 3 +- lib/Sema/SemaTemplate.cpp | 96 ++++++++++++++++++- lib/Sema/SemaTemplateInstantiateDecl.cpp | 4 + lib/Serialization/ASTCommon.cpp | 1 + lib/Serialization/ASTReaderDecl.cpp | 10 ++ lib/Serialization/ASTWriter.cpp | 1 + lib/Serialization/ASTWriterDecl.cpp | 7 ++ .../expr/expr.prim/expr.prim.id/p3.cpp | 4 + test/Parser/cxx2a-concept-declaration.cpp | 73 ++++++++++++++ tools/libclang/CIndex.cpp | 1 + 32 files changed, 450 insertions(+), 47 deletions(-) create mode 100644 test/CXX/concepts-ts/expr/expr.prim/expr.prim.id/p3.cpp create mode 100644 test/Parser/cxx2a-concept-declaration.cpp diff --git a/include/clang/AST/ASTNodeTraverser.h b/include/clang/AST/ASTNodeTraverser.h index 1d4025f63b..e43eacef86 100644 --- a/include/clang/AST/ASTNodeTraverser.h +++ b/include/clang/AST/ASTNodeTraverser.h @@ -529,6 +529,11 @@ public: D->defaultArgumentWasInherited() ? "inherited from" : "previous"); } + void VisitConceptDecl(const ConceptDecl *D) { + dumpTemplateParameters(D->getTemplateParameters()); + Visit(D->getConstraintExpr()); + } + void VisitUsingShadowDecl(const UsingShadowDecl *D) { if (auto *TD = dyn_cast(D->getUnderlyingDecl())) Visit(TD->getTypeForDecl()); diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 5933810ec8..235b31c1c3 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -3090,6 +3090,42 @@ public: static bool classofKind(Kind K) { return K == VarTemplate; } }; +// \brief Declaration of a C++2a concept. +class ConceptDecl : public TemplateDecl, public Mergeable { +protected: + Expr *ConstraintExpr; + + ConceptDecl(DeclContext *DC, + SourceLocation L, DeclarationName Name, + TemplateParameterList *Params, + Expr *ConstraintExpr) + : TemplateDecl(nullptr, Concept, DC, L, Name, Params), + ConstraintExpr(ConstraintExpr) {}; +public: + static ConceptDecl *Create(ASTContext &C, DeclContext *DC, + SourceLocation L, DeclarationName Name, + TemplateParameterList *Params, + Expr *ConstraintExpr); + static ConceptDecl *CreateDeserialized(ASTContext &C, unsigned ID); + + Expr *getConstraintExpr() const { + return ConstraintExpr; + } + + SourceRange getSourceRange() const override LLVM_READONLY { + return SourceRange(getTemplateParameters()->getTemplateLoc(), + ConstraintExpr->getEndLoc()); + } + + // 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 292b57af76..698fba2f4e 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -1800,6 +1800,11 @@ DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, { TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); }) +DEF_TRAVERSE_DECL(ConceptDecl, { + TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); + TRY_TO(TraverseStmt(D->getConstraintExpr())); +}) + DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, { // A dependent using declaration which was marked with 'typename'. // template class A : public B { using typename B::foo; }; diff --git a/include/clang/AST/TextNodeDumper.h b/include/clang/AST/TextNodeDumper.h index a26b06058b..4c2d071096 100644 --- a/include/clang/AST/TextNodeDumper.h +++ b/include/clang/AST/TextNodeDumper.h @@ -347,6 +347,7 @@ public: void VisitObjCPropertyDecl(const ObjCPropertyDecl *D); void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D); void VisitBlockDecl(const BlockDecl *D); + void VisitConceptDecl(const ConceptDecl *D); }; } // namespace clang diff --git a/include/clang/Basic/DeclNodes.td b/include/clang/Basic/DeclNodes.td index 45eba45415..2d3fa6b614 100644 --- a/include/clang/Basic/DeclNodes.td +++ b/include/clang/Basic/DeclNodes.td @@ -70,6 +70,7 @@ def Named : Decl<"named declarations", 1>; def TypeAliasTemplate : DDecl; def TemplateTemplateParm : DDecl