llvm/clang/include/clang/AST/ExprConcepts.h

//===- ExprConcepts.h - C++2a Concepts expressions --------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
/// \file
/// Defines Expressions and AST nodes for C++2a concepts.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_EXPRCONCEPTS_H
#define LLVM_CLANG_AST_EXPRCONCEPTS_H

#include "clang/AST/ASTConcept.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/TrailingObjects.h"
#include <string>
#include <utility>

namespace clang {
class ASTStmtReader;
class ASTStmtWriter;

/// \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 {};

namespace concepts {

/// \brief A static requirement that can be used in a requires-expression to
/// check properties of types and expression.
class Requirement {};

/// \brief A requires-expression requirement which queries the existence of a
/// type name or type template specialization ('type' requirements).
class TypeRequirement : public Requirement {};

/// \brief A requires-expression requirement which queries the validity and
/// properties of an expression ('simple' and 'compound' requirements).
class ExprRequirement : public Requirement {};

/// \brief A requires-expression requirement which is satisfied when a general
/// constraint expression is satisfied ('nested' requirements).
class NestedRequirement : public Requirement {};

EntityPrinter;

/// \brief create a Requirement::SubstitutionDiagnostic with only a
/// SubstitutedEntity and DiagLoc using Sema's allocator.
Requirement::SubstitutionDiagnostic *
createSubstDiagAt(Sema &S, SourceLocation Location, EntityPrinter Printer);

} // namespace concepts

/// C++2a [expr.prim.req]:
///     A requires-expression provides a concise way to express requirements on
///     template arguments. A requirement is one that can be checked by name
///     lookup (6.4) or by checking properties of types and expressions.
///     [...]
///     A requires-expression is a prvalue of type bool [...]
class RequiresExpr final : public Expr,
    llvm::TrailingObjects<RequiresExpr, ParmVarDecl *,
                          concepts::Requirement *> {};

} // namespace clang

#endif // LLVM_CLANG_AST_EXPRCONCEPTS_H