Skip to content

Commit a0f50d7

Browse files
committed
[Concepts] Requires Expressions
Implement support for C++2a requires-expressions. Re-commit after compilation failure on some platforms due to alignment issues with PointerIntPair. Differential Revision: https://reviews.llvm.org/D50360
1 parent ed9cc64 commit a0f50d7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+3811
-302
lines changed

clang/include/clang/AST/ASTConcept.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <utility>
2323
namespace clang {
2424
class ConceptDecl;
25+
class ConceptSpecializationExpr;
2526

2627
/// \brief The result of a constraint satisfaction check, containing the
2728
/// necessary information to diagnose an unsatisfied constraint.

clang/include/clang/AST/DeclCXX.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1893,6 +1893,37 @@ class CXXDeductionGuideDecl : public FunctionDecl {
18931893
static bool classofKind(Kind K) { return K == CXXDeductionGuide; }
18941894
};
18951895

1896+
/// \brief Represents the body of a requires-expression.
1897+
///
1898+
/// This decl exists merely to serve as the DeclContext for the local
1899+
/// parameters of the requires expression as well as other declarations inside
1900+
/// it.
1901+
///
1902+
/// \code
1903+
/// template<typename T> requires requires (T t) { {t++} -> regular; }
1904+
/// \endcode
1905+
///
1906+
/// In this example, a RequiresExpr object will be generated for the expression,
1907+
/// and a RequiresExprBodyDecl will be created to hold the parameter t and the
1908+
/// template argument list imposed by the compound requirement.
1909+
class RequiresExprBodyDecl : public Decl, public DeclContext {
1910+
RequiresExprBodyDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc)
1911+
: Decl(RequiresExprBody, DC, StartLoc), DeclContext(RequiresExprBody) {}
1912+
1913+
public:
1914+
friend class ASTDeclReader;
1915+
friend class ASTDeclWriter;
1916+
1917+
static RequiresExprBodyDecl *Create(ASTContext &C, DeclContext *DC,
1918+
SourceLocation StartLoc);
1919+
1920+
static RequiresExprBodyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
1921+
1922+
// Implement isa/cast/dyncast/etc.
1923+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
1924+
static bool classofKind(Kind K) { return K == RequiresExprBody; }
1925+
};
1926+
18961927
/// Represents a static or instance method of a struct/union/class.
18971928
///
18981929
/// In the terminology of the C++ Standard, these are the (static and

clang/include/clang/AST/ExprCXX.h

Lines changed: 0 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#ifndef LLVM_CLANG_AST_EXPRCXX_H
1515
#define LLVM_CLANG_AST_EXPRCXX_H
1616

17-
#include "clang/AST/ASTConcept.h"
1817
#include "clang/AST/Decl.h"
1918
#include "clang/AST/DeclBase.h"
2019
#include "clang/AST/DeclCXX.h"
@@ -4836,99 +4835,6 @@ class BuiltinBitCastExpr final
48364835
}
48374836
};
48384837

4839-
/// \brief Represents the specialization of a concept - evaluates to a prvalue
4840-
/// of type bool.
4841-
///
4842-
/// According to C++2a [expr.prim.id]p3 an id-expression that denotes the
4843-
/// specialization of a concept results in a prvalue of type bool.
4844-
class ConceptSpecializationExpr final : public Expr, public ConceptReference,
4845-
private llvm::TrailingObjects<ConceptSpecializationExpr,
4846-
TemplateArgument> {
4847-
friend class ASTStmtReader;
4848-
friend TrailingObjects;
4849-
public:
4850-
using SubstitutionDiagnostic = std::pair<SourceLocation, std::string>;
4851-
4852-
protected:
4853-
/// \brief The number of template arguments in the tail-allocated list of
4854-
/// converted template arguments.
4855-
unsigned NumTemplateArgs;
4856-
4857-
/// \brief Information about the satisfaction of the named concept with the
4858-
/// given arguments. If this expression is value dependent, this is to be
4859-
/// ignored.
4860-
ASTConstraintSatisfaction *Satisfaction;
4861-
4862-
ConceptSpecializationExpr(const ASTContext &C, NestedNameSpecifierLoc NNS,
4863-
SourceLocation TemplateKWLoc,
4864-
DeclarationNameInfo ConceptNameInfo,
4865-
NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
4866-
const ASTTemplateArgumentListInfo *ArgsAsWritten,
4867-
ArrayRef<TemplateArgument> ConvertedArgs,
4868-
const ConstraintSatisfaction *Satisfaction);
4869-
4870-
ConceptSpecializationExpr(EmptyShell Empty, unsigned NumTemplateArgs);
4871-
4872-
public:
4873-
4874-
static ConceptSpecializationExpr *
4875-
Create(const ASTContext &C, NestedNameSpecifierLoc NNS,
4876-
SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
4877-
NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
4878-
const ASTTemplateArgumentListInfo *ArgsAsWritten,
4879-
ArrayRef<TemplateArgument> ConvertedArgs,
4880-
const ConstraintSatisfaction *Satisfaction);
4881-
4882-
static ConceptSpecializationExpr *
4883-
Create(ASTContext &C, EmptyShell Empty, unsigned NumTemplateArgs);
4884-
4885-
ArrayRef<TemplateArgument> getTemplateArguments() const {
4886-
return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
4887-
NumTemplateArgs);
4888-
}
4889-
4890-
/// \brief Set new template arguments for this concept specialization.
4891-
void setTemplateArguments(ArrayRef<TemplateArgument> Converted);
4892-
4893-
/// \brief Whether or not the concept with the given arguments was satisfied
4894-
/// when the expression was created.
4895-
/// The expression must not be dependent.
4896-
bool isSatisfied() const {
4897-
assert(!isValueDependent()
4898-
&& "isSatisfied called on a dependent ConceptSpecializationExpr");
4899-
return Satisfaction->IsSatisfied;
4900-
}
4901-
4902-
/// \brief Get elaborated satisfaction info about the template arguments'
4903-
/// satisfaction of the named concept.
4904-
/// The expression must not be dependent.
4905-
const ASTConstraintSatisfaction &getSatisfaction() const {
4906-
assert(!isValueDependent()
4907-
&& "getSatisfaction called on dependent ConceptSpecializationExpr");
4908-
return *Satisfaction;
4909-
}
4910-
4911-
static bool classof(const Stmt *T) {
4912-
return T->getStmtClass() == ConceptSpecializationExprClass;
4913-
}
4914-
4915-
SourceLocation getBeginLoc() const LLVM_READONLY {
4916-
return ConceptName.getBeginLoc();
4917-
}
4918-
4919-
SourceLocation getEndLoc() const LLVM_READONLY {
4920-
return ArgsAsWritten->RAngleLoc;
4921-
}
4922-
4923-
// Iterators
4924-
child_range children() {
4925-
return child_range(child_iterator(), child_iterator());
4926-
}
4927-
const_child_range children() const {
4928-
return const_child_range(const_child_iterator(), const_child_iterator());
4929-
}
4930-
};
4931-
49324838
} // namespace clang
49334839

49344840
#endif // LLVM_CLANG_AST_EXPRCXX_H

0 commit comments

Comments
 (0)