Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- ExprConcepts.h - C++2a Concepts expressions --------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. /// \file
  10. /// Defines Expressions and AST nodes for C++2a concepts.
  11. //
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_CLANG_AST_EXPRCONCEPTS_H
  15. #define LLVM_CLANG_AST_EXPRCONCEPTS_H
  16.  
  17. #include "clang/AST/ASTContext.h"
  18. #include "clang/AST/ASTConcept.h"
  19. #include "clang/AST/Decl.h"
  20. #include "clang/AST/DeclarationName.h"
  21. #include "clang/AST/DeclTemplate.h"
  22. #include "clang/AST/Expr.h"
  23. #include "clang/AST/NestedNameSpecifier.h"
  24. #include "clang/AST/TemplateBase.h"
  25. #include "clang/AST/Type.h"
  26. #include "clang/Basic/SourceLocation.h"
  27. #include "llvm/Support/ErrorHandling.h"
  28. #include "llvm/Support/TrailingObjects.h"
  29. #include <utility>
  30. #include <string>
  31.  
  32. namespace clang {
  33. class ASTStmtReader;
  34. class ASTStmtWriter;
  35.  
  36. /// \brief Represents the specialization of a concept - evaluates to a prvalue
  37. /// of type bool.
  38. ///
  39. /// According to C++2a [expr.prim.id]p3 an id-expression that denotes the
  40. /// specialization of a concept results in a prvalue of type bool.
  41. class ConceptSpecializationExpr final : public Expr, public ConceptReference {
  42.   friend class ASTReader;
  43.   friend class ASTStmtReader;
  44.  
  45. public:
  46.   using SubstitutionDiagnostic = std::pair<SourceLocation, std::string>;
  47.  
  48. protected:
  49.   /// \brief The Implicit Concept Specialization Decl, which holds the template
  50.   /// arguments for this specialization.
  51.   ImplicitConceptSpecializationDecl *SpecDecl;
  52.  
  53.   /// \brief Information about the satisfaction of the named concept with the
  54.   /// given arguments. If this expression is value dependent, this is to be
  55.   /// ignored.
  56.   ASTConstraintSatisfaction *Satisfaction;
  57.  
  58.   ConceptSpecializationExpr(const ASTContext &C, NestedNameSpecifierLoc NNS,
  59.                             SourceLocation TemplateKWLoc,
  60.                             DeclarationNameInfo ConceptNameInfo,
  61.                             NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
  62.                             const ASTTemplateArgumentListInfo *ArgsAsWritten,
  63.                             ImplicitConceptSpecializationDecl *SpecDecl,
  64.                             const ConstraintSatisfaction *Satisfaction);
  65.  
  66.   ConceptSpecializationExpr(const ASTContext &C, ConceptDecl *NamedConcept,
  67.                             const ASTTemplateArgumentListInfo *ArgsAsWritten,
  68.                             ImplicitConceptSpecializationDecl *SpecDecl,
  69.                             const ConstraintSatisfaction *Satisfaction,
  70.                             bool Dependent,
  71.                             bool ContainsUnexpandedParameterPack);
  72.   ConceptSpecializationExpr(EmptyShell Empty);
  73.  
  74. public:
  75.   static ConceptSpecializationExpr *
  76.   Create(const ASTContext &C, NestedNameSpecifierLoc NNS,
  77.          SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
  78.          NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
  79.          const ASTTemplateArgumentListInfo *ArgsAsWritten,
  80.          ImplicitConceptSpecializationDecl *SpecDecl,
  81.          const ConstraintSatisfaction *Satisfaction);
  82.  
  83.   static ConceptSpecializationExpr *
  84.   Create(const ASTContext &C, ConceptDecl *NamedConcept,
  85.          ImplicitConceptSpecializationDecl *SpecDecl,
  86.          const ConstraintSatisfaction *Satisfaction, bool Dependent,
  87.          bool ContainsUnexpandedParameterPack);
  88.  
  89.   static ConceptSpecializationExpr *
  90.   Create(const ASTContext &C, ConceptDecl *NamedConcept,
  91.          const ASTTemplateArgumentListInfo *ArgsAsWritten,
  92.          ImplicitConceptSpecializationDecl *SpecDecl,
  93.          const ConstraintSatisfaction *Satisfaction, bool Dependent,
  94.          bool ContainsUnexpandedParameterPack);
  95.  
  96.   ArrayRef<TemplateArgument> getTemplateArguments() const {
  97.     return SpecDecl->getTemplateArguments();
  98.   }
  99.  
  100.   const ImplicitConceptSpecializationDecl *getSpecializationDecl() const {
  101.     assert(SpecDecl && "Template Argument Decl not initialized");
  102.     return SpecDecl;
  103.   }
  104.  
  105.   /// \brief Whether or not the concept with the given arguments was satisfied
  106.   /// when the expression was created.
  107.   /// The expression must not be dependent.
  108.   bool isSatisfied() const {
  109.     assert(!isValueDependent() &&
  110.            "isSatisfied called on a dependent ConceptSpecializationExpr");
  111.     return Satisfaction->IsSatisfied;
  112.   }
  113.  
  114.   /// \brief Get elaborated satisfaction info about the template arguments'
  115.   /// satisfaction of the named concept.
  116.   /// The expression must not be dependent.
  117.   const ASTConstraintSatisfaction &getSatisfaction() const {
  118.     assert(!isValueDependent() &&
  119.            "getSatisfaction called on dependent ConceptSpecializationExpr");
  120.     return *Satisfaction;
  121.   }
  122.  
  123.   static bool classof(const Stmt *T) {
  124.     return T->getStmtClass() == ConceptSpecializationExprClass;
  125.   }
  126.  
  127.   SourceLocation getBeginLoc() const LLVM_READONLY {
  128.     if (auto QualifierLoc = getNestedNameSpecifierLoc())
  129.       return QualifierLoc.getBeginLoc();
  130.     return ConceptName.getBeginLoc();
  131.   }
  132.  
  133.   SourceLocation getEndLoc() const LLVM_READONLY {
  134.     // If the ConceptSpecializationExpr is the ImmediatelyDeclaredConstraint
  135.     // of a TypeConstraint written syntactically as a constrained-parameter,
  136.     // there may not be a template argument list.
  137.     return ArgsAsWritten->RAngleLoc.isValid() ? ArgsAsWritten->RAngleLoc
  138.                                               : ConceptName.getEndLoc();
  139.   }
  140.  
  141.   // Iterators
  142.   child_range children() {
  143.     return child_range(child_iterator(), child_iterator());
  144.   }
  145.   const_child_range children() const {
  146.     return const_child_range(const_child_iterator(), const_child_iterator());
  147.   }
  148. };
  149.  
  150. namespace concepts {
  151.  
  152. /// \brief A static requirement that can be used in a requires-expression to
  153. /// check properties of types and expression.
  154. class Requirement {
  155. public:
  156.   // Note - simple and compound requirements are both represented by the same
  157.   // class (ExprRequirement).
  158.   enum RequirementKind { RK_Type, RK_Simple, RK_Compound, RK_Nested };
  159. private:
  160.   const RequirementKind Kind;
  161.   // FIXME: use RequirementDependence to model dependence?
  162.   bool Dependent : 1;
  163.   bool ContainsUnexpandedParameterPack : 1;
  164.   bool Satisfied : 1;
  165. public:
  166.   struct SubstitutionDiagnostic {
  167.     StringRef SubstitutedEntity;
  168.     // FIXME: Store diagnostics semantically and not as prerendered strings.
  169.     //  Fixing this probably requires serialization of PartialDiagnostic
  170.     //  objects.
  171.     SourceLocation DiagLoc;
  172.     StringRef DiagMessage;
  173.   };
  174.  
  175.   Requirement(RequirementKind Kind, bool IsDependent,
  176.               bool ContainsUnexpandedParameterPack, bool IsSatisfied = true) :
  177.       Kind(Kind), Dependent(IsDependent),
  178.       ContainsUnexpandedParameterPack(ContainsUnexpandedParameterPack),
  179.       Satisfied(IsSatisfied) {}
  180.  
  181.   RequirementKind getKind() const { return Kind; }
  182.  
  183.   bool isSatisfied() const {
  184.     assert(!Dependent &&
  185.            "isSatisfied can only be called on non-dependent requirements.");
  186.     return Satisfied;
  187.   }
  188.  
  189.   void setSatisfied(bool IsSatisfied) {
  190.     assert(!Dependent &&
  191.            "setSatisfied can only be called on non-dependent requirements.");
  192.     Satisfied = IsSatisfied;
  193.   }
  194.  
  195.   void setDependent(bool IsDependent) { Dependent = IsDependent; }
  196.   bool isDependent() const { return Dependent; }
  197.  
  198.   void setContainsUnexpandedParameterPack(bool Contains) {
  199.     ContainsUnexpandedParameterPack = Contains;
  200.   }
  201.   bool containsUnexpandedParameterPack() const {
  202.     return ContainsUnexpandedParameterPack;
  203.   }
  204. };
  205.  
  206. /// \brief A requires-expression requirement which queries the existence of a
  207. /// type name or type template specialization ('type' requirements).
  208. class TypeRequirement : public Requirement {
  209. public:
  210.   enum SatisfactionStatus {
  211.       SS_Dependent,
  212.       SS_SubstitutionFailure,
  213.       SS_Satisfied
  214.   };
  215. private:
  216.   llvm::PointerUnion<SubstitutionDiagnostic *, TypeSourceInfo *> Value;
  217.   SatisfactionStatus Status;
  218. public:
  219.   friend ASTStmtReader;
  220.   friend ASTStmtWriter;
  221.  
  222.   /// \brief Construct a type requirement from a type. If the given type is not
  223.   /// dependent, this indicates that the type exists and the requirement will be
  224.   /// satisfied. Otherwise, the SubstitutionDiagnostic constructor is to be
  225.   /// used.
  226.   TypeRequirement(TypeSourceInfo *T);
  227.  
  228.   /// \brief Construct a type requirement when the nested name specifier is
  229.   /// invalid due to a bad substitution. The requirement is unsatisfied.
  230.   TypeRequirement(SubstitutionDiagnostic *Diagnostic) :
  231.       Requirement(RK_Type, false, false, false), Value(Diagnostic),
  232.       Status(SS_SubstitutionFailure) {}
  233.  
  234.   SatisfactionStatus getSatisfactionStatus() const { return Status; }
  235.   void setSatisfactionStatus(SatisfactionStatus Status) {
  236.     this->Status = Status;
  237.   }
  238.  
  239.   bool isSubstitutionFailure() const {
  240.     return Status == SS_SubstitutionFailure;
  241.   }
  242.  
  243.   SubstitutionDiagnostic *getSubstitutionDiagnostic() const {
  244.     assert(Status == SS_SubstitutionFailure &&
  245.            "Attempted to get substitution diagnostic when there has been no "
  246.            "substitution failure.");
  247.     return Value.get<SubstitutionDiagnostic *>();
  248.   }
  249.  
  250.   TypeSourceInfo *getType() const {
  251.     assert(!isSubstitutionFailure() &&
  252.            "Attempted to get type when there has been a substitution failure.");
  253.     return Value.get<TypeSourceInfo *>();
  254.   }
  255.  
  256.   static bool classof(const Requirement *R) {
  257.     return R->getKind() == RK_Type;
  258.   }
  259. };
  260.  
  261. /// \brief A requires-expression requirement which queries the validity and
  262. /// properties of an expression ('simple' and 'compound' requirements).
  263. class ExprRequirement : public Requirement {
  264. public:
  265.   enum SatisfactionStatus {
  266.       SS_Dependent,
  267.       SS_ExprSubstitutionFailure,
  268.       SS_NoexceptNotMet,
  269.       SS_TypeRequirementSubstitutionFailure,
  270.       SS_ConstraintsNotSatisfied,
  271.       SS_Satisfied
  272.   };
  273.   class ReturnTypeRequirement {
  274.       llvm::PointerIntPair<
  275.           llvm::PointerUnion<TemplateParameterList *, SubstitutionDiagnostic *>,
  276.           1, bool>
  277.           TypeConstraintInfo;
  278.   public:
  279.       friend ASTStmtReader;
  280.       friend ASTStmtWriter;
  281.  
  282.       /// \brief No return type requirement was specified.
  283.       ReturnTypeRequirement() : TypeConstraintInfo(nullptr, false) {}
  284.  
  285.       /// \brief A return type requirement was specified but it was a
  286.       /// substitution failure.
  287.       ReturnTypeRequirement(SubstitutionDiagnostic *SubstDiag) :
  288.           TypeConstraintInfo(SubstDiag, false) {}
  289.  
  290.       /// \brief A 'type constraint' style return type requirement.
  291.       /// \param TPL an invented template parameter list containing a single
  292.       /// type parameter with a type-constraint.
  293.       // TODO: Can we maybe not save the whole template parameter list and just
  294.       //  the type constraint? Saving the whole TPL makes it easier to handle in
  295.       //  serialization but is less elegant.
  296.       ReturnTypeRequirement(TemplateParameterList *TPL);
  297.  
  298.       bool isDependent() const {
  299.         return TypeConstraintInfo.getInt();
  300.       }
  301.  
  302.       bool containsUnexpandedParameterPack() const {
  303.         if (!isTypeConstraint())
  304.           return false;
  305.         return getTypeConstraintTemplateParameterList()
  306.                 ->containsUnexpandedParameterPack();
  307.       }
  308.  
  309.       bool isEmpty() const {
  310.         return TypeConstraintInfo.getPointer().isNull();
  311.       }
  312.  
  313.       bool isSubstitutionFailure() const {
  314.         return !isEmpty() &&
  315.             TypeConstraintInfo.getPointer().is<SubstitutionDiagnostic *>();
  316.       }
  317.  
  318.       bool isTypeConstraint() const {
  319.         return !isEmpty() &&
  320.             TypeConstraintInfo.getPointer().is<TemplateParameterList *>();
  321.       }
  322.  
  323.       SubstitutionDiagnostic *getSubstitutionDiagnostic() const {
  324.         assert(isSubstitutionFailure());
  325.         return TypeConstraintInfo.getPointer().get<SubstitutionDiagnostic *>();
  326.       }
  327.  
  328.       const TypeConstraint *getTypeConstraint() const;
  329.  
  330.       TemplateParameterList *getTypeConstraintTemplateParameterList() const {
  331.         assert(isTypeConstraint());
  332.         return TypeConstraintInfo.getPointer().get<TemplateParameterList *>();
  333.       }
  334.   };
  335. private:
  336.   llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> Value;
  337.   SourceLocation NoexceptLoc; // May be empty if noexcept wasn't specified.
  338.   ReturnTypeRequirement TypeReq;
  339.   ConceptSpecializationExpr *SubstitutedConstraintExpr;
  340.   SatisfactionStatus Status;
  341. public:
  342.   friend ASTStmtReader;
  343.   friend ASTStmtWriter;
  344.  
  345.   /// \brief Construct a compound requirement.
  346.   /// \param E the expression which is checked by this requirement.
  347.   /// \param IsSimple whether this was a simple requirement in source.
  348.   /// \param NoexceptLoc the location of the noexcept keyword, if it was
  349.   /// specified, otherwise an empty location.
  350.   /// \param Req the requirement for the type of the checked expression.
  351.   /// \param Status the satisfaction status of this requirement.
  352.   ExprRequirement(
  353.       Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
  354.       ReturnTypeRequirement Req, SatisfactionStatus Status,
  355.       ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr);
  356.  
  357.   /// \brief Construct a compound requirement whose expression was a
  358.   /// substitution failure. The requirement is not satisfied.
  359.   /// \param E the diagnostic emitted while instantiating the original
  360.   /// expression.
  361.   /// \param IsSimple whether this was a simple requirement in source.
  362.   /// \param NoexceptLoc the location of the noexcept keyword, if it was
  363.   /// specified, otherwise an empty location.
  364.   /// \param Req the requirement for the type of the checked expression (omit
  365.   /// if no requirement was specified).
  366.   ExprRequirement(SubstitutionDiagnostic *E, bool IsSimple,
  367.                   SourceLocation NoexceptLoc, ReturnTypeRequirement Req = {});
  368.  
  369.   bool isSimple() const { return getKind() == RK_Simple; }
  370.   bool isCompound() const { return getKind() == RK_Compound; }
  371.  
  372.   bool hasNoexceptRequirement() const { return NoexceptLoc.isValid(); }
  373.   SourceLocation getNoexceptLoc() const { return NoexceptLoc; }
  374.  
  375.   SatisfactionStatus getSatisfactionStatus() const { return Status; }
  376.  
  377.   bool isExprSubstitutionFailure() const {
  378.     return Status == SS_ExprSubstitutionFailure;
  379.   }
  380.  
  381.   const ReturnTypeRequirement &getReturnTypeRequirement() const {
  382.     return TypeReq;
  383.   }
  384.  
  385.   ConceptSpecializationExpr *
  386.   getReturnTypeRequirementSubstitutedConstraintExpr() const {
  387.     assert(Status >= SS_TypeRequirementSubstitutionFailure);
  388.     return SubstitutedConstraintExpr;
  389.   }
  390.  
  391.   SubstitutionDiagnostic *getExprSubstitutionDiagnostic() const {
  392.     assert(isExprSubstitutionFailure() &&
  393.            "Attempted to get expression substitution diagnostic when there has "
  394.            "been no expression substitution failure");
  395.     return Value.get<SubstitutionDiagnostic *>();
  396.   }
  397.  
  398.   Expr *getExpr() const {
  399.     assert(!isExprSubstitutionFailure() &&
  400.            "ExprRequirement has no expression because there has been a "
  401.            "substitution failure.");
  402.     return Value.get<Expr *>();
  403.   }
  404.  
  405.   static bool classof(const Requirement *R) {
  406.     return R->getKind() == RK_Compound || R->getKind() == RK_Simple;
  407.   }
  408. };
  409.  
  410. /// \brief A requires-expression requirement which is satisfied when a general
  411. /// constraint expression is satisfied ('nested' requirements).
  412. class NestedRequirement : public Requirement {
  413.   Expr *Constraint = nullptr;
  414.   const ASTConstraintSatisfaction *Satisfaction = nullptr;
  415.   bool HasInvalidConstraint = false;
  416.   StringRef InvalidConstraintEntity;
  417.  
  418. public:
  419.   friend ASTStmtReader;
  420.   friend ASTStmtWriter;
  421.  
  422.   NestedRequirement(Expr *Constraint)
  423.       : Requirement(RK_Nested, /*IsDependent=*/true,
  424.                     Constraint->containsUnexpandedParameterPack()),
  425.         Constraint(Constraint) {
  426.     assert(Constraint->isInstantiationDependent() &&
  427.            "Nested requirement with non-dependent constraint must be "
  428.            "constructed with a ConstraintSatisfaction object");
  429.   }
  430.  
  431.   NestedRequirement(ASTContext &C, Expr *Constraint,
  432.                     const ConstraintSatisfaction &Satisfaction)
  433.       : Requirement(RK_Nested, Constraint->isInstantiationDependent(),
  434.                     Constraint->containsUnexpandedParameterPack(),
  435.                     Satisfaction.IsSatisfied),
  436.         Constraint(Constraint),
  437.         Satisfaction(ASTConstraintSatisfaction::Create(C, Satisfaction)) {}
  438.  
  439.   NestedRequirement(StringRef InvalidConstraintEntity,
  440.                     const ASTConstraintSatisfaction *Satisfaction)
  441.       : Requirement(RK_Nested,
  442.                     /*IsDependent=*/false,
  443.                     /*ContainsUnexpandedParameterPack*/ false,
  444.                     Satisfaction->IsSatisfied),
  445.         Satisfaction(Satisfaction), HasInvalidConstraint(true),
  446.         InvalidConstraintEntity(InvalidConstraintEntity) {}
  447.  
  448.   NestedRequirement(ASTContext &C, StringRef InvalidConstraintEntity,
  449.                     const ConstraintSatisfaction &Satisfaction)
  450.       : NestedRequirement(InvalidConstraintEntity,
  451.                           ASTConstraintSatisfaction::Create(C, Satisfaction)) {}
  452.  
  453.   bool hasInvalidConstraint() const { return HasInvalidConstraint; }
  454.  
  455.   StringRef getInvalidConstraintEntity() {
  456.     assert(hasInvalidConstraint());
  457.     return InvalidConstraintEntity;
  458.   }
  459.  
  460.   Expr *getConstraintExpr() const {
  461.     assert(!hasInvalidConstraint() &&
  462.            "getConstraintExpr() may not be called "
  463.            "on nested requirements with invalid constraint.");
  464.     return Constraint;
  465.   }
  466.  
  467.   const ASTConstraintSatisfaction &getConstraintSatisfaction() const {
  468.     return *Satisfaction;
  469.   }
  470.  
  471.   static bool classof(const Requirement *R) {
  472.     return R->getKind() == RK_Nested;
  473.   }
  474. };
  475.  
  476. } // namespace concepts
  477.  
  478. /// C++2a [expr.prim.req]:
  479. ///     A requires-expression provides a concise way to express requirements on
  480. ///     template arguments. A requirement is one that can be checked by name
  481. ///     lookup (6.4) or by checking properties of types and expressions.
  482. ///     [...]
  483. ///     A requires-expression is a prvalue of type bool [...]
  484. class RequiresExpr final : public Expr,
  485.     llvm::TrailingObjects<RequiresExpr, ParmVarDecl *,
  486.                           concepts::Requirement *> {
  487.   friend TrailingObjects;
  488.   friend class ASTStmtReader;
  489.  
  490.   unsigned NumLocalParameters;
  491.   unsigned NumRequirements;
  492.   RequiresExprBodyDecl *Body;
  493.   SourceLocation RBraceLoc;
  494.  
  495.   unsigned numTrailingObjects(OverloadToken<ParmVarDecl *>) const {
  496.     return NumLocalParameters;
  497.   }
  498.  
  499.   unsigned numTrailingObjects(OverloadToken<concepts::Requirement *>) const {
  500.     return NumRequirements;
  501.   }
  502.  
  503.   RequiresExpr(ASTContext &C, SourceLocation RequiresKWLoc,
  504.                RequiresExprBodyDecl *Body,
  505.                ArrayRef<ParmVarDecl *> LocalParameters,
  506.                ArrayRef<concepts::Requirement *> Requirements,
  507.                SourceLocation RBraceLoc);
  508.   RequiresExpr(ASTContext &C, EmptyShell Empty, unsigned NumLocalParameters,
  509.                unsigned NumRequirements);
  510.  
  511. public:
  512.   static RequiresExpr *
  513.   Create(ASTContext &C, SourceLocation RequiresKWLoc,
  514.          RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> LocalParameters,
  515.          ArrayRef<concepts::Requirement *> Requirements,
  516.          SourceLocation RBraceLoc);
  517.   static RequiresExpr *
  518.   Create(ASTContext &C, EmptyShell Empty, unsigned NumLocalParameters,
  519.          unsigned NumRequirements);
  520.  
  521.   ArrayRef<ParmVarDecl *> getLocalParameters() const {
  522.     return {getTrailingObjects<ParmVarDecl *>(), NumLocalParameters};
  523.   }
  524.  
  525.   RequiresExprBodyDecl *getBody() const { return Body; }
  526.  
  527.   ArrayRef<concepts::Requirement *> getRequirements() const {
  528.     return {getTrailingObjects<concepts::Requirement *>(), NumRequirements};
  529.   }
  530.  
  531.   /// \brief Whether or not the requires clause is satisfied.
  532.   /// The expression must not be dependent.
  533.   bool isSatisfied() const {
  534.     assert(!isValueDependent()
  535.            && "isSatisfied called on a dependent RequiresExpr");
  536.     return RequiresExprBits.IsSatisfied;
  537.   }
  538.  
  539.   void setSatisfied(bool IsSatisfied) {
  540.     assert(!isValueDependent() &&
  541.            "setSatisfied called on a dependent RequiresExpr");
  542.     RequiresExprBits.IsSatisfied = IsSatisfied;
  543.   }
  544.  
  545.   SourceLocation getRequiresKWLoc() const {
  546.     return RequiresExprBits.RequiresKWLoc;
  547.   }
  548.  
  549.   SourceLocation getRBraceLoc() const { return RBraceLoc; }
  550.  
  551.   static bool classof(const Stmt *T) {
  552.     return T->getStmtClass() == RequiresExprClass;
  553.   }
  554.  
  555.   SourceLocation getBeginLoc() const LLVM_READONLY {
  556.     return RequiresExprBits.RequiresKWLoc;
  557.   }
  558.   SourceLocation getEndLoc() const LLVM_READONLY {
  559.     return RBraceLoc;
  560.   }
  561.  
  562.   // Iterators
  563.   child_range children() {
  564.     return child_range(child_iterator(), child_iterator());
  565.   }
  566.   const_child_range children() const {
  567.     return const_child_range(const_child_iterator(), const_child_iterator());
  568.   }
  569. };
  570.  
  571. } // namespace clang
  572.  
  573. #endif // LLVM_CLANG_AST_EXPRCONCEPTS_H
  574.