summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
authorSaar Raz <saar@raz.email>2019-07-10 21:25:49 +0000
committerSaar Raz <saar@raz.email>2019-07-10 21:25:49 +0000
commitd7aae33a9513d29400157867cdc1f11c2e4a0c40 (patch)
treec2c44b5657f7e2efa19a29f4130868d05314eef8 /clang/lib/AST
parent0171866672346f2a6e956ea97d5cc913f85b39db (diff)
downloadbcm5719-llvm-d7aae33a9513d29400157867cdc1f11c2e4a0c40.tar.gz
bcm5719-llvm-d7aae33a9513d29400157867cdc1f11c2e4a0c40.zip
[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. llvm-svn: 365699
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/ASTStructuralEquivalence.cpp20
-rw-r--r--clang/lib/AST/DeclBase.cpp1
-rw-r--r--clang/lib/AST/DeclPrinter.cpp9
-rw-r--r--clang/lib/AST/DeclTemplate.cpp20
-rw-r--r--clang/lib/AST/TextNodeDumper.cpp4
5 files changed, 52 insertions, 2 deletions
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 744b30f8533..bb2e353eeef 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -1513,6 +1513,18 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+ ConceptDecl *D1,
+ ConceptDecl *D2) {
+ // Check template parameters.
+ if (!IsTemplateDeclCommonStructurallyEquivalent(Context, D1, D2))
+ return false;
+
+ // Check the constraint expression.
+ return IsStructurallyEquivalent(Context, D1->getConstraintExpr(),
+ D2->getConstraintExpr());
+}
+
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
FriendDecl *D1, FriendDecl *D2) {
if ((D1->getFriendType() && D2->getFriendDecl()) ||
(D1->getFriendDecl() && D2->getFriendType())) {
@@ -1771,6 +1783,14 @@ bool StructuralEquivalenceContext::CheckKindSpecificEquivalence(
// Class template/non-class-template mismatch.
return false;
}
+ } else if (auto *ConceptDecl1 = dyn_cast<ConceptDecl>(D1)) {
+ if (auto *ConceptDecl2 = dyn_cast<ConceptDecl>(D2)) {
+ if (!::IsStructurallyEquivalent(*this, ConceptDecl1, ConceptDecl2))
+ return false;
+ } else {
+ // Concept/non-concept mismatch.
+ return false;
+ }
} else if (auto *TTP1 = dyn_cast<TemplateTypeParmDecl>(D1)) {
if (auto *TTP2 = dyn_cast<TemplateTypeParmDecl>(D2)) {
if (!::IsStructurallyEquivalent(*this, TTP1, TTP2))
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index f5853b49804..fd80e1532eb 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -710,6 +710,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
case Binding:
case NonTypeTemplateParm:
case VarTemplate:
+ case Concept:
// These (C++-only) declarations are found by redeclaration lookup for
// tag types, so we include them in the tag namespace.
return IDNS_Ordinary | IDNS_Tag;
diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp
index 73dcdc6854f..f5c69944034 100644
--- a/clang/lib/AST/DeclPrinter.cpp
+++ b/clang/lib/AST/DeclPrinter.cpp
@@ -1123,8 +1123,13 @@ void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) {
if (TTP->isParameterPack())
Out << "...";
Out << D->getName();
- } else {
- Visit(D->getTemplatedDecl());
+ } else if (auto *TD = D->getTemplatedDecl())
+ Visit(TD);
+ else if (const auto *Concept = dyn_cast<ConceptDecl>(D)) {
+ Out << "concept " << Concept->getName() << " = " ;
+ Concept->getConstraintExpr()->printPretty(Out, nullptr, Policy,
+ Indentation);
+ Out << ";";
}
}
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index 3c4cf72f7f5..40c39c845db 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -822,6 +822,26 @@ ClassTemplateSpecializationDecl::getSourceRange() const {
}
//===----------------------------------------------------------------------===//
+// ConceptDecl Implementation
+//===----------------------------------------------------------------------===//
+ConceptDecl *ConceptDecl::Create(ASTContext &C, DeclContext *DC,
+ SourceLocation L, DeclarationName Name,
+ TemplateParameterList *Params,
+ Expr *ConstraintExpr) {
+ AdoptTemplateParameterList(Params, DC);
+ return new (C, DC) ConceptDecl(DC, L, Name, Params, ConstraintExpr);
+}
+
+ConceptDecl *ConceptDecl::CreateDeserialized(ASTContext &C,
+ unsigned ID) {
+ ConceptDecl *Result = new (C, ID) ConceptDecl(nullptr, SourceLocation(),
+ DeclarationName(),
+ nullptr, nullptr);
+
+ return Result;
+}
+
+//===----------------------------------------------------------------------===//
// ClassTemplatePartialSpecializationDecl Implementation
//===----------------------------------------------------------------------===//
void ClassTemplatePartialSpecializationDecl::anchor() {}
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index 01bcc22753e..44c2612a721 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -1936,3 +1936,7 @@ void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) {
if (D->capturesCXXThis())
OS << " captures_this";
}
+
+void TextNodeDumper::VisitConceptDecl(const ConceptDecl *D) {
+ dumpName(D);
+} \ No newline at end of file
OpenPOWER on IntegriCloud