|
@@ -17,6 +17,7 @@
|
|
#include "clang/AST/Decl.h"
|
|
#include "clang/AST/Decl.h"
|
|
#include "clang/AST/DeclBase.h"
|
|
#include "clang/AST/DeclBase.h"
|
|
#include "clang/AST/DeclCXX.h"
|
|
#include "clang/AST/DeclCXX.h"
|
|
|
|
+#include "clang/AST/DeclTemplate.h"
|
|
#include "clang/AST/DeclarationName.h"
|
|
#include "clang/AST/DeclarationName.h"
|
|
#include "clang/AST/Expr.h"
|
|
#include "clang/AST/Expr.h"
|
|
#include "clang/AST/NestedNameSpecifier.h"
|
|
#include "clang/AST/NestedNameSpecifier.h"
|
|
@@ -56,6 +57,7 @@ class IdentifierInfo;
|
|
class LambdaCapture;
|
|
class LambdaCapture;
|
|
class NonTypeTemplateParmDecl;
|
|
class NonTypeTemplateParmDecl;
|
|
class TemplateParameterList;
|
|
class TemplateParameterList;
|
|
|
|
+class Sema;
|
|
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
//===--------------------------------------------------------------------===//
|
|
// C++ Expressions.
|
|
// C++ Expressions.
|
|
@@ -4750,6 +4752,125 @@ public:
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+/// \brief Represents the specialization of a concept - evaluates to a prvalue
|
|
|
|
+/// of type bool.
|
|
|
|
+///
|
|
|
|
+/// According to C++2a [expr.prim.id]p3 an id-expression that denotes the
|
|
|
|
+/// specialization of a concept results in a prvalue of type bool.
|
|
|
|
+class ConceptSpecializationExpr final : public Expr,
|
|
|
|
+ private llvm::TrailingObjects<ConceptSpecializationExpr,
|
|
|
|
+ TemplateArgument> {
|
|
|
|
+ friend class ASTStmtReader;
|
|
|
|
+ friend TrailingObjects;
|
|
|
|
+
|
|
|
|
+ // \brief The optional nested name specifier used when naming the concept.
|
|
|
|
+ NestedNameSpecifierLoc NestedNameSpec;
|
|
|
|
+
|
|
|
|
+ /// \brief The location of the template keyword, if specified when naming the
|
|
|
|
+ /// concept.
|
|
|
|
+ SourceLocation TemplateKWLoc;
|
|
|
|
+
|
|
|
|
+ /// \brief The location of the concept name in the expression.
|
|
|
|
+ SourceLocation ConceptNameLoc;
|
|
|
|
+
|
|
|
|
+ /// \brief The declaration found by name lookup when the expression was
|
|
|
|
+ /// created.
|
|
|
|
+ /// Can differ from NamedConcept when, for example, the concept was found
|
|
|
|
+ /// through a UsingShadowDecl.
|
|
|
|
+ NamedDecl *FoundDecl;
|
|
|
|
+
|
|
|
|
+ /// \brief The concept named, and whether or not the concept with the given
|
|
|
|
+ /// arguments was satisfied when the expression was created.
|
|
|
|
+ /// If any of the template arguments are dependent (this expr would then be
|
|
|
|
+ /// isValueDependent()), this bit is to be ignored.
|
|
|
|
+ llvm::PointerIntPair<ConceptDecl *, 1, bool> NamedConcept;
|
|
|
|
+
|
|
|
|
+ /// \brief The template argument list source info used to specialize the
|
|
|
|
+ /// concept.
|
|
|
|
+ const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
|
|
|
|
+
|
|
|
|
+ /// \brief The number of template arguments in the tail-allocated list of
|
|
|
|
+ /// converted template arguments.
|
|
|
|
+ unsigned NumTemplateArgs;
|
|
|
|
+
|
|
|
|
+ ConceptSpecializationExpr(ASTContext &C, NestedNameSpecifierLoc NNS,
|
|
|
|
+ SourceLocation TemplateKWLoc,
|
|
|
|
+ SourceLocation ConceptNameLoc, NamedDecl *FoundDecl,
|
|
|
|
+ ConceptDecl *NamedConcept,
|
|
|
|
+ const ASTTemplateArgumentListInfo *ArgsAsWritten,
|
|
|
|
+ ArrayRef<TemplateArgument> ConvertedArgs,
|
|
|
|
+ Optional<bool> IsSatisfied);
|
|
|
|
+
|
|
|
|
+ ConceptSpecializationExpr(EmptyShell Empty, unsigned NumTemplateArgs);
|
|
|
|
+
|
|
|
|
+public:
|
|
|
|
+
|
|
|
|
+ static ConceptSpecializationExpr *
|
|
|
|
+ Create(ASTContext &C, NestedNameSpecifierLoc NNS,
|
|
|
|
+ SourceLocation TemplateKWLoc, SourceLocation ConceptNameLoc,
|
|
|
|
+ NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
|
|
|
|
+ const ASTTemplateArgumentListInfo *ArgsAsWritten,
|
|
|
|
+ ArrayRef<TemplateArgument> ConvertedArgs, Optional<bool> IsSatisfied);
|
|
|
|
+
|
|
|
|
+ static ConceptSpecializationExpr *
|
|
|
|
+ Create(ASTContext &C, EmptyShell Empty, unsigned NumTemplateArgs);
|
|
|
|
+
|
|
|
|
+ const NestedNameSpecifierLoc &getNestedNameSpecifierLoc() const {
|
|
|
|
+ return NestedNameSpec;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ NamedDecl *getFoundDecl() const {
|
|
|
|
+ return FoundDecl;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ConceptDecl *getNamedConcept() const {
|
|
|
|
+ return NamedConcept.getPointer();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ArrayRef<TemplateArgument> getTemplateArguments() const {
|
|
|
|
+ return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
|
|
|
|
+ NumTemplateArgs);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
|
|
|
|
+ return ArgsAsWritten;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /// \brief Set new template arguments for this concept specialization.
|
|
|
|
+ void setTemplateArguments(const ASTTemplateArgumentListInfo *ArgsAsWritten,
|
|
|
|
+ ArrayRef<TemplateArgument> Converted);
|
|
|
|
+
|
|
|
|
+ /// \brief Whether or not the concept with the given arguments was satisfied
|
|
|
|
+ /// when the expression was created. This method assumes that the expression
|
|
|
|
+ /// is not dependent!
|
|
|
|
+ bool isSatisfied() const {
|
|
|
|
+ assert(!isValueDependent()
|
|
|
|
+ && "isSatisfied called on a dependent ConceptSpecializationExpr");
|
|
|
|
+ return NamedConcept.getInt();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ SourceLocation getConceptNameLoc() const { return ConceptNameLoc; }
|
|
|
|
+
|
|
|
|
+ SourceLocation getTemplateKWLoc() const { return TemplateKWLoc; }
|
|
|
|
+
|
|
|
|
+ static bool classof(const Stmt *T) {
|
|
|
|
+ return T->getStmtClass() == ConceptSpecializationExprClass;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ SourceLocation getBeginLoc() const LLVM_READONLY { return ConceptNameLoc; }
|
|
|
|
+ SourceLocation getEndLoc() const LLVM_READONLY {
|
|
|
|
+ return ArgsAsWritten->RAngleLoc;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Iterators
|
|
|
|
+ child_range children() {
|
|
|
|
+ return child_range(child_iterator(), child_iterator());
|
|
|
|
+ }
|
|
|
|
+ const_child_range children() const {
|
|
|
|
+ return const_child_range(const_child_iterator(), const_child_iterator());
|
|
|
|
+ }
|
|
|
|
+};
|
|
|
|
+
|
|
} // namespace clang
|
|
} // namespace clang
|
|
|
|
|
|
#endif // LLVM_CLANG_AST_EXPRCXX_H
|
|
#endif // LLVM_CLANG_AST_EXPRCXX_H
|