summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorSaar Raz <saar@raz.email>2019-10-15 18:44:06 +0000
committerSaar Raz <saar@raz.email>2019-10-15 18:44:06 +0000
commitcf4a18c6aa180512c2f9b2a88450492b9c89c3c8 (patch)
treea8f878dad9ce11e042bd5a9388610e90425997f9 /include
parentea4934045aa895f450dae600d12b7f5582915598 (diff)
downloadclang-cf4a18c6aa180512c2f9b2a88450492b9c89c3c8.tar.gz
[Concept] Associated Constraints Infrastructure
Add code to correctly calculate the associated constraints of a template (no enforcement yet). D41284 on Phabricator. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@374938 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/clang/AST/ASTNodeTraverser.h3
-rw-r--r--include/clang/AST/DeclTemplate.h174
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td4
-rw-r--r--include/clang/Sema/Sema.h8
5 files changed, 81 insertions, 116 deletions
diff --git a/include/clang/AST/ASTNodeTraverser.h b/include/clang/AST/ASTNodeTraverser.h
index e43eacef86..0bb2aad553 100644
--- a/include/clang/AST/ASTNodeTraverser.h
+++ b/include/clang/AST/ASTNodeTraverser.h
@@ -237,6 +237,9 @@ public:
for (const auto &TP : *TPL)
Visit(TP);
+
+ if (const Expr *RC = TPL->getRequiresClause())
+ Visit(RC);
}
void
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h
index cb04e78b3d..ec14adc7de 100644
--- a/include/clang/AST/DeclTemplate.h
+++ b/include/clang/AST/DeclTemplate.h
@@ -168,6 +168,16 @@ public:
return HasRequiresClause ? *getTrailingObjects<Expr *>() : nullptr;
}
+ /// \brief All associated constraints derived from this template parameter
+ /// list, including the requires clause and any constraints derived from
+ /// constrained-parameters.
+ ///
+ /// The constraints in the resulting list are to be treated as if in a
+ /// conjunction ("and").
+ void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const;
+
+ bool hasAssociatedConstraints() const;
+
SourceLocation getTemplateLoc() const { return TemplateLoc; }
SourceLocation getLAngleLoc() const { return LAngleLoc; }
SourceLocation getRAngleLoc() const { return RAngleLoc; }
@@ -369,33 +379,7 @@ public:
// Kinds of Templates
//===----------------------------------------------------------------------===//
-/// Stores the template parameter list and associated constraints for
-/// \c TemplateDecl objects that track associated constraints.
-class ConstrainedTemplateDeclInfo {
- friend TemplateDecl;
-
-public:
- ConstrainedTemplateDeclInfo() = default;
-
- TemplateParameterList *getTemplateParameters() const {
- return TemplateParams;
- }
-
- Expr *getAssociatedConstraints() const { return AssociatedConstraints; }
-
-protected:
- void setTemplateParameters(TemplateParameterList *TParams) {
- TemplateParams = TParams;
- }
-
- void setAssociatedConstraints(Expr *AC) { AssociatedConstraints = AC; }
-
- TemplateParameterList *TemplateParams = nullptr;
- Expr *AssociatedConstraints = nullptr;
-};
-
-
-/// The base class of all kinds of template declarations (e.g.,
+/// \brief The base class of all kinds of template declarations (e.g.,
/// class, function, etc.).
///
/// The TemplateDecl class stores the list of template parameters and a
@@ -404,54 +388,32 @@ class TemplateDecl : public NamedDecl {
void anchor() override;
protected:
+ // Construct a template decl with name, parameters, and templated element.
+ TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
+ TemplateParameterList *Params, NamedDecl *Decl);
+
// Construct a template decl with the given name and parameters.
// Used when there is no templated element (e.g., for tt-params).
- TemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK, DeclContext *DC,
- SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params)
- : NamedDecl(DK, DC, L, Name), TemplatedDecl(nullptr),
- TemplateParams(CTDI) {
- this->setTemplateParameters(Params);
- }
-
TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
TemplateParameterList *Params)
- : TemplateDecl(nullptr, DK, DC, L, Name, Params) {}
-
- // Construct a template decl with name, parameters, and templated element.
- TemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK, DeclContext *DC,
- SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl)
- : NamedDecl(DK, DC, L, Name), TemplatedDecl(Decl),
- TemplateParams(CTDI) {
- this->setTemplateParameters(Params);
- }
-
- TemplateDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl)
- : TemplateDecl(nullptr, DK, DC, L, Name, Params, Decl) {}
+ : TemplateDecl(DK, DC, L, Name, Params, nullptr) {}
public:
+ friend class ASTDeclReader;
+ friend class ASTDeclWriter;
+
/// Get the list of template parameters
TemplateParameterList *getTemplateParameters() const {
- const auto *const CTDI =
- TemplateParams.dyn_cast<ConstrainedTemplateDeclInfo *>();
- return CTDI ? CTDI->getTemplateParameters()
- : TemplateParams.get<TemplateParameterList *>();
+ return TemplateParams;
}
- /// Get the constraint-expression from the associated requires-clause (if any)
- const Expr *getRequiresClause() const {
- const TemplateParameterList *const TP = getTemplateParameters();
- return TP ? TP->getRequiresClause() : nullptr;
- }
+ /// \brief Get the total constraint-expression associated with this template,
+ /// including constraint-expressions derived from the requires-clause,
+ /// trailing requires-clause (for functions and methods) and constrained
+ /// template parameters.
+ void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const;
- Expr *getAssociatedConstraints() const {
- const auto *const C = cast<TemplateDecl>(getCanonicalDecl());
- const auto *const CTDI =
- C->TemplateParams.dyn_cast<ConstrainedTemplateDeclInfo *>();
- return CTDI ? CTDI->getAssociatedConstraints() : nullptr;
- }
+ bool hasAssociatedConstraints() const;
/// Get the underlying, templated declaration.
NamedDecl *getTemplatedDecl() const { return TemplatedDecl; }
@@ -470,29 +432,10 @@ public:
protected:
NamedDecl *TemplatedDecl;
-
- /// The template parameter list and optional requires-clause
- /// associated with this declaration; alternatively, a
- /// \c ConstrainedTemplateDeclInfo if the associated constraints of the
- /// template are being tracked by this particular declaration.
- llvm::PointerUnion<TemplateParameterList *,
- ConstrainedTemplateDeclInfo *>
- TemplateParams;
+ TemplateParameterList *TemplateParams;
void setTemplateParameters(TemplateParameterList *TParams) {
- if (auto *const CTDI =
- TemplateParams.dyn_cast<ConstrainedTemplateDeclInfo *>()) {
- CTDI->setTemplateParameters(TParams);
- } else {
- TemplateParams = TParams;
- }
- }
-
- void setAssociatedConstraints(Expr *AC) {
- assert(isCanonicalDecl() &&
- "Attaching associated constraints to non-canonical Decl");
- TemplateParams.get<ConstrainedTemplateDeclInfo *>()
- ->setAssociatedConstraints(AC);
+ TemplateParams = TParams;
}
public:
@@ -889,17 +832,10 @@ protected:
virtual CommonBase *newCommon(ASTContext &C) const = 0;
// Construct a template decl with name, parameters, and templated element.
- RedeclarableTemplateDecl(ConstrainedTemplateDeclInfo *CTDI, Kind DK,
- ASTContext &C, DeclContext *DC, SourceLocation L,
- DeclarationName Name, TemplateParameterList *Params,
- NamedDecl *Decl)
- : TemplateDecl(CTDI, DK, DC, L, Name, Params, Decl), redeclarable_base(C)
- {}
-
RedeclarableTemplateDecl(Kind DK, ASTContext &C, DeclContext *DC,
SourceLocation L, DeclarationName Name,
TemplateParameterList *Params, NamedDecl *Decl)
- : RedeclarableTemplateDecl(nullptr, DK, C, DC, L, Name, Params, Decl) {}
+ : TemplateDecl(DK, DC, L, Name, Params, Decl), redeclarable_base(C) {}
public:
friend class ASTDeclReader;
@@ -2026,6 +1962,20 @@ public:
return TemplateParams;
}
+ /// \brief All associated constraints of this partial specialization,
+ /// including the requires clause and any constraints derived from
+ /// constrained-parameters.
+ ///
+ /// The constraints in the resulting list are to be treated as if in a
+ /// conjunction ("and").
+ void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
+ TemplateParams->getAssociatedConstraints(AC);
+ }
+
+ bool hasAssociatedConstraints() const {
+ return TemplateParams->hasAssociatedConstraints();
+ }
+
/// Get the template arguments as written.
const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
return ArgsAsWritten;
@@ -2145,16 +2095,10 @@ protected:
llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl> &
getPartialSpecializations();
- ClassTemplateDecl(ConstrainedTemplateDeclInfo *CTDI, ASTContext &C,
- DeclContext *DC, SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params, NamedDecl *Decl)
- : RedeclarableTemplateDecl(CTDI, ClassTemplate, C, DC, L, Name, Params,
- Decl) {}
-
ClassTemplateDecl(ASTContext &C, DeclContext *DC, SourceLocation L,
DeclarationName Name, TemplateParameterList *Params,
NamedDecl *Decl)
- : ClassTemplateDecl(nullptr, C, DC, L, Name, Params, Decl) {}
+ : RedeclarableTemplateDecl(ClassTemplate, C, DC, L, Name, Params, Decl) {}
CommonBase *newCommon(ASTContext &C) const override;
@@ -2180,14 +2124,12 @@ public:
return getTemplatedDecl()->isThisDeclarationADefinition();
}
- // FIXME: remove default argument for AssociatedConstraints
- /// Create a class template node.
+ /// \brief Create a class template node.
static ClassTemplateDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
DeclarationName Name,
TemplateParameterList *Params,
- NamedDecl *Decl,
- Expr *AssociatedConstraints = nullptr);
+ NamedDecl *Decl);
/// Create an empty class template node.
static ClassTemplateDecl *CreateDeserialized(ASTContext &C, unsigned ID);
@@ -2862,7 +2804,21 @@ public:
return ArgsAsWritten;
}
- /// Retrieve the member variable template partial specialization from
+ /// \brief All associated constraints of this partial specialization,
+ /// including the requires clause and any constraints derived from
+ /// constrained-parameters.
+ ///
+ /// The constraints in the resulting list are to be treated as if in a
+ /// conjunction ("and").
+ void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
+ TemplateParams->getAssociatedConstraints(AC);
+ }
+
+ bool hasAssociatedConstraints() const {
+ return TemplateParams->hasAssociatedConstraints();
+ }
+
+ /// \brief Retrieve the member variable template partial specialization from
/// which this particular variable template partial specialization was
/// instantiated.
///
@@ -3091,11 +3047,9 @@ class ConceptDecl : public TemplateDecl, public Mergeable<ConceptDecl> {
protected:
Expr *ConstraintExpr;
- ConceptDecl(DeclContext *DC,
- SourceLocation L, DeclarationName Name,
- TemplateParameterList *Params,
- Expr *ConstraintExpr)
- : TemplateDecl(nullptr, Concept, DC, L, Name, Params),
+ ConceptDecl(DeclContext *DC, SourceLocation L, DeclarationName Name,
+ TemplateParameterList *Params, Expr *ConstraintExpr)
+ : TemplateDecl(Concept, DC, L, Name, Params),
ConstraintExpr(ConstraintExpr) {};
public:
static ConceptDecl *Create(ASTContext &C, DeclContext *DC,
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 998cf9238c..3a21034057 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -1633,9 +1633,11 @@ template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
TemplateParameterList *TPL) {
if (TPL) {
- for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
- I != E; ++I) {
- TRY_TO(TraverseDecl(*I));
+ for (NamedDecl *D : *TPL) {
+ TRY_TO(TraverseDecl(D));
+ }
+ if (Expr *RequiresClause = TPL->getRequiresClause()) {
+ TRY_TO(TraverseStmt(RequiresClause));
}
}
return true;
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 968c2dbd56..755fac842d 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -2543,8 +2543,8 @@ def err_non_constant_constraint_expression : Error<
def err_non_bool_atomic_constraint : Error<
"atomic constraint must be of type 'bool' (found %0)">;
-def err_template_different_associated_constraints : Error<
- "associated constraints differ in template redeclaration">;
+def err_template_different_requires_clause : Error<
+ "requires clause differs in template redeclaration">;
// C++11 char16_t/char32_t
def warn_cxx98_compat_unicode_type : Warning<
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 7c93d40952..d2798eaf65 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -6058,7 +6058,13 @@ public:
Expr *ConstraintExpr,
bool &IsSatisfied);
- // ParseObjCStringLiteral - Parse Objective-C string literals.
+ /// Check that the associated constraints of a template declaration match the
+ /// associated constraints of an older declaration of which it is a
+ /// redeclaration.
+ bool CheckRedeclarationConstraintMatch(TemplateParameterList *Old,
+ TemplateParameterList *New);
+
+ // ParseObjCStringLiteral - Parse Objective-C string literals.
ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
ArrayRef<Expr *> Strings);