Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

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

  1. //===- StmtOpenMP.h - Classes for OpenMP directives  ------------*- 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. /// \file
  9. /// This file defines OpenMP AST classes for executable directives and
  10. /// clauses.
  11. ///
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_CLANG_AST_STMTOPENMP_H
  15. #define LLVM_CLANG_AST_STMTOPENMP_H
  16.  
  17. #include "clang/AST/ASTContext.h"
  18. #include "clang/AST/Expr.h"
  19. #include "clang/AST/OpenMPClause.h"
  20. #include "clang/AST/Stmt.h"
  21. #include "clang/AST/StmtCXX.h"
  22. #include "clang/Basic/OpenMPKinds.h"
  23. #include "clang/Basic/SourceLocation.h"
  24.  
  25. namespace clang {
  26.  
  27. //===----------------------------------------------------------------------===//
  28. // AST classes for directives.
  29. //===----------------------------------------------------------------------===//
  30.  
  31. /// Representation of an OpenMP canonical loop.
  32. ///
  33. /// OpenMP 1.0 C/C++, section 2.4.1 for Construct; canonical-shape
  34. /// OpenMP 2.0 C/C++, section 2.4.1 for Construct; canonical-shape
  35. /// OpenMP 2.5, section 2.5.1 Loop Construct; canonical form
  36. /// OpenMP 3.1, section 2.5.1 Loop Construct; canonical form
  37. /// OpenMP 4.0, section 2.6 Canonical Loop Form
  38. /// OpenMP 4.5, section 2.6 Canonical Loop Form
  39. /// OpenMP 5.0, section 2.9.1 Canonical Loop Form
  40. /// OpenMP 5.1, section 2.11.1 Canonical Loop Nest Form
  41. ///
  42. /// An OpenMP canonical loop is a for-statement or range-based for-statement
  43. /// with additional requirements that ensure that the number of iterations is
  44. /// known before entering the loop and allow skipping to an arbitrary iteration.
  45. /// The OMPCanonicalLoop AST node wraps a ForStmt or CXXForRangeStmt that is
  46. /// known to fulfill OpenMP's canonical loop requirements because of being
  47. /// associated to an OMPLoopBasedDirective. That is, the general structure is:
  48. ///
  49. ///  OMPLoopBasedDirective
  50. /// [`- CapturedStmt   ]
  51. /// [   `- CapturedDecl]
  52. ///        ` OMPCanonicalLoop
  53. ///          `- ForStmt/CXXForRangeStmt
  54. ///             `- Stmt
  55. ///
  56. /// One or multiple CapturedStmt/CapturedDecl pairs may be inserted by some
  57. /// directives such as OMPParallelForDirective, but others do not need them
  58. /// (such as OMPTileDirective). In  The OMPCanonicalLoop and
  59. /// ForStmt/CXXForRangeStmt pair is repeated for loop associated with the
  60. /// directive. A OMPCanonicalLoop must not appear in the AST unless associated
  61. /// with a OMPLoopBasedDirective. In an imperfectly nested loop nest, the
  62. /// OMPCanonicalLoop may also be wrapped in a CompoundStmt:
  63. ///
  64. /// [...]
  65. ///  ` OMPCanonicalLoop
  66. ///    `- ForStmt/CXXForRangeStmt
  67. ///       `- CompoundStmt
  68. ///          |- Leading in-between code (if any)
  69. ///          |- OMPCanonicalLoop
  70. ///          |  `- ForStmt/CXXForRangeStmt
  71. ///          |     `- ...
  72. ///          `- Trailing in-between code (if any)
  73. ///
  74. /// The leading/trailing in-between code must not itself be a OMPCanonicalLoop
  75. /// to avoid confusion which loop belongs to the nesting.
  76. ///
  77. /// There are three different kinds of iteration variables for different
  78. /// purposes:
  79. /// * Loop user variable: The user-accessible variable with different value for
  80. ///   each iteration.
  81. /// * Loop iteration variable: The variable used to identify a loop iteration;
  82. ///   for range-based for-statement, this is the hidden iterator '__begin'. For
  83. ///   other loops, it is identical to the loop user variable. Must be a
  84. ///   random-access iterator, pointer or integer type.
  85. /// * Logical iteration counter: Normalized loop counter starting at 0 and
  86. ///   incrementing by one at each iteration. Allows abstracting over the type
  87. ///   of the loop iteration variable and is always an unsigned integer type
  88. ///   appropriate to represent the range of the loop iteration variable. Its
  89. ///   value corresponds to the logical iteration number in the OpenMP
  90. ///   specification.
  91. ///
  92. /// This AST node provides two captured statements:
  93. /// * The distance function which computes the number of iterations.
  94. /// * The loop user variable function that computes the loop user variable when
  95. ///   given a logical iteration number.
  96. ///
  97. /// These captured statements provide the link between C/C++ semantics and the
  98. /// logical iteration counters used by the OpenMPIRBuilder which is
  99. /// language-agnostic and therefore does not know e.g. how to advance a
  100. /// random-access iterator. The OpenMPIRBuilder will use this information to
  101. /// apply simd, workshare-loop, distribute, taskloop and loop directives to the
  102. /// loop. For compatibility with the non-OpenMPIRBuilder codegen path, an
  103. /// OMPCanonicalLoop can itself also be wrapped into the CapturedStmts of an
  104. /// OMPLoopDirective and skipped when searching for the associated syntactical
  105. /// loop.
  106. ///
  107. /// Example:
  108. /// <code>
  109. ///   std::vector<std::string> Container{1,2,3};
  110. ///   for (std::string Str : Container)
  111. ///      Body(Str);
  112. /// </code>
  113. /// which is syntactic sugar for approximately:
  114. /// <code>
  115. ///   auto &&__range = Container;
  116. ///   auto __begin = std::begin(__range);
  117. ///   auto __end = std::end(__range);
  118. ///   for (; __begin != __end; ++__begin) {
  119. ///     std::String Str = *__begin;
  120. ///     Body(Str);
  121. ///   }
  122. /// </code>
  123. /// In this example, the loop user variable is `Str`, the loop iteration
  124. /// variable is `__begin` of type `std::vector<std::string>::iterator` and the
  125. /// logical iteration number type is `size_t` (unsigned version of
  126. /// `std::vector<std::string>::iterator::difference_type` aka `ptrdiff_t`).
  127. /// Therefore, the distance function will be
  128. /// <code>
  129. ///   [&](size_t &Result) { Result = __end - __begin; }
  130. /// </code>
  131. /// and the loop variable function is
  132. /// <code>
  133. ///   [&,__begin](std::vector<std::string>::iterator &Result, size_t Logical) {
  134. ///     Result = __begin + Logical;
  135. ///   }
  136. /// </code>
  137. /// The variable `__begin`, aka the loop iteration variable, is captured by
  138. /// value because it is modified in the loop body, but both functions require
  139. /// the initial value. The OpenMP specification explicitly leaves unspecified
  140. /// when the loop expressions are evaluated such that a capture by reference is
  141. /// sufficient.
  142. class OMPCanonicalLoop : public Stmt {
  143.   friend class ASTStmtReader;
  144.   friend class ASTStmtWriter;
  145.  
  146.   /// Children of this AST node.
  147.   enum {
  148.     LOOP_STMT,
  149.     DISTANCE_FUNC,
  150.     LOOPVAR_FUNC,
  151.     LOOPVAR_REF,
  152.     LastSubStmt = LOOPVAR_REF
  153.   };
  154.  
  155. private:
  156.   /// This AST node's children.
  157.   Stmt *SubStmts[LastSubStmt + 1] = {};
  158.  
  159.   OMPCanonicalLoop() : Stmt(StmtClass::OMPCanonicalLoopClass) {}
  160.  
  161. public:
  162.   /// Create a new OMPCanonicalLoop.
  163.   static OMPCanonicalLoop *create(const ASTContext &Ctx, Stmt *LoopStmt,
  164.                                   CapturedStmt *DistanceFunc,
  165.                                   CapturedStmt *LoopVarFunc,
  166.                                   DeclRefExpr *LoopVarRef) {
  167.     OMPCanonicalLoop *S = new (Ctx) OMPCanonicalLoop();
  168.     S->setLoopStmt(LoopStmt);
  169.     S->setDistanceFunc(DistanceFunc);
  170.     S->setLoopVarFunc(LoopVarFunc);
  171.     S->setLoopVarRef(LoopVarRef);
  172.     return S;
  173.   }
  174.  
  175.   /// Create an empty OMPCanonicalLoop for deserialization.
  176.   static OMPCanonicalLoop *createEmpty(const ASTContext &Ctx) {
  177.     return new (Ctx) OMPCanonicalLoop();
  178.   }
  179.  
  180.   static bool classof(const Stmt *S) {
  181.     return S->getStmtClass() == StmtClass::OMPCanonicalLoopClass;
  182.   }
  183.  
  184.   SourceLocation getBeginLoc() const { return getLoopStmt()->getBeginLoc(); }
  185.   SourceLocation getEndLoc() const { return getLoopStmt()->getEndLoc(); }
  186.  
  187.   /// Return this AST node's children.
  188.   /// @{
  189.   child_range children() {
  190.     return child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1);
  191.   }
  192.   const_child_range children() const {
  193.     return const_child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1);
  194.   }
  195.   /// @}
  196.  
  197.   /// The wrapped syntactic loop statement (ForStmt or CXXForRangeStmt).
  198.   /// @{
  199.   Stmt *getLoopStmt() { return SubStmts[LOOP_STMT]; }
  200.   const Stmt *getLoopStmt() const { return SubStmts[LOOP_STMT]; }
  201.   void setLoopStmt(Stmt *S) {
  202.     assert((isa<ForStmt>(S) || isa<CXXForRangeStmt>(S)) &&
  203.            "Canonical loop must be a for loop (range-based or otherwise)");
  204.     SubStmts[LOOP_STMT] = S;
  205.   }
  206.   /// @}
  207.  
  208.   /// The function that computes the number of loop iterations. Can be evaluated
  209.   /// before entering the loop but after the syntactical loop's init
  210.   /// statement(s).
  211.   ///
  212.   /// Function signature: void(LogicalTy &Result)
  213.   /// Any values necessary to compute the distance are captures of the closure.
  214.   /// @{
  215.   CapturedStmt *getDistanceFunc() {
  216.     return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]);
  217.   }
  218.   const CapturedStmt *getDistanceFunc() const {
  219.     return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]);
  220.   }
  221.   void setDistanceFunc(CapturedStmt *S) {
  222.     assert(S && "Expected non-null captured statement");
  223.     SubStmts[DISTANCE_FUNC] = S;
  224.   }
  225.   /// @}
  226.  
  227.   /// The function that computes the loop user variable from a logical iteration
  228.   /// counter. Can be evaluated as first statement in the loop.
  229.   ///
  230.   /// Function signature: void(LoopVarTy &Result, LogicalTy Number)
  231.   /// Any other values required to compute the loop user variable (such as start
  232.   /// value, step size) are captured by the closure. In particular, the initial
  233.   /// value of loop iteration variable is captured by value to be unaffected by
  234.   /// previous iterations.
  235.   /// @{
  236.   CapturedStmt *getLoopVarFunc() {
  237.     return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]);
  238.   }
  239.   const CapturedStmt *getLoopVarFunc() const {
  240.     return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]);
  241.   }
  242.   void setLoopVarFunc(CapturedStmt *S) {
  243.     assert(S && "Expected non-null captured statement");
  244.     SubStmts[LOOPVAR_FUNC] = S;
  245.   }
  246.   /// @}
  247.  
  248.   /// Reference to the loop user variable as accessed in the loop body.
  249.   /// @{
  250.   DeclRefExpr *getLoopVarRef() {
  251.     return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]);
  252.   }
  253.   const DeclRefExpr *getLoopVarRef() const {
  254.     return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]);
  255.   }
  256.   void setLoopVarRef(DeclRefExpr *E) {
  257.     assert(E && "Expected non-null loop variable");
  258.     SubStmts[LOOPVAR_REF] = E;
  259.   }
  260.   /// @}
  261. };
  262.  
  263. /// This is a basic class for representing single OpenMP executable
  264. /// directive.
  265. ///
  266. class OMPExecutableDirective : public Stmt {
  267.   friend class ASTStmtReader;
  268.   friend class ASTStmtWriter;
  269.  
  270.   /// Kind of the directive.
  271.   OpenMPDirectiveKind Kind = llvm::omp::OMPD_unknown;
  272.   /// Starting location of the directive (directive keyword).
  273.   SourceLocation StartLoc;
  274.   /// Ending location of the directive.
  275.   SourceLocation EndLoc;
  276.  
  277.   /// Get the clauses storage.
  278.   MutableArrayRef<OMPClause *> getClauses() {
  279.     if (!Data)
  280.       return std::nullopt;
  281.     return Data->getClauses();
  282.   }
  283.  
  284. protected:
  285.   /// Data, associated with the directive.
  286.   OMPChildren *Data = nullptr;
  287.  
  288.   /// Build instance of directive of class \a K.
  289.   ///
  290.   /// \param SC Statement class.
  291.   /// \param K Kind of OpenMP directive.
  292.   /// \param StartLoc Starting location of the directive (directive keyword).
  293.   /// \param EndLoc Ending location of the directive.
  294.   ///
  295.   OMPExecutableDirective(StmtClass SC, OpenMPDirectiveKind K,
  296.                          SourceLocation StartLoc, SourceLocation EndLoc)
  297.       : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
  298.         EndLoc(std::move(EndLoc)) {}
  299.  
  300.   template <typename T, typename... Params>
  301.   static T *createDirective(const ASTContext &C, ArrayRef<OMPClause *> Clauses,
  302.                             Stmt *AssociatedStmt, unsigned NumChildren,
  303.                             Params &&... P) {
  304.     void *Mem =
  305.         C.Allocate(sizeof(T) + OMPChildren::size(Clauses.size(), AssociatedStmt,
  306.                                                  NumChildren),
  307.                    alignof(T));
  308.  
  309.     auto *Data = OMPChildren::Create(reinterpret_cast<T *>(Mem) + 1, Clauses,
  310.                                      AssociatedStmt, NumChildren);
  311.     auto *Inst = new (Mem) T(std::forward<Params>(P)...);
  312.     Inst->Data = Data;
  313.     return Inst;
  314.   }
  315.  
  316.   template <typename T, typename... Params>
  317.   static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses,
  318.                                  bool HasAssociatedStmt, unsigned NumChildren,
  319.                                  Params &&... P) {
  320.     void *Mem =
  321.         C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt,
  322.                                                  NumChildren),
  323.                    alignof(T));
  324.     auto *Data =
  325.         OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses,
  326.                                  HasAssociatedStmt, NumChildren);
  327.     auto *Inst = new (Mem) T(std::forward<Params>(P)...);
  328.     Inst->Data = Data;
  329.     return Inst;
  330.   }
  331.  
  332.   template <typename T>
  333.   static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses,
  334.                                  bool HasAssociatedStmt = false,
  335.                                  unsigned NumChildren = 0) {
  336.     void *Mem =
  337.         C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt,
  338.                                                  NumChildren),
  339.                    alignof(T));
  340.     auto *Data =
  341.         OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses,
  342.                                  HasAssociatedStmt, NumChildren);
  343.     auto *Inst = new (Mem) T;
  344.     Inst->Data = Data;
  345.     return Inst;
  346.   }
  347.  
  348. public:
  349.   /// Iterates over expressions/statements used in the construct.
  350.   class used_clauses_child_iterator
  351.       : public llvm::iterator_adaptor_base<
  352.             used_clauses_child_iterator, ArrayRef<OMPClause *>::iterator,
  353.             std::forward_iterator_tag, Stmt *, ptrdiff_t, Stmt *, Stmt *> {
  354.     ArrayRef<OMPClause *>::iterator End;
  355.     OMPClause::child_iterator ChildI, ChildEnd;
  356.  
  357.     void MoveToNext() {
  358.       if (ChildI != ChildEnd)
  359.         return;
  360.       while (this->I != End) {
  361.         ++this->I;
  362.         if (this->I != End) {
  363.           ChildI = (*this->I)->used_children().begin();
  364.           ChildEnd = (*this->I)->used_children().end();
  365.           if (ChildI != ChildEnd)
  366.             return;
  367.         }
  368.       }
  369.     }
  370.  
  371.   public:
  372.     explicit used_clauses_child_iterator(ArrayRef<OMPClause *> Clauses)
  373.         : used_clauses_child_iterator::iterator_adaptor_base(Clauses.begin()),
  374.           End(Clauses.end()) {
  375.       if (this->I != End) {
  376.         ChildI = (*this->I)->used_children().begin();
  377.         ChildEnd = (*this->I)->used_children().end();
  378.         MoveToNext();
  379.       }
  380.     }
  381.     Stmt *operator*() const { return *ChildI; }
  382.     Stmt *operator->() const { return **this; }
  383.  
  384.     used_clauses_child_iterator &operator++() {
  385.       ++ChildI;
  386.       if (ChildI != ChildEnd)
  387.         return *this;
  388.       if (this->I != End) {
  389.         ++this->I;
  390.         if (this->I != End) {
  391.           ChildI = (*this->I)->used_children().begin();
  392.           ChildEnd = (*this->I)->used_children().end();
  393.         }
  394.       }
  395.       MoveToNext();
  396.       return *this;
  397.     }
  398.   };
  399.  
  400.   static llvm::iterator_range<used_clauses_child_iterator>
  401.   used_clauses_children(ArrayRef<OMPClause *> Clauses) {
  402.     return {
  403.         used_clauses_child_iterator(Clauses),
  404.         used_clauses_child_iterator(llvm::ArrayRef(Clauses.end(), (size_t)0))};
  405.   }
  406.  
  407.   /// Iterates over a filtered subrange of clauses applied to a
  408.   /// directive.
  409.   ///
  410.   /// This iterator visits only clauses of type SpecificClause.
  411.   template <typename SpecificClause>
  412.   class specific_clause_iterator
  413.       : public llvm::iterator_adaptor_base<
  414.             specific_clause_iterator<SpecificClause>,
  415.             ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag,
  416.             const SpecificClause *, ptrdiff_t, const SpecificClause *,
  417.             const SpecificClause *> {
  418.     ArrayRef<OMPClause *>::const_iterator End;
  419.  
  420.     void SkipToNextClause() {
  421.       while (this->I != End && !isa<SpecificClause>(*this->I))
  422.         ++this->I;
  423.     }
  424.  
  425.   public:
  426.     explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses)
  427.         : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()),
  428.           End(Clauses.end()) {
  429.       SkipToNextClause();
  430.     }
  431.  
  432.     const SpecificClause *operator*() const {
  433.       return cast<SpecificClause>(*this->I);
  434.     }
  435.     const SpecificClause *operator->() const { return **this; }
  436.  
  437.     specific_clause_iterator &operator++() {
  438.       ++this->I;
  439.       SkipToNextClause();
  440.       return *this;
  441.     }
  442.   };
  443.  
  444.   template <typename SpecificClause>
  445.   static llvm::iterator_range<specific_clause_iterator<SpecificClause>>
  446.   getClausesOfKind(ArrayRef<OMPClause *> Clauses) {
  447.     return {specific_clause_iterator<SpecificClause>(Clauses),
  448.             specific_clause_iterator<SpecificClause>(
  449.                 llvm::ArrayRef(Clauses.end(), (size_t)0))};
  450.   }
  451.  
  452.   template <typename SpecificClause>
  453.   llvm::iterator_range<specific_clause_iterator<SpecificClause>>
  454.   getClausesOfKind() const {
  455.     return getClausesOfKind<SpecificClause>(clauses());
  456.   }
  457.  
  458.   /// Gets a single clause of the specified kind associated with the
  459.   /// current directive iff there is only one clause of this kind (and assertion
  460.   /// is fired if there is more than one clause is associated with the
  461.   /// directive). Returns nullptr if no clause of this kind is associated with
  462.   /// the directive.
  463.   template <typename SpecificClause>
  464.   static const SpecificClause *getSingleClause(ArrayRef<OMPClause *> Clauses) {
  465.     auto ClausesOfKind = getClausesOfKind<SpecificClause>(Clauses);
  466.  
  467.     if (ClausesOfKind.begin() != ClausesOfKind.end()) {
  468.       assert(std::next(ClausesOfKind.begin()) == ClausesOfKind.end() &&
  469.              "There are at least 2 clauses of the specified kind");
  470.       return *ClausesOfKind.begin();
  471.     }
  472.     return nullptr;
  473.   }
  474.  
  475.   template <typename SpecificClause>
  476.   const SpecificClause *getSingleClause() const {
  477.     return getSingleClause<SpecificClause>(clauses());
  478.   }
  479.  
  480.   /// Returns true if the current directive has one or more clauses of a
  481.   /// specific kind.
  482.   template <typename SpecificClause>
  483.   bool hasClausesOfKind() const {
  484.     auto Clauses = getClausesOfKind<SpecificClause>();
  485.     return Clauses.begin() != Clauses.end();
  486.   }
  487.  
  488.   /// Returns starting location of directive kind.
  489.   SourceLocation getBeginLoc() const { return StartLoc; }
  490.   /// Returns ending location of directive.
  491.   SourceLocation getEndLoc() const { return EndLoc; }
  492.  
  493.   /// Set starting location of directive kind.
  494.   ///
  495.   /// \param Loc New starting location of directive.
  496.   ///
  497.   void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
  498.   /// Set ending location of directive.
  499.   ///
  500.   /// \param Loc New ending location of directive.
  501.   ///
  502.   void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
  503.  
  504.   /// Get number of clauses.
  505.   unsigned getNumClauses() const {
  506.     if (!Data)
  507.       return 0;
  508.     return Data->getNumClauses();
  509.   }
  510.  
  511.   /// Returns specified clause.
  512.   ///
  513.   /// \param I Number of clause.
  514.   ///
  515.   OMPClause *getClause(unsigned I) const { return clauses()[I]; }
  516.  
  517.   /// Returns true if directive has associated statement.
  518.   bool hasAssociatedStmt() const { return Data && Data->hasAssociatedStmt(); }
  519.  
  520.   /// Returns statement associated with the directive.
  521.   const Stmt *getAssociatedStmt() const {
  522.     return const_cast<OMPExecutableDirective *>(this)->getAssociatedStmt();
  523.   }
  524.   Stmt *getAssociatedStmt() {
  525.     assert(hasAssociatedStmt() &&
  526.            "Expected directive with the associated statement.");
  527.     return Data->getAssociatedStmt();
  528.   }
  529.  
  530.   /// Returns the captured statement associated with the
  531.   /// component region within the (combined) directive.
  532.   ///
  533.   /// \param RegionKind Component region kind.
  534.   const CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const {
  535.     assert(hasAssociatedStmt() &&
  536.            "Expected directive with the associated statement.");
  537.     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
  538.     getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
  539.     return Data->getCapturedStmt(RegionKind, CaptureRegions);
  540.   }
  541.  
  542.   /// Get innermost captured statement for the construct.
  543.   CapturedStmt *getInnermostCapturedStmt() {
  544.     assert(hasAssociatedStmt() &&
  545.            "Expected directive with the associated statement.");
  546.     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
  547.     getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
  548.     return Data->getInnermostCapturedStmt(CaptureRegions);
  549.   }
  550.  
  551.   const CapturedStmt *getInnermostCapturedStmt() const {
  552.     return const_cast<OMPExecutableDirective *>(this)
  553.         ->getInnermostCapturedStmt();
  554.   }
  555.  
  556.   OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
  557.  
  558.   static bool classof(const Stmt *S) {
  559.     return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
  560.            S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
  561.   }
  562.  
  563.   child_range children() {
  564.     if (!Data)
  565.       return child_range(child_iterator(), child_iterator());
  566.     return Data->getAssociatedStmtAsRange();
  567.   }
  568.  
  569.   const_child_range children() const {
  570.     return const_cast<OMPExecutableDirective *>(this)->children();
  571.   }
  572.  
  573.   ArrayRef<OMPClause *> clauses() const {
  574.     if (!Data)
  575.       return std::nullopt;
  576.     return Data->getClauses();
  577.   }
  578.  
  579.   /// Returns whether or not this is a Standalone directive.
  580.   ///
  581.   /// Stand-alone directives are executable directives
  582.   /// that have no associated user code.
  583.   bool isStandaloneDirective() const;
  584.  
  585.   /// Returns the AST node representing OpenMP structured-block of this
  586.   /// OpenMP executable directive,
  587.   /// Prerequisite: Executable Directive must not be Standalone directive.
  588.   const Stmt *getStructuredBlock() const {
  589.     return const_cast<OMPExecutableDirective *>(this)->getStructuredBlock();
  590.   }
  591.   Stmt *getStructuredBlock();
  592.  
  593.   const Stmt *getRawStmt() const {
  594.     return const_cast<OMPExecutableDirective *>(this)->getRawStmt();
  595.   }
  596.   Stmt *getRawStmt() {
  597.     assert(hasAssociatedStmt() &&
  598.            "Expected directive with the associated statement.");
  599.     return Data->getRawStmt();
  600.   }
  601. };
  602.  
  603. /// This represents '#pragma omp parallel' directive.
  604. ///
  605. /// \code
  606. /// #pragma omp parallel private(a,b) reduction(+: c,d)
  607. /// \endcode
  608. /// In this example directive '#pragma omp parallel' has clauses 'private'
  609. /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
  610. /// variables 'c' and 'd'.
  611. ///
  612. class OMPParallelDirective : public OMPExecutableDirective {
  613.   friend class ASTStmtReader;
  614.   friend class OMPExecutableDirective;
  615.   /// true if the construct has inner cancel directive.
  616.   bool HasCancel = false;
  617.  
  618.   /// Build directive with the given start and end location.
  619.   ///
  620.   /// \param StartLoc Starting location of the directive (directive keyword).
  621.   /// \param EndLoc Ending Location of the directive.
  622.   ///
  623.   OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  624.       : OMPExecutableDirective(OMPParallelDirectiveClass,
  625.                                llvm::omp::OMPD_parallel, StartLoc, EndLoc) {}
  626.  
  627.   /// Build an empty directive.
  628.   ///
  629.   explicit OMPParallelDirective()
  630.       : OMPExecutableDirective(OMPParallelDirectiveClass,
  631.                                llvm::omp::OMPD_parallel, SourceLocation(),
  632.                                SourceLocation()) {}
  633.  
  634.   /// Sets special task reduction descriptor.
  635.   void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
  636.  
  637.   /// Set cancel state.
  638.   void setHasCancel(bool Has) { HasCancel = Has; }
  639.  
  640. public:
  641.   /// Creates directive with a list of \a Clauses.
  642.   ///
  643.   /// \param C AST context.
  644.   /// \param StartLoc Starting location of the directive kind.
  645.   /// \param EndLoc Ending Location of the directive.
  646.   /// \param Clauses List of clauses.
  647.   /// \param AssociatedStmt Statement associated with the directive.
  648.   /// \param TaskRedRef Task reduction special reference expression to handle
  649.   /// taskgroup descriptor.
  650.   /// \param HasCancel true if this directive has inner cancel directive.
  651.   ///
  652.   static OMPParallelDirective *
  653.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  654.          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
  655.          bool HasCancel);
  656.  
  657.   /// Creates an empty directive with the place for \a N clauses.
  658.   ///
  659.   /// \param C AST context.
  660.   /// \param NumClauses Number of clauses.
  661.   ///
  662.   static OMPParallelDirective *CreateEmpty(const ASTContext &C,
  663.                                            unsigned NumClauses, EmptyShell);
  664.  
  665.   /// Returns special task reduction reference expression.
  666.   Expr *getTaskReductionRefExpr() {
  667.     return cast_or_null<Expr>(Data->getChildren()[0]);
  668.   }
  669.   const Expr *getTaskReductionRefExpr() const {
  670.     return const_cast<OMPParallelDirective *>(this)->getTaskReductionRefExpr();
  671.   }
  672.  
  673.   /// Return true if current directive has inner cancel directive.
  674.   bool hasCancel() const { return HasCancel; }
  675.  
  676.   static bool classof(const Stmt *T) {
  677.     return T->getStmtClass() == OMPParallelDirectiveClass;
  678.   }
  679. };
  680.  
  681. /// The base class for all loop-based directives, including loop transformation
  682. /// directives.
  683. class OMPLoopBasedDirective : public OMPExecutableDirective {
  684.   friend class ASTStmtReader;
  685.  
  686. protected:
  687.   /// Number of collapsed loops as specified by 'collapse' clause.
  688.   unsigned NumAssociatedLoops = 0;
  689.  
  690.   /// Build instance of loop directive of class \a Kind.
  691.   ///
  692.   /// \param SC Statement class.
  693.   /// \param Kind Kind of OpenMP directive.
  694.   /// \param StartLoc Starting location of the directive (directive keyword).
  695.   /// \param EndLoc Ending location of the directive.
  696.   /// \param NumAssociatedLoops Number of loops associated with the construct.
  697.   ///
  698.   OMPLoopBasedDirective(StmtClass SC, OpenMPDirectiveKind Kind,
  699.                         SourceLocation StartLoc, SourceLocation EndLoc,
  700.                         unsigned NumAssociatedLoops)
  701.       : OMPExecutableDirective(SC, Kind, StartLoc, EndLoc),
  702.         NumAssociatedLoops(NumAssociatedLoops) {}
  703.  
  704. public:
  705.   /// The expressions built to support OpenMP loops in combined/composite
  706.   /// pragmas (e.g. pragma omp distribute parallel for)
  707.   struct DistCombinedHelperExprs {
  708.     /// DistributeLowerBound - used when composing 'omp distribute' with
  709.     /// 'omp for' in a same construct.
  710.     Expr *LB;
  711.     /// DistributeUpperBound - used when composing 'omp distribute' with
  712.     /// 'omp for' in a same construct.
  713.     Expr *UB;
  714.     /// DistributeEnsureUpperBound - used when composing 'omp distribute'
  715.     ///  with 'omp for' in a same construct, EUB depends on DistUB
  716.     Expr *EUB;
  717.     /// Distribute loop iteration variable init used when composing 'omp
  718.     /// distribute'
  719.     ///  with 'omp for' in a same construct
  720.     Expr *Init;
  721.     /// Distribute Loop condition used when composing 'omp distribute'
  722.     ///  with 'omp for' in a same construct
  723.     Expr *Cond;
  724.     /// Update of LowerBound for statically scheduled omp loops for
  725.     /// outer loop in combined constructs (e.g. 'distribute parallel for')
  726.     Expr *NLB;
  727.     /// Update of UpperBound for statically scheduled omp loops for
  728.     /// outer loop in combined constructs (e.g. 'distribute parallel for')
  729.     Expr *NUB;
  730.     /// Distribute Loop condition used when composing 'omp distribute'
  731.     ///  with 'omp for' in a same construct when schedule is chunked.
  732.     Expr *DistCond;
  733.     /// 'omp parallel for' loop condition used when composed with
  734.     /// 'omp distribute' in the same construct and when schedule is
  735.     /// chunked and the chunk size is 1.
  736.     Expr *ParForInDistCond;
  737.   };
  738.  
  739.   /// The expressions built for the OpenMP loop CodeGen for the
  740.   /// whole collapsed loop nest.
  741.   struct HelperExprs {
  742.     /// Loop iteration variable.
  743.     Expr *IterationVarRef;
  744.     /// Loop last iteration number.
  745.     Expr *LastIteration;
  746.     /// Loop number of iterations.
  747.     Expr *NumIterations;
  748.     /// Calculation of last iteration.
  749.     Expr *CalcLastIteration;
  750.     /// Loop pre-condition.
  751.     Expr *PreCond;
  752.     /// Loop condition.
  753.     Expr *Cond;
  754.     /// Loop iteration variable init.
  755.     Expr *Init;
  756.     /// Loop increment.
  757.     Expr *Inc;
  758.     /// IsLastIteration - local flag variable passed to runtime.
  759.     Expr *IL;
  760.     /// LowerBound - local variable passed to runtime.
  761.     Expr *LB;
  762.     /// UpperBound - local variable passed to runtime.
  763.     Expr *UB;
  764.     /// Stride - local variable passed to runtime.
  765.     Expr *ST;
  766.     /// EnsureUpperBound -- expression UB = min(UB, NumIterations).
  767.     Expr *EUB;
  768.     /// Update of LowerBound for statically scheduled 'omp for' loops.
  769.     Expr *NLB;
  770.     /// Update of UpperBound for statically scheduled 'omp for' loops.
  771.     Expr *NUB;
  772.     /// PreviousLowerBound - local variable passed to runtime in the
  773.     /// enclosing schedule or null if that does not apply.
  774.     Expr *PrevLB;
  775.     /// PreviousUpperBound - local variable passed to runtime in the
  776.     /// enclosing schedule or null if that does not apply.
  777.     Expr *PrevUB;
  778.     /// DistInc - increment expression for distribute loop when found
  779.     /// combined with a further loop level (e.g. in 'distribute parallel for')
  780.     /// expression IV = IV + ST
  781.     Expr *DistInc;
  782.     /// PrevEUB - expression similar to EUB but to be used when loop
  783.     /// scheduling uses PrevLB and PrevUB (e.g.  in 'distribute parallel for'
  784.     /// when ensuring that the UB is either the calculated UB by the runtime or
  785.     /// the end of the assigned distribute chunk)
  786.     /// expression UB = min (UB, PrevUB)
  787.     Expr *PrevEUB;
  788.     /// Counters Loop counters.
  789.     SmallVector<Expr *, 4> Counters;
  790.     /// PrivateCounters Loop counters.
  791.     SmallVector<Expr *, 4> PrivateCounters;
  792.     /// Expressions for loop counters inits for CodeGen.
  793.     SmallVector<Expr *, 4> Inits;
  794.     /// Expressions for loop counters update for CodeGen.
  795.     SmallVector<Expr *, 4> Updates;
  796.     /// Final loop counter values for GodeGen.
  797.     SmallVector<Expr *, 4> Finals;
  798.     /// List of counters required for the generation of the non-rectangular
  799.     /// loops.
  800.     SmallVector<Expr *, 4> DependentCounters;
  801.     /// List of initializers required for the generation of the non-rectangular
  802.     /// loops.
  803.     SmallVector<Expr *, 4> DependentInits;
  804.     /// List of final conditions required for the generation of the
  805.     /// non-rectangular loops.
  806.     SmallVector<Expr *, 4> FinalsConditions;
  807.     /// Init statement for all captured expressions.
  808.     Stmt *PreInits;
  809.  
  810.     /// Expressions used when combining OpenMP loop pragmas
  811.     DistCombinedHelperExprs DistCombinedFields;
  812.  
  813.     /// Check if all the expressions are built (does not check the
  814.     /// worksharing ones).
  815.     bool builtAll() {
  816.       return IterationVarRef != nullptr && LastIteration != nullptr &&
  817.              NumIterations != nullptr && PreCond != nullptr &&
  818.              Cond != nullptr && Init != nullptr && Inc != nullptr;
  819.     }
  820.  
  821.     /// Initialize all the fields to null.
  822.     /// \param Size Number of elements in the
  823.     /// counters/finals/updates/dependent_counters/dependent_inits/finals_conditions
  824.     /// arrays.
  825.     void clear(unsigned Size) {
  826.       IterationVarRef = nullptr;
  827.       LastIteration = nullptr;
  828.       CalcLastIteration = nullptr;
  829.       PreCond = nullptr;
  830.       Cond = nullptr;
  831.       Init = nullptr;
  832.       Inc = nullptr;
  833.       IL = nullptr;
  834.       LB = nullptr;
  835.       UB = nullptr;
  836.       ST = nullptr;
  837.       EUB = nullptr;
  838.       NLB = nullptr;
  839.       NUB = nullptr;
  840.       NumIterations = nullptr;
  841.       PrevLB = nullptr;
  842.       PrevUB = nullptr;
  843.       DistInc = nullptr;
  844.       PrevEUB = nullptr;
  845.       Counters.resize(Size);
  846.       PrivateCounters.resize(Size);
  847.       Inits.resize(Size);
  848.       Updates.resize(Size);
  849.       Finals.resize(Size);
  850.       DependentCounters.resize(Size);
  851.       DependentInits.resize(Size);
  852.       FinalsConditions.resize(Size);
  853.       for (unsigned I = 0; I < Size; ++I) {
  854.         Counters[I] = nullptr;
  855.         PrivateCounters[I] = nullptr;
  856.         Inits[I] = nullptr;
  857.         Updates[I] = nullptr;
  858.         Finals[I] = nullptr;
  859.         DependentCounters[I] = nullptr;
  860.         DependentInits[I] = nullptr;
  861.         FinalsConditions[I] = nullptr;
  862.       }
  863.       PreInits = nullptr;
  864.       DistCombinedFields.LB = nullptr;
  865.       DistCombinedFields.UB = nullptr;
  866.       DistCombinedFields.EUB = nullptr;
  867.       DistCombinedFields.Init = nullptr;
  868.       DistCombinedFields.Cond = nullptr;
  869.       DistCombinedFields.NLB = nullptr;
  870.       DistCombinedFields.NUB = nullptr;
  871.       DistCombinedFields.DistCond = nullptr;
  872.       DistCombinedFields.ParForInDistCond = nullptr;
  873.     }
  874.   };
  875.  
  876.   /// Get number of collapsed loops.
  877.   unsigned getLoopsNumber() const { return NumAssociatedLoops; }
  878.  
  879.   /// Try to find the next loop sub-statement in the specified statement \p
  880.   /// CurStmt.
  881.   /// \param TryImperfectlyNestedLoops true, if we need to try to look for the
  882.   /// imperfectly nested loop.
  883.   static Stmt *tryToFindNextInnerLoop(Stmt *CurStmt,
  884.                                       bool TryImperfectlyNestedLoops);
  885.   static const Stmt *tryToFindNextInnerLoop(const Stmt *CurStmt,
  886.                                             bool TryImperfectlyNestedLoops) {
  887.     return tryToFindNextInnerLoop(const_cast<Stmt *>(CurStmt),
  888.                                   TryImperfectlyNestedLoops);
  889.   }
  890.  
  891.   /// Calls the specified callback function for all the loops in \p CurStmt,
  892.   /// from the outermost to the innermost.
  893.   static bool
  894.   doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
  895.                 unsigned NumLoops,
  896.                 llvm::function_ref<bool(unsigned, Stmt *)> Callback,
  897.                 llvm::function_ref<void(OMPLoopTransformationDirective *)>
  898.                     OnTransformationCallback);
  899.   static bool
  900.   doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
  901.                 unsigned NumLoops,
  902.                 llvm::function_ref<bool(unsigned, const Stmt *)> Callback,
  903.                 llvm::function_ref<void(const OMPLoopTransformationDirective *)>
  904.                     OnTransformationCallback) {
  905.     auto &&NewCallback = [Callback](unsigned Cnt, Stmt *CurStmt) {
  906.       return Callback(Cnt, CurStmt);
  907.     };
  908.     auto &&NewTransformCb =
  909.         [OnTransformationCallback](OMPLoopTransformationDirective *A) {
  910.           OnTransformationCallback(A);
  911.         };
  912.     return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
  913.                          NumLoops, NewCallback, NewTransformCb);
  914.   }
  915.  
  916.   /// Calls the specified callback function for all the loops in \p CurStmt,
  917.   /// from the outermost to the innermost.
  918.   static bool
  919.   doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
  920.                 unsigned NumLoops,
  921.                 llvm::function_ref<bool(unsigned, Stmt *)> Callback) {
  922.     auto &&TransformCb = [](OMPLoopTransformationDirective *) {};
  923.     return doForAllLoops(CurStmt, TryImperfectlyNestedLoops, NumLoops, Callback,
  924.                          TransformCb);
  925.   }
  926.   static bool
  927.   doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
  928.                 unsigned NumLoops,
  929.                 llvm::function_ref<bool(unsigned, const Stmt *)> Callback) {
  930.     auto &&NewCallback = [Callback](unsigned Cnt, const Stmt *CurStmt) {
  931.       return Callback(Cnt, CurStmt);
  932.     };
  933.     return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
  934.                          NumLoops, NewCallback);
  935.   }
  936.  
  937.   /// Calls the specified callback function for all the loop bodies in \p
  938.   /// CurStmt, from the outermost loop to the innermost.
  939.   static void doForAllLoopsBodies(
  940.       Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops,
  941.       llvm::function_ref<void(unsigned, Stmt *, Stmt *)> Callback);
  942.   static void doForAllLoopsBodies(
  943.       const Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops,
  944.       llvm::function_ref<void(unsigned, const Stmt *, const Stmt *)> Callback) {
  945.     auto &&NewCallback = [Callback](unsigned Cnt, Stmt *Loop, Stmt *Body) {
  946.       Callback(Cnt, Loop, Body);
  947.     };
  948.     doForAllLoopsBodies(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
  949.                         NumLoops, NewCallback);
  950.   }
  951.  
  952.   static bool classof(const Stmt *T) {
  953.     if (auto *D = dyn_cast<OMPExecutableDirective>(T))
  954.       return isOpenMPLoopDirective(D->getDirectiveKind());
  955.     return false;
  956.   }
  957. };
  958.  
  959. /// The base class for all loop transformation directives.
  960. class OMPLoopTransformationDirective : public OMPLoopBasedDirective {
  961.   friend class ASTStmtReader;
  962.  
  963.   /// Number of loops generated by this loop transformation.
  964.   unsigned NumGeneratedLoops = 0;
  965.  
  966. protected:
  967.   explicit OMPLoopTransformationDirective(StmtClass SC,
  968.                                           OpenMPDirectiveKind Kind,
  969.                                           SourceLocation StartLoc,
  970.                                           SourceLocation EndLoc,
  971.                                           unsigned NumAssociatedLoops)
  972.       : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, NumAssociatedLoops) {}
  973.  
  974.   /// Set the number of loops generated by this loop transformation.
  975.   void setNumGeneratedLoops(unsigned Num) { NumGeneratedLoops = Num; }
  976.  
  977. public:
  978.   /// Return the number of associated (consumed) loops.
  979.   unsigned getNumAssociatedLoops() const { return getLoopsNumber(); }
  980.  
  981.   /// Return the number of loops generated by this loop transformation.
  982.   unsigned getNumGeneratedLoops() { return NumGeneratedLoops; }
  983.  
  984.   /// Get the de-sugared statements after the loop transformation.
  985.   ///
  986.   /// Might be nullptr if either the directive generates no loops and is handled
  987.   /// directly in CodeGen, or resolving a template-dependence context is
  988.   /// required.
  989.   Stmt *getTransformedStmt() const;
  990.  
  991.   /// Return preinits statement.
  992.   Stmt *getPreInits() const;
  993.  
  994.   static bool classof(const Stmt *T) {
  995.     return T->getStmtClass() == OMPTileDirectiveClass ||
  996.            T->getStmtClass() == OMPUnrollDirectiveClass;
  997.   }
  998. };
  999.  
  1000. /// This is a common base class for loop directives ('omp simd', 'omp
  1001. /// for', 'omp for simd' etc.). It is responsible for the loop code generation.
  1002. ///
  1003. class OMPLoopDirective : public OMPLoopBasedDirective {
  1004.   friend class ASTStmtReader;
  1005.  
  1006.   /// Offsets to the stored exprs.
  1007.   /// This enumeration contains offsets to all the pointers to children
  1008.   /// expressions stored in OMPLoopDirective.
  1009.   /// The first 9 children are necessary for all the loop directives,
  1010.   /// the next 8 are specific to the worksharing ones, and the next 11 are
  1011.   /// used for combined constructs containing two pragmas associated to loops.
  1012.   /// After the fixed children, three arrays of length NumAssociatedLoops are
  1013.   /// allocated: loop counters, their updates and final values.
  1014.   /// PrevLowerBound and PrevUpperBound are used to communicate blocking
  1015.   /// information in composite constructs which require loop blocking
  1016.   /// DistInc is used to generate the increment expression for the distribute
  1017.   /// loop when combined with a further nested loop
  1018.   /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the
  1019.   /// for loop when combined with a previous distribute loop in the same pragma
  1020.   /// (e.g. 'distribute parallel for')
  1021.   ///
  1022.   enum {
  1023.     IterationVariableOffset = 0,
  1024.     LastIterationOffset = 1,
  1025.     CalcLastIterationOffset = 2,
  1026.     PreConditionOffset = 3,
  1027.     CondOffset = 4,
  1028.     InitOffset = 5,
  1029.     IncOffset = 6,
  1030.     PreInitsOffset = 7,
  1031.     // The '...End' enumerators do not correspond to child expressions - they
  1032.     // specify the offset to the end (and start of the following counters/
  1033.     // updates/finals/dependent_counters/dependent_inits/finals_conditions
  1034.     // arrays).
  1035.     DefaultEnd = 8,
  1036.     // The following 8 exprs are used by worksharing and distribute loops only.
  1037.     IsLastIterVariableOffset = 8,
  1038.     LowerBoundVariableOffset = 9,
  1039.     UpperBoundVariableOffset = 10,
  1040.     StrideVariableOffset = 11,
  1041.     EnsureUpperBoundOffset = 12,
  1042.     NextLowerBoundOffset = 13,
  1043.     NextUpperBoundOffset = 14,
  1044.     NumIterationsOffset = 15,
  1045.     // Offset to the end for worksharing loop directives.
  1046.     WorksharingEnd = 16,
  1047.     PrevLowerBoundVariableOffset = 16,
  1048.     PrevUpperBoundVariableOffset = 17,
  1049.     DistIncOffset = 18,
  1050.     PrevEnsureUpperBoundOffset = 19,
  1051.     CombinedLowerBoundVariableOffset = 20,
  1052.     CombinedUpperBoundVariableOffset = 21,
  1053.     CombinedEnsureUpperBoundOffset = 22,
  1054.     CombinedInitOffset = 23,
  1055.     CombinedConditionOffset = 24,
  1056.     CombinedNextLowerBoundOffset = 25,
  1057.     CombinedNextUpperBoundOffset = 26,
  1058.     CombinedDistConditionOffset = 27,
  1059.     CombinedParForInDistConditionOffset = 28,
  1060.     // Offset to the end (and start of the following
  1061.     // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions
  1062.     // arrays) for combined distribute loop directives.
  1063.     CombinedDistributeEnd = 29,
  1064.   };
  1065.  
  1066.   /// Get the counters storage.
  1067.   MutableArrayRef<Expr *> getCounters() {
  1068.     auto **Storage = reinterpret_cast<Expr **>(
  1069.         &Data->getChildren()[getArraysOffset(getDirectiveKind())]);
  1070.     return llvm::MutableArrayRef(Storage, getLoopsNumber());
  1071.   }
  1072.  
  1073.   /// Get the private counters storage.
  1074.   MutableArrayRef<Expr *> getPrivateCounters() {
  1075.     auto **Storage = reinterpret_cast<Expr **>(
  1076.         &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
  1077.                              getLoopsNumber()]);
  1078.     return llvm::MutableArrayRef(Storage, getLoopsNumber());
  1079.   }
  1080.  
  1081.   /// Get the updates storage.
  1082.   MutableArrayRef<Expr *> getInits() {
  1083.     auto **Storage = reinterpret_cast<Expr **>(
  1084.         &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
  1085.                              2 * getLoopsNumber()]);
  1086.     return llvm::MutableArrayRef(Storage, getLoopsNumber());
  1087.   }
  1088.  
  1089.   /// Get the updates storage.
  1090.   MutableArrayRef<Expr *> getUpdates() {
  1091.     auto **Storage = reinterpret_cast<Expr **>(
  1092.         &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
  1093.                              3 * getLoopsNumber()]);
  1094.     return llvm::MutableArrayRef(Storage, getLoopsNumber());
  1095.   }
  1096.  
  1097.   /// Get the final counter updates storage.
  1098.   MutableArrayRef<Expr *> getFinals() {
  1099.     auto **Storage = reinterpret_cast<Expr **>(
  1100.         &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
  1101.                              4 * getLoopsNumber()]);
  1102.     return llvm::MutableArrayRef(Storage, getLoopsNumber());
  1103.   }
  1104.  
  1105.   /// Get the dependent counters storage.
  1106.   MutableArrayRef<Expr *> getDependentCounters() {
  1107.     auto **Storage = reinterpret_cast<Expr **>(
  1108.         &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
  1109.                              5 * getLoopsNumber()]);
  1110.     return llvm::MutableArrayRef(Storage, getLoopsNumber());
  1111.   }
  1112.  
  1113.   /// Get the dependent inits storage.
  1114.   MutableArrayRef<Expr *> getDependentInits() {
  1115.     auto **Storage = reinterpret_cast<Expr **>(
  1116.         &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
  1117.                              6 * getLoopsNumber()]);
  1118.     return llvm::MutableArrayRef(Storage, getLoopsNumber());
  1119.   }
  1120.  
  1121.   /// Get the finals conditions storage.
  1122.   MutableArrayRef<Expr *> getFinalsConditions() {
  1123.     auto **Storage = reinterpret_cast<Expr **>(
  1124.         &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
  1125.                              7 * getLoopsNumber()]);
  1126.     return llvm::MutableArrayRef(Storage, getLoopsNumber());
  1127.   }
  1128.  
  1129. protected:
  1130.   /// Build instance of loop directive of class \a Kind.
  1131.   ///
  1132.   /// \param SC Statement class.
  1133.   /// \param Kind Kind of OpenMP directive.
  1134.   /// \param StartLoc Starting location of the directive (directive keyword).
  1135.   /// \param EndLoc Ending location of the directive.
  1136.   /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
  1137.   ///
  1138.   OMPLoopDirective(StmtClass SC, OpenMPDirectiveKind Kind,
  1139.                    SourceLocation StartLoc, SourceLocation EndLoc,
  1140.                    unsigned CollapsedNum)
  1141.       : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, CollapsedNum) {}
  1142.  
  1143.   /// Offset to the start of children expression arrays.
  1144.   static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
  1145.     if (isOpenMPLoopBoundSharingDirective(Kind))
  1146.       return CombinedDistributeEnd;
  1147.     if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) ||
  1148.         isOpenMPGenericLoopDirective(Kind) || isOpenMPDistributeDirective(Kind))
  1149.       return WorksharingEnd;
  1150.     return DefaultEnd;
  1151.   }
  1152.  
  1153.   /// Children number.
  1154.   static unsigned numLoopChildren(unsigned CollapsedNum,
  1155.                                   OpenMPDirectiveKind Kind) {
  1156.     return getArraysOffset(Kind) +
  1157.            8 * CollapsedNum; // Counters, PrivateCounters, Inits,
  1158.                              // Updates, Finals, DependentCounters,
  1159.                              // DependentInits, FinalsConditions.
  1160.   }
  1161.  
  1162.   void setIterationVariable(Expr *IV) {
  1163.     Data->getChildren()[IterationVariableOffset] = IV;
  1164.   }
  1165.   void setLastIteration(Expr *LI) {
  1166.     Data->getChildren()[LastIterationOffset] = LI;
  1167.   }
  1168.   void setCalcLastIteration(Expr *CLI) {
  1169.     Data->getChildren()[CalcLastIterationOffset] = CLI;
  1170.   }
  1171.   void setPreCond(Expr *PC) { Data->getChildren()[PreConditionOffset] = PC; }
  1172.   void setCond(Expr *Cond) { Data->getChildren()[CondOffset] = Cond; }
  1173.   void setInit(Expr *Init) { Data->getChildren()[InitOffset] = Init; }
  1174.   void setInc(Expr *Inc) { Data->getChildren()[IncOffset] = Inc; }
  1175.   void setPreInits(Stmt *PreInits) {
  1176.     Data->getChildren()[PreInitsOffset] = PreInits;
  1177.   }
  1178.   void setIsLastIterVariable(Expr *IL) {
  1179.     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
  1180.             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
  1181.             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
  1182.             isOpenMPDistributeDirective(getDirectiveKind())) &&
  1183.            "expected worksharing loop directive");
  1184.     Data->getChildren()[IsLastIterVariableOffset] = IL;
  1185.   }
  1186.   void setLowerBoundVariable(Expr *LB) {
  1187.     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
  1188.             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
  1189.             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
  1190.             isOpenMPDistributeDirective(getDirectiveKind())) &&
  1191.            "expected worksharing loop directive");
  1192.     Data->getChildren()[LowerBoundVariableOffset] = LB;
  1193.   }
  1194.   void setUpperBoundVariable(Expr *UB) {
  1195.     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
  1196.             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
  1197.             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
  1198.             isOpenMPDistributeDirective(getDirectiveKind())) &&
  1199.            "expected worksharing loop directive");
  1200.     Data->getChildren()[UpperBoundVariableOffset] = UB;
  1201.   }
  1202.   void setStrideVariable(Expr *ST) {
  1203.     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
  1204.             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
  1205.             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
  1206.             isOpenMPDistributeDirective(getDirectiveKind())) &&
  1207.            "expected worksharing loop directive");
  1208.     Data->getChildren()[StrideVariableOffset] = ST;
  1209.   }
  1210.   void setEnsureUpperBound(Expr *EUB) {
  1211.     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
  1212.             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
  1213.             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
  1214.             isOpenMPDistributeDirective(getDirectiveKind())) &&
  1215.            "expected worksharing loop directive");
  1216.     Data->getChildren()[EnsureUpperBoundOffset] = EUB;
  1217.   }
  1218.   void setNextLowerBound(Expr *NLB) {
  1219.     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
  1220.             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
  1221.             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
  1222.             isOpenMPDistributeDirective(getDirectiveKind())) &&
  1223.            "expected worksharing loop directive");
  1224.     Data->getChildren()[NextLowerBoundOffset] = NLB;
  1225.   }
  1226.   void setNextUpperBound(Expr *NUB) {
  1227.     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
  1228.             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
  1229.             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
  1230.             isOpenMPDistributeDirective(getDirectiveKind())) &&
  1231.            "expected worksharing loop directive");
  1232.     Data->getChildren()[NextUpperBoundOffset] = NUB;
  1233.   }
  1234.   void setNumIterations(Expr *NI) {
  1235.     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
  1236.             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
  1237.             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
  1238.             isOpenMPDistributeDirective(getDirectiveKind())) &&
  1239.            "expected worksharing loop directive");
  1240.     Data->getChildren()[NumIterationsOffset] = NI;
  1241.   }
  1242.   void setPrevLowerBoundVariable(Expr *PrevLB) {
  1243.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1244.            "expected loop bound sharing directive");
  1245.     Data->getChildren()[PrevLowerBoundVariableOffset] = PrevLB;
  1246.   }
  1247.   void setPrevUpperBoundVariable(Expr *PrevUB) {
  1248.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1249.            "expected loop bound sharing directive");
  1250.     Data->getChildren()[PrevUpperBoundVariableOffset] = PrevUB;
  1251.   }
  1252.   void setDistInc(Expr *DistInc) {
  1253.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1254.            "expected loop bound sharing directive");
  1255.     Data->getChildren()[DistIncOffset] = DistInc;
  1256.   }
  1257.   void setPrevEnsureUpperBound(Expr *PrevEUB) {
  1258.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1259.            "expected loop bound sharing directive");
  1260.     Data->getChildren()[PrevEnsureUpperBoundOffset] = PrevEUB;
  1261.   }
  1262.   void setCombinedLowerBoundVariable(Expr *CombLB) {
  1263.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1264.            "expected loop bound sharing directive");
  1265.     Data->getChildren()[CombinedLowerBoundVariableOffset] = CombLB;
  1266.   }
  1267.   void setCombinedUpperBoundVariable(Expr *CombUB) {
  1268.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1269.            "expected loop bound sharing directive");
  1270.     Data->getChildren()[CombinedUpperBoundVariableOffset] = CombUB;
  1271.   }
  1272.   void setCombinedEnsureUpperBound(Expr *CombEUB) {
  1273.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1274.            "expected loop bound sharing directive");
  1275.     Data->getChildren()[CombinedEnsureUpperBoundOffset] = CombEUB;
  1276.   }
  1277.   void setCombinedInit(Expr *CombInit) {
  1278.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1279.            "expected loop bound sharing directive");
  1280.     Data->getChildren()[CombinedInitOffset] = CombInit;
  1281.   }
  1282.   void setCombinedCond(Expr *CombCond) {
  1283.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1284.            "expected loop bound sharing directive");
  1285.     Data->getChildren()[CombinedConditionOffset] = CombCond;
  1286.   }
  1287.   void setCombinedNextLowerBound(Expr *CombNLB) {
  1288.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1289.            "expected loop bound sharing directive");
  1290.     Data->getChildren()[CombinedNextLowerBoundOffset] = CombNLB;
  1291.   }
  1292.   void setCombinedNextUpperBound(Expr *CombNUB) {
  1293.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1294.            "expected loop bound sharing directive");
  1295.     Data->getChildren()[CombinedNextUpperBoundOffset] = CombNUB;
  1296.   }
  1297.   void setCombinedDistCond(Expr *CombDistCond) {
  1298.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1299.            "expected loop bound distribute sharing directive");
  1300.     Data->getChildren()[CombinedDistConditionOffset] = CombDistCond;
  1301.   }
  1302.   void setCombinedParForInDistCond(Expr *CombParForInDistCond) {
  1303.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1304.            "expected loop bound distribute sharing directive");
  1305.     Data->getChildren()[CombinedParForInDistConditionOffset] =
  1306.         CombParForInDistCond;
  1307.   }
  1308.   void setCounters(ArrayRef<Expr *> A);
  1309.   void setPrivateCounters(ArrayRef<Expr *> A);
  1310.   void setInits(ArrayRef<Expr *> A);
  1311.   void setUpdates(ArrayRef<Expr *> A);
  1312.   void setFinals(ArrayRef<Expr *> A);
  1313.   void setDependentCounters(ArrayRef<Expr *> A);
  1314.   void setDependentInits(ArrayRef<Expr *> A);
  1315.   void setFinalsConditions(ArrayRef<Expr *> A);
  1316.  
  1317. public:
  1318.   Expr *getIterationVariable() const {
  1319.     return cast<Expr>(Data->getChildren()[IterationVariableOffset]);
  1320.   }
  1321.   Expr *getLastIteration() const {
  1322.     return cast<Expr>(Data->getChildren()[LastIterationOffset]);
  1323.   }
  1324.   Expr *getCalcLastIteration() const {
  1325.     return cast<Expr>(Data->getChildren()[CalcLastIterationOffset]);
  1326.   }
  1327.   Expr *getPreCond() const {
  1328.     return cast<Expr>(Data->getChildren()[PreConditionOffset]);
  1329.   }
  1330.   Expr *getCond() const { return cast<Expr>(Data->getChildren()[CondOffset]); }
  1331.   Expr *getInit() const { return cast<Expr>(Data->getChildren()[InitOffset]); }
  1332.   Expr *getInc() const { return cast<Expr>(Data->getChildren()[IncOffset]); }
  1333.   const Stmt *getPreInits() const {
  1334.     return Data->getChildren()[PreInitsOffset];
  1335.   }
  1336.   Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; }
  1337.   Expr *getIsLastIterVariable() const {
  1338.     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
  1339.             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
  1340.             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
  1341.             isOpenMPDistributeDirective(getDirectiveKind())) &&
  1342.            "expected worksharing loop directive");
  1343.     return cast<Expr>(Data->getChildren()[IsLastIterVariableOffset]);
  1344.   }
  1345.   Expr *getLowerBoundVariable() const {
  1346.     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
  1347.             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
  1348.             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
  1349.             isOpenMPDistributeDirective(getDirectiveKind())) &&
  1350.            "expected worksharing loop directive");
  1351.     return cast<Expr>(Data->getChildren()[LowerBoundVariableOffset]);
  1352.   }
  1353.   Expr *getUpperBoundVariable() const {
  1354.     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
  1355.             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
  1356.             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
  1357.             isOpenMPDistributeDirective(getDirectiveKind())) &&
  1358.            "expected worksharing loop directive");
  1359.     return cast<Expr>(Data->getChildren()[UpperBoundVariableOffset]);
  1360.   }
  1361.   Expr *getStrideVariable() const {
  1362.     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
  1363.             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
  1364.             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
  1365.             isOpenMPDistributeDirective(getDirectiveKind())) &&
  1366.            "expected worksharing loop directive");
  1367.     return cast<Expr>(Data->getChildren()[StrideVariableOffset]);
  1368.   }
  1369.   Expr *getEnsureUpperBound() const {
  1370.     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
  1371.             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
  1372.             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
  1373.             isOpenMPDistributeDirective(getDirectiveKind())) &&
  1374.            "expected worksharing loop directive");
  1375.     return cast<Expr>(Data->getChildren()[EnsureUpperBoundOffset]);
  1376.   }
  1377.   Expr *getNextLowerBound() const {
  1378.     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
  1379.             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
  1380.             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
  1381.             isOpenMPDistributeDirective(getDirectiveKind())) &&
  1382.            "expected worksharing loop directive");
  1383.     return cast<Expr>(Data->getChildren()[NextLowerBoundOffset]);
  1384.   }
  1385.   Expr *getNextUpperBound() const {
  1386.     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
  1387.             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
  1388.             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
  1389.             isOpenMPDistributeDirective(getDirectiveKind())) &&
  1390.            "expected worksharing loop directive");
  1391.     return cast<Expr>(Data->getChildren()[NextUpperBoundOffset]);
  1392.   }
  1393.   Expr *getNumIterations() const {
  1394.     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
  1395.             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
  1396.             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
  1397.             isOpenMPDistributeDirective(getDirectiveKind())) &&
  1398.            "expected worksharing loop directive");
  1399.     return cast<Expr>(Data->getChildren()[NumIterationsOffset]);
  1400.   }
  1401.   Expr *getPrevLowerBoundVariable() const {
  1402.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1403.            "expected loop bound sharing directive");
  1404.     return cast<Expr>(Data->getChildren()[PrevLowerBoundVariableOffset]);
  1405.   }
  1406.   Expr *getPrevUpperBoundVariable() const {
  1407.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1408.            "expected loop bound sharing directive");
  1409.     return cast<Expr>(Data->getChildren()[PrevUpperBoundVariableOffset]);
  1410.   }
  1411.   Expr *getDistInc() const {
  1412.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1413.            "expected loop bound sharing directive");
  1414.     return cast<Expr>(Data->getChildren()[DistIncOffset]);
  1415.   }
  1416.   Expr *getPrevEnsureUpperBound() const {
  1417.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1418.            "expected loop bound sharing directive");
  1419.     return cast<Expr>(Data->getChildren()[PrevEnsureUpperBoundOffset]);
  1420.   }
  1421.   Expr *getCombinedLowerBoundVariable() const {
  1422.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1423.            "expected loop bound sharing directive");
  1424.     return cast<Expr>(Data->getChildren()[CombinedLowerBoundVariableOffset]);
  1425.   }
  1426.   Expr *getCombinedUpperBoundVariable() const {
  1427.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1428.            "expected loop bound sharing directive");
  1429.     return cast<Expr>(Data->getChildren()[CombinedUpperBoundVariableOffset]);
  1430.   }
  1431.   Expr *getCombinedEnsureUpperBound() const {
  1432.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1433.            "expected loop bound sharing directive");
  1434.     return cast<Expr>(Data->getChildren()[CombinedEnsureUpperBoundOffset]);
  1435.   }
  1436.   Expr *getCombinedInit() const {
  1437.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1438.            "expected loop bound sharing directive");
  1439.     return cast<Expr>(Data->getChildren()[CombinedInitOffset]);
  1440.   }
  1441.   Expr *getCombinedCond() const {
  1442.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1443.            "expected loop bound sharing directive");
  1444.     return cast<Expr>(Data->getChildren()[CombinedConditionOffset]);
  1445.   }
  1446.   Expr *getCombinedNextLowerBound() const {
  1447.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1448.            "expected loop bound sharing directive");
  1449.     return cast<Expr>(Data->getChildren()[CombinedNextLowerBoundOffset]);
  1450.   }
  1451.   Expr *getCombinedNextUpperBound() const {
  1452.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1453.            "expected loop bound sharing directive");
  1454.     return cast<Expr>(Data->getChildren()[CombinedNextUpperBoundOffset]);
  1455.   }
  1456.   Expr *getCombinedDistCond() const {
  1457.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1458.            "expected loop bound distribute sharing directive");
  1459.     return cast<Expr>(Data->getChildren()[CombinedDistConditionOffset]);
  1460.   }
  1461.   Expr *getCombinedParForInDistCond() const {
  1462.     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
  1463.            "expected loop bound distribute sharing directive");
  1464.     return cast<Expr>(Data->getChildren()[CombinedParForInDistConditionOffset]);
  1465.   }
  1466.   Stmt *getBody();
  1467.   const Stmt *getBody() const {
  1468.     return const_cast<OMPLoopDirective *>(this)->getBody();
  1469.   }
  1470.  
  1471.   ArrayRef<Expr *> counters() { return getCounters(); }
  1472.  
  1473.   ArrayRef<Expr *> counters() const {
  1474.     return const_cast<OMPLoopDirective *>(this)->getCounters();
  1475.   }
  1476.  
  1477.   ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
  1478.  
  1479.   ArrayRef<Expr *> private_counters() const {
  1480.     return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
  1481.   }
  1482.  
  1483.   ArrayRef<Expr *> inits() { return getInits(); }
  1484.  
  1485.   ArrayRef<Expr *> inits() const {
  1486.     return const_cast<OMPLoopDirective *>(this)->getInits();
  1487.   }
  1488.  
  1489.   ArrayRef<Expr *> updates() { return getUpdates(); }
  1490.  
  1491.   ArrayRef<Expr *> updates() const {
  1492.     return const_cast<OMPLoopDirective *>(this)->getUpdates();
  1493.   }
  1494.  
  1495.   ArrayRef<Expr *> finals() { return getFinals(); }
  1496.  
  1497.   ArrayRef<Expr *> finals() const {
  1498.     return const_cast<OMPLoopDirective *>(this)->getFinals();
  1499.   }
  1500.  
  1501.   ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); }
  1502.  
  1503.   ArrayRef<Expr *> dependent_counters() const {
  1504.     return const_cast<OMPLoopDirective *>(this)->getDependentCounters();
  1505.   }
  1506.  
  1507.   ArrayRef<Expr *> dependent_inits() { return getDependentInits(); }
  1508.  
  1509.   ArrayRef<Expr *> dependent_inits() const {
  1510.     return const_cast<OMPLoopDirective *>(this)->getDependentInits();
  1511.   }
  1512.  
  1513.   ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); }
  1514.  
  1515.   ArrayRef<Expr *> finals_conditions() const {
  1516.     return const_cast<OMPLoopDirective *>(this)->getFinalsConditions();
  1517.   }
  1518.  
  1519.   static bool classof(const Stmt *T) {
  1520.     return T->getStmtClass() == OMPSimdDirectiveClass ||
  1521.            T->getStmtClass() == OMPForDirectiveClass ||
  1522.            T->getStmtClass() == OMPForSimdDirectiveClass ||
  1523.            T->getStmtClass() == OMPParallelForDirectiveClass ||
  1524.            T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
  1525.            T->getStmtClass() == OMPTaskLoopDirectiveClass ||
  1526.            T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
  1527.            T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass ||
  1528.            T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass ||
  1529.            T->getStmtClass() == OMPMasterTaskLoopDirectiveClass ||
  1530.            T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass ||
  1531.            T->getStmtClass() == OMPGenericLoopDirectiveClass ||
  1532.            T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass ||
  1533.            T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass ||
  1534.            T->getStmtClass() == OMPParallelGenericLoopDirectiveClass ||
  1535.            T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass ||
  1536.            T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass ||
  1537.            T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass ||
  1538.            T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass ||
  1539.            T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass ||
  1540.            T->getStmtClass() == OMPDistributeDirectiveClass ||
  1541.            T->getStmtClass() == OMPTargetParallelForDirectiveClass ||
  1542.            T->getStmtClass() == OMPDistributeParallelForDirectiveClass ||
  1543.            T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass ||
  1544.            T->getStmtClass() == OMPDistributeSimdDirectiveClass ||
  1545.            T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass ||
  1546.            T->getStmtClass() == OMPTargetSimdDirectiveClass ||
  1547.            T->getStmtClass() == OMPTeamsDistributeDirectiveClass ||
  1548.            T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass ||
  1549.            T->getStmtClass() ==
  1550.                OMPTeamsDistributeParallelForSimdDirectiveClass ||
  1551.            T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass ||
  1552.            T->getStmtClass() ==
  1553.                OMPTargetTeamsDistributeParallelForDirectiveClass ||
  1554.            T->getStmtClass() ==
  1555.                OMPTargetTeamsDistributeParallelForSimdDirectiveClass ||
  1556.            T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass ||
  1557.            T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
  1558.   }
  1559. };
  1560.  
  1561. /// This represents '#pragma omp simd' directive.
  1562. ///
  1563. /// \code
  1564. /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
  1565. /// \endcode
  1566. /// In this example directive '#pragma omp simd' has clauses 'private'
  1567. /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
  1568. /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
  1569. ///
  1570. class OMPSimdDirective : public OMPLoopDirective {
  1571.   friend class ASTStmtReader;
  1572.   friend class OMPExecutableDirective;
  1573.   /// Build directive with the given start and end location.
  1574.   ///
  1575.   /// \param StartLoc Starting location of the directive kind.
  1576.   /// \param EndLoc Ending location of the directive.
  1577.   /// \param CollapsedNum Number of collapsed nested loops.
  1578.   ///
  1579.   OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
  1580.                    unsigned CollapsedNum)
  1581.       : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, StartLoc,
  1582.                          EndLoc, CollapsedNum) {}
  1583.  
  1584.   /// Build an empty directive.
  1585.   ///
  1586.   /// \param CollapsedNum Number of collapsed nested loops.
  1587.   ///
  1588.   explicit OMPSimdDirective(unsigned CollapsedNum)
  1589.       : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd,
  1590.                          SourceLocation(), SourceLocation(), CollapsedNum) {}
  1591.  
  1592. public:
  1593.   /// Creates directive with a list of \a Clauses.
  1594.   ///
  1595.   /// \param C AST context.
  1596.   /// \param StartLoc Starting location of the directive kind.
  1597.   /// \param EndLoc Ending Location of the directive.
  1598.   /// \param CollapsedNum Number of collapsed loops.
  1599.   /// \param Clauses List of clauses.
  1600.   /// \param AssociatedStmt Statement, associated with the directive.
  1601.   /// \param Exprs Helper expressions for CodeGen.
  1602.   ///
  1603.   static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
  1604.                                   SourceLocation EndLoc, unsigned CollapsedNum,
  1605.                                   ArrayRef<OMPClause *> Clauses,
  1606.                                   Stmt *AssociatedStmt,
  1607.                                   const HelperExprs &Exprs);
  1608.  
  1609.   /// Creates an empty directive with the place
  1610.   /// for \a NumClauses clauses.
  1611.   ///
  1612.   /// \param C AST context.
  1613.   /// \param CollapsedNum Number of collapsed nested loops.
  1614.   /// \param NumClauses Number of clauses.
  1615.   ///
  1616.   static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
  1617.                                        unsigned CollapsedNum, EmptyShell);
  1618.  
  1619.   static bool classof(const Stmt *T) {
  1620.     return T->getStmtClass() == OMPSimdDirectiveClass;
  1621.   }
  1622. };
  1623.  
  1624. /// This represents '#pragma omp for' directive.
  1625. ///
  1626. /// \code
  1627. /// #pragma omp for private(a,b) reduction(+:c,d)
  1628. /// \endcode
  1629. /// In this example directive '#pragma omp for' has clauses 'private' with the
  1630. /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
  1631. /// and 'd'.
  1632. ///
  1633. class OMPForDirective : public OMPLoopDirective {
  1634.   friend class ASTStmtReader;
  1635.   friend class OMPExecutableDirective;
  1636.   /// true if current directive has inner cancel directive.
  1637.   bool HasCancel = false;
  1638.  
  1639.   /// Build directive with the given start and end location.
  1640.   ///
  1641.   /// \param StartLoc Starting location of the directive kind.
  1642.   /// \param EndLoc Ending location of the directive.
  1643.   /// \param CollapsedNum Number of collapsed nested loops.
  1644.   ///
  1645.   OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
  1646.                   unsigned CollapsedNum)
  1647.       : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, StartLoc,
  1648.                          EndLoc, CollapsedNum) {}
  1649.  
  1650.   /// Build an empty directive.
  1651.   ///
  1652.   /// \param CollapsedNum Number of collapsed nested loops.
  1653.   ///
  1654.   explicit OMPForDirective(unsigned CollapsedNum)
  1655.       : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for,
  1656.                          SourceLocation(), SourceLocation(), CollapsedNum) {}
  1657.  
  1658.   /// Sets special task reduction descriptor.
  1659.   void setTaskReductionRefExpr(Expr *E) {
  1660.     Data->getChildren()[numLoopChildren(getLoopsNumber(),
  1661.                                         llvm::omp::OMPD_for)] = E;
  1662.   }
  1663.  
  1664.   /// Set cancel state.
  1665.   void setHasCancel(bool Has) { HasCancel = Has; }
  1666.  
  1667. public:
  1668.   /// Creates directive with a list of \a Clauses.
  1669.   ///
  1670.   /// \param C AST context.
  1671.   /// \param StartLoc Starting location of the directive kind.
  1672.   /// \param EndLoc Ending Location of the directive.
  1673.   /// \param CollapsedNum Number of collapsed loops.
  1674.   /// \param Clauses List of clauses.
  1675.   /// \param AssociatedStmt Statement, associated with the directive.
  1676.   /// \param Exprs Helper expressions for CodeGen.
  1677.   /// \param TaskRedRef Task reduction special reference expression to handle
  1678.   /// taskgroup descriptor.
  1679.   /// \param HasCancel true if current directive has inner cancel directive.
  1680.   ///
  1681.   static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
  1682.                                  SourceLocation EndLoc, unsigned CollapsedNum,
  1683.                                  ArrayRef<OMPClause *> Clauses,
  1684.                                  Stmt *AssociatedStmt, const HelperExprs &Exprs,
  1685.                                  Expr *TaskRedRef, bool HasCancel);
  1686.  
  1687.   /// Creates an empty directive with the place
  1688.   /// for \a NumClauses clauses.
  1689.   ///
  1690.   /// \param C AST context.
  1691.   /// \param CollapsedNum Number of collapsed nested loops.
  1692.   /// \param NumClauses Number of clauses.
  1693.   ///
  1694.   static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
  1695.                                       unsigned CollapsedNum, EmptyShell);
  1696.  
  1697.   /// Returns special task reduction reference expression.
  1698.   Expr *getTaskReductionRefExpr() {
  1699.     return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
  1700.         getLoopsNumber(), llvm::omp::OMPD_for)]);
  1701.   }
  1702.   const Expr *getTaskReductionRefExpr() const {
  1703.     return const_cast<OMPForDirective *>(this)->getTaskReductionRefExpr();
  1704.   }
  1705.  
  1706.   /// Return true if current directive has inner cancel directive.
  1707.   bool hasCancel() const { return HasCancel; }
  1708.  
  1709.   static bool classof(const Stmt *T) {
  1710.     return T->getStmtClass() == OMPForDirectiveClass;
  1711.   }
  1712. };
  1713.  
  1714. /// This represents '#pragma omp for simd' directive.
  1715. ///
  1716. /// \code
  1717. /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
  1718. /// \endcode
  1719. /// In this example directive '#pragma omp for simd' has clauses 'private'
  1720. /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
  1721. /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
  1722. ///
  1723. class OMPForSimdDirective : public OMPLoopDirective {
  1724.   friend class ASTStmtReader;
  1725.   friend class OMPExecutableDirective;
  1726.   /// Build directive with the given start and end location.
  1727.   ///
  1728.   /// \param StartLoc Starting location of the directive kind.
  1729.   /// \param EndLoc Ending location of the directive.
  1730.   /// \param CollapsedNum Number of collapsed nested loops.
  1731.   ///
  1732.   OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
  1733.                       unsigned CollapsedNum)
  1734.       : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
  1735.                          StartLoc, EndLoc, CollapsedNum) {}
  1736.  
  1737.   /// Build an empty directive.
  1738.   ///
  1739.   /// \param CollapsedNum Number of collapsed nested loops.
  1740.   ///
  1741.   explicit OMPForSimdDirective(unsigned CollapsedNum)
  1742.       : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
  1743.                          SourceLocation(), SourceLocation(), CollapsedNum) {}
  1744.  
  1745. public:
  1746.   /// Creates directive with a list of \a Clauses.
  1747.   ///
  1748.   /// \param C AST context.
  1749.   /// \param StartLoc Starting location of the directive kind.
  1750.   /// \param EndLoc Ending Location of the directive.
  1751.   /// \param CollapsedNum Number of collapsed loops.
  1752.   /// \param Clauses List of clauses.
  1753.   /// \param AssociatedStmt Statement, associated with the directive.
  1754.   /// \param Exprs Helper expressions for CodeGen.
  1755.   ///
  1756.   static OMPForSimdDirective *
  1757.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  1758.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  1759.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  1760.  
  1761.   /// Creates an empty directive with the place
  1762.   /// for \a NumClauses clauses.
  1763.   ///
  1764.   /// \param C AST context.
  1765.   /// \param CollapsedNum Number of collapsed nested loops.
  1766.   /// \param NumClauses Number of clauses.
  1767.   ///
  1768.   static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
  1769.                                           unsigned NumClauses,
  1770.                                           unsigned CollapsedNum, EmptyShell);
  1771.  
  1772.   static bool classof(const Stmt *T) {
  1773.     return T->getStmtClass() == OMPForSimdDirectiveClass;
  1774.   }
  1775. };
  1776.  
  1777. /// This represents '#pragma omp sections' directive.
  1778. ///
  1779. /// \code
  1780. /// #pragma omp sections private(a,b) reduction(+:c,d)
  1781. /// \endcode
  1782. /// In this example directive '#pragma omp sections' has clauses 'private' with
  1783. /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
  1784. /// 'c' and 'd'.
  1785. ///
  1786. class OMPSectionsDirective : public OMPExecutableDirective {
  1787.   friend class ASTStmtReader;
  1788.   friend class OMPExecutableDirective;
  1789.  
  1790.   /// true if current directive has inner cancel directive.
  1791.   bool HasCancel = false;
  1792.  
  1793.   /// Build directive with the given start and end location.
  1794.   ///
  1795.   /// \param StartLoc Starting location of the directive kind.
  1796.   /// \param EndLoc Ending location of the directive.
  1797.   ///
  1798.   OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  1799.       : OMPExecutableDirective(OMPSectionsDirectiveClass,
  1800.                                llvm::omp::OMPD_sections, StartLoc, EndLoc) {}
  1801.  
  1802.   /// Build an empty directive.
  1803.   ///
  1804.   explicit OMPSectionsDirective()
  1805.       : OMPExecutableDirective(OMPSectionsDirectiveClass,
  1806.                                llvm::omp::OMPD_sections, SourceLocation(),
  1807.                                SourceLocation()) {}
  1808.  
  1809.   /// Sets special task reduction descriptor.
  1810.   void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
  1811.  
  1812.   /// Set cancel state.
  1813.   void setHasCancel(bool Has) { HasCancel = Has; }
  1814.  
  1815. public:
  1816.   /// Creates directive with a list of \a Clauses.
  1817.   ///
  1818.   /// \param C AST context.
  1819.   /// \param StartLoc Starting location of the directive kind.
  1820.   /// \param EndLoc Ending Location of the directive.
  1821.   /// \param Clauses List of clauses.
  1822.   /// \param AssociatedStmt Statement, associated with the directive.
  1823.   /// \param TaskRedRef Task reduction special reference expression to handle
  1824.   /// taskgroup descriptor.
  1825.   /// \param HasCancel true if current directive has inner directive.
  1826.   ///
  1827.   static OMPSectionsDirective *
  1828.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  1829.          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
  1830.          bool HasCancel);
  1831.  
  1832.   /// Creates an empty directive with the place for \a NumClauses
  1833.   /// clauses.
  1834.   ///
  1835.   /// \param C AST context.
  1836.   /// \param NumClauses Number of clauses.
  1837.   ///
  1838.   static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
  1839.                                            unsigned NumClauses, EmptyShell);
  1840.  
  1841.   /// Returns special task reduction reference expression.
  1842.   Expr *getTaskReductionRefExpr() {
  1843.     return cast_or_null<Expr>(Data->getChildren()[0]);
  1844.   }
  1845.   const Expr *getTaskReductionRefExpr() const {
  1846.     return const_cast<OMPSectionsDirective *>(this)->getTaskReductionRefExpr();
  1847.   }
  1848.  
  1849.   /// Return true if current directive has inner cancel directive.
  1850.   bool hasCancel() const { return HasCancel; }
  1851.  
  1852.   static bool classof(const Stmt *T) {
  1853.     return T->getStmtClass() == OMPSectionsDirectiveClass;
  1854.   }
  1855. };
  1856.  
  1857. /// This represents '#pragma omp section' directive.
  1858. ///
  1859. /// \code
  1860. /// #pragma omp section
  1861. /// \endcode
  1862. ///
  1863. class OMPSectionDirective : public OMPExecutableDirective {
  1864.   friend class ASTStmtReader;
  1865.   friend class OMPExecutableDirective;
  1866.  
  1867.   /// true if current directive has inner cancel directive.
  1868.   bool HasCancel = false;
  1869.  
  1870.   /// Build directive with the given start and end location.
  1871.   ///
  1872.   /// \param StartLoc Starting location of the directive kind.
  1873.   /// \param EndLoc Ending location of the directive.
  1874.   ///
  1875.   OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  1876.       : OMPExecutableDirective(OMPSectionDirectiveClass,
  1877.                                llvm::omp::OMPD_section, StartLoc, EndLoc) {}
  1878.  
  1879.   /// Build an empty directive.
  1880.   ///
  1881.   explicit OMPSectionDirective()
  1882.       : OMPExecutableDirective(OMPSectionDirectiveClass,
  1883.                                llvm::omp::OMPD_section, SourceLocation(),
  1884.                                SourceLocation()) {}
  1885.  
  1886. public:
  1887.   /// Creates directive.
  1888.   ///
  1889.   /// \param C AST context.
  1890.   /// \param StartLoc Starting location of the directive kind.
  1891.   /// \param EndLoc Ending Location of the directive.
  1892.   /// \param AssociatedStmt Statement, associated with the directive.
  1893.   /// \param HasCancel true if current directive has inner directive.
  1894.   ///
  1895.   static OMPSectionDirective *Create(const ASTContext &C,
  1896.                                      SourceLocation StartLoc,
  1897.                                      SourceLocation EndLoc,
  1898.                                      Stmt *AssociatedStmt, bool HasCancel);
  1899.  
  1900.   /// Creates an empty directive.
  1901.   ///
  1902.   /// \param C AST context.
  1903.   ///
  1904.   static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
  1905.  
  1906.   /// Set cancel state.
  1907.   void setHasCancel(bool Has) { HasCancel = Has; }
  1908.  
  1909.   /// Return true if current directive has inner cancel directive.
  1910.   bool hasCancel() const { return HasCancel; }
  1911.  
  1912.   static bool classof(const Stmt *T) {
  1913.     return T->getStmtClass() == OMPSectionDirectiveClass;
  1914.   }
  1915. };
  1916.  
  1917. /// This represents '#pragma omp single' directive.
  1918. ///
  1919. /// \code
  1920. /// #pragma omp single private(a,b) copyprivate(c,d)
  1921. /// \endcode
  1922. /// In this example directive '#pragma omp single' has clauses 'private' with
  1923. /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
  1924. ///
  1925. class OMPSingleDirective : public OMPExecutableDirective {
  1926.   friend class ASTStmtReader;
  1927.   friend class OMPExecutableDirective;
  1928.   /// Build directive with the given start and end location.
  1929.   ///
  1930.   /// \param StartLoc Starting location of the directive kind.
  1931.   /// \param EndLoc Ending location of the directive.
  1932.   ///
  1933.   OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  1934.       : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
  1935.                                StartLoc, EndLoc) {}
  1936.  
  1937.   /// Build an empty directive.
  1938.   ///
  1939.   explicit OMPSingleDirective()
  1940.       : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
  1941.                                SourceLocation(), SourceLocation()) {}
  1942.  
  1943. public:
  1944.   /// Creates directive with a list of \a Clauses.
  1945.   ///
  1946.   /// \param C AST context.
  1947.   /// \param StartLoc Starting location of the directive kind.
  1948.   /// \param EndLoc Ending Location of the directive.
  1949.   /// \param Clauses List of clauses.
  1950.   /// \param AssociatedStmt Statement, associated with the directive.
  1951.   ///
  1952.   static OMPSingleDirective *
  1953.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  1954.          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
  1955.  
  1956.   /// Creates an empty directive with the place for \a NumClauses
  1957.   /// clauses.
  1958.   ///
  1959.   /// \param C AST context.
  1960.   /// \param NumClauses Number of clauses.
  1961.   ///
  1962.   static OMPSingleDirective *CreateEmpty(const ASTContext &C,
  1963.                                          unsigned NumClauses, EmptyShell);
  1964.  
  1965.   static bool classof(const Stmt *T) {
  1966.     return T->getStmtClass() == OMPSingleDirectiveClass;
  1967.   }
  1968. };
  1969.  
  1970. /// This represents '#pragma omp master' directive.
  1971. ///
  1972. /// \code
  1973. /// #pragma omp master
  1974. /// \endcode
  1975. ///
  1976. class OMPMasterDirective : public OMPExecutableDirective {
  1977.   friend class ASTStmtReader;
  1978.   friend class OMPExecutableDirective;
  1979.   /// Build directive with the given start and end location.
  1980.   ///
  1981.   /// \param StartLoc Starting location of the directive kind.
  1982.   /// \param EndLoc Ending location of the directive.
  1983.   ///
  1984.   OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  1985.       : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
  1986.                                StartLoc, EndLoc) {}
  1987.  
  1988.   /// Build an empty directive.
  1989.   ///
  1990.   explicit OMPMasterDirective()
  1991.       : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
  1992.                                SourceLocation(), SourceLocation()) {}
  1993.  
  1994. public:
  1995.   /// Creates directive.
  1996.   ///
  1997.   /// \param C AST context.
  1998.   /// \param StartLoc Starting location of the directive kind.
  1999.   /// \param EndLoc Ending Location of the directive.
  2000.   /// \param AssociatedStmt Statement, associated with the directive.
  2001.   ///
  2002.   static OMPMasterDirective *Create(const ASTContext &C,
  2003.                                     SourceLocation StartLoc,
  2004.                                     SourceLocation EndLoc,
  2005.                                     Stmt *AssociatedStmt);
  2006.  
  2007.   /// Creates an empty directive.
  2008.   ///
  2009.   /// \param C AST context.
  2010.   ///
  2011.   static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
  2012.  
  2013.   static bool classof(const Stmt *T) {
  2014.     return T->getStmtClass() == OMPMasterDirectiveClass;
  2015.   }
  2016. };
  2017.  
  2018. /// This represents '#pragma omp critical' directive.
  2019. ///
  2020. /// \code
  2021. /// #pragma omp critical
  2022. /// \endcode
  2023. ///
  2024. class OMPCriticalDirective : public OMPExecutableDirective {
  2025.   friend class ASTStmtReader;
  2026.   friend class OMPExecutableDirective;
  2027.   /// Name of the directive.
  2028.   DeclarationNameInfo DirName;
  2029.   /// Build directive with the given start and end location.
  2030.   ///
  2031.   /// \param Name Name of the directive.
  2032.   /// \param StartLoc Starting location of the directive kind.
  2033.   /// \param EndLoc Ending location of the directive.
  2034.   ///
  2035.   OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
  2036.                        SourceLocation EndLoc)
  2037.       : OMPExecutableDirective(OMPCriticalDirectiveClass,
  2038.                                llvm::omp::OMPD_critical, StartLoc, EndLoc),
  2039.         DirName(Name) {}
  2040.  
  2041.   /// Build an empty directive.
  2042.   ///
  2043.   explicit OMPCriticalDirective()
  2044.       : OMPExecutableDirective(OMPCriticalDirectiveClass,
  2045.                                llvm::omp::OMPD_critical, SourceLocation(),
  2046.                                SourceLocation()) {}
  2047.  
  2048.   /// Set name of the directive.
  2049.   ///
  2050.   /// \param Name Name of the directive.
  2051.   ///
  2052.   void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
  2053.  
  2054. public:
  2055.   /// Creates directive.
  2056.   ///
  2057.   /// \param C AST context.
  2058.   /// \param Name Name of the directive.
  2059.   /// \param StartLoc Starting location of the directive kind.
  2060.   /// \param EndLoc Ending Location of the directive.
  2061.   /// \param Clauses List of clauses.
  2062.   /// \param AssociatedStmt Statement, associated with the directive.
  2063.   ///
  2064.   static OMPCriticalDirective *
  2065.   Create(const ASTContext &C, const DeclarationNameInfo &Name,
  2066.          SourceLocation StartLoc, SourceLocation EndLoc,
  2067.          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
  2068.  
  2069.   /// Creates an empty directive.
  2070.   ///
  2071.   /// \param C AST context.
  2072.   /// \param NumClauses Number of clauses.
  2073.   ///
  2074.   static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
  2075.                                            unsigned NumClauses, EmptyShell);
  2076.  
  2077.   /// Return name of the directive.
  2078.   ///
  2079.   DeclarationNameInfo getDirectiveName() const { return DirName; }
  2080.  
  2081.   static bool classof(const Stmt *T) {
  2082.     return T->getStmtClass() == OMPCriticalDirectiveClass;
  2083.   }
  2084. };
  2085.  
  2086. /// This represents '#pragma omp parallel for' directive.
  2087. ///
  2088. /// \code
  2089. /// #pragma omp parallel for private(a,b) reduction(+:c,d)
  2090. /// \endcode
  2091. /// In this example directive '#pragma omp parallel for' has clauses 'private'
  2092. /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
  2093. /// variables 'c' and 'd'.
  2094. ///
  2095. class OMPParallelForDirective : public OMPLoopDirective {
  2096.   friend class ASTStmtReader;
  2097.   friend class OMPExecutableDirective;
  2098.  
  2099.   /// true if current region has inner cancel directive.
  2100.   bool HasCancel = false;
  2101.  
  2102.   /// Build directive with the given start and end location.
  2103.   ///
  2104.   /// \param StartLoc Starting location of the directive kind.
  2105.   /// \param EndLoc Ending location of the directive.
  2106.   /// \param CollapsedNum Number of collapsed nested loops.
  2107.   ///
  2108.   OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
  2109.                           unsigned CollapsedNum)
  2110.       : OMPLoopDirective(OMPParallelForDirectiveClass,
  2111.                          llvm::omp::OMPD_parallel_for, StartLoc, EndLoc,
  2112.                          CollapsedNum) {}
  2113.  
  2114.   /// Build an empty directive.
  2115.   ///
  2116.   /// \param CollapsedNum Number of collapsed nested loops.
  2117.   ///
  2118.   explicit OMPParallelForDirective(unsigned CollapsedNum)
  2119.       : OMPLoopDirective(OMPParallelForDirectiveClass,
  2120.                          llvm::omp::OMPD_parallel_for, SourceLocation(),
  2121.                          SourceLocation(), CollapsedNum) {}
  2122.  
  2123.   /// Sets special task reduction descriptor.
  2124.   void setTaskReductionRefExpr(Expr *E) {
  2125.     Data->getChildren()[numLoopChildren(getLoopsNumber(),
  2126.                                         llvm::omp::OMPD_parallel_for)] = E;
  2127.   }
  2128.  
  2129.   /// Set cancel state.
  2130.   void setHasCancel(bool Has) { HasCancel = Has; }
  2131.  
  2132. public:
  2133.   /// Creates directive with a list of \a Clauses.
  2134.   ///
  2135.   /// \param C AST context.
  2136.   /// \param StartLoc Starting location of the directive kind.
  2137.   /// \param EndLoc Ending Location of the directive.
  2138.   /// \param CollapsedNum Number of collapsed loops.
  2139.   /// \param Clauses List of clauses.
  2140.   /// \param AssociatedStmt Statement, associated with the directive.
  2141.   /// \param Exprs Helper expressions for CodeGen.
  2142.   /// \param TaskRedRef Task reduction special reference expression to handle
  2143.   /// taskgroup descriptor.
  2144.   /// \param HasCancel true if current directive has inner cancel directive.
  2145.   ///
  2146.   static OMPParallelForDirective *
  2147.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  2148.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  2149.          Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
  2150.          bool HasCancel);
  2151.  
  2152.   /// Creates an empty directive with the place
  2153.   /// for \a NumClauses clauses.
  2154.   ///
  2155.   /// \param C AST context.
  2156.   /// \param CollapsedNum Number of collapsed nested loops.
  2157.   /// \param NumClauses Number of clauses.
  2158.   ///
  2159.   static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
  2160.                                               unsigned NumClauses,
  2161.                                               unsigned CollapsedNum,
  2162.                                               EmptyShell);
  2163.  
  2164.   /// Returns special task reduction reference expression.
  2165.   Expr *getTaskReductionRefExpr() {
  2166.     return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
  2167.         getLoopsNumber(), llvm::omp::OMPD_parallel_for)]);
  2168.   }
  2169.   const Expr *getTaskReductionRefExpr() const {
  2170.     return const_cast<OMPParallelForDirective *>(this)
  2171.         ->getTaskReductionRefExpr();
  2172.   }
  2173.  
  2174.   /// Return true if current directive has inner cancel directive.
  2175.   bool hasCancel() const { return HasCancel; }
  2176.  
  2177.   static bool classof(const Stmt *T) {
  2178.     return T->getStmtClass() == OMPParallelForDirectiveClass;
  2179.   }
  2180. };
  2181.  
  2182. /// This represents '#pragma omp parallel for simd' directive.
  2183. ///
  2184. /// \code
  2185. /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
  2186. /// \endcode
  2187. /// In this example directive '#pragma omp parallel for simd' has clauses
  2188. /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
  2189. /// and linear step 's', 'reduction' with operator '+' and variables 'c' and
  2190. /// 'd'.
  2191. ///
  2192. class OMPParallelForSimdDirective : public OMPLoopDirective {
  2193.   friend class ASTStmtReader;
  2194.   friend class OMPExecutableDirective;
  2195.   /// Build directive with the given start and end location.
  2196.   ///
  2197.   /// \param StartLoc Starting location of the directive kind.
  2198.   /// \param EndLoc Ending location of the directive.
  2199.   /// \param CollapsedNum Number of collapsed nested loops.
  2200.   ///
  2201.   OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
  2202.                               unsigned CollapsedNum)
  2203.       : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
  2204.                          llvm::omp::OMPD_parallel_for_simd, StartLoc, EndLoc,
  2205.                          CollapsedNum) {}
  2206.  
  2207.   /// Build an empty directive.
  2208.   ///
  2209.   /// \param CollapsedNum Number of collapsed nested loops.
  2210.   ///
  2211.   explicit OMPParallelForSimdDirective(unsigned CollapsedNum)
  2212.       : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
  2213.                          llvm::omp::OMPD_parallel_for_simd, SourceLocation(),
  2214.                          SourceLocation(), CollapsedNum) {}
  2215.  
  2216. public:
  2217.   /// Creates directive with a list of \a Clauses.
  2218.   ///
  2219.   /// \param C AST context.
  2220.   /// \param StartLoc Starting location of the directive kind.
  2221.   /// \param EndLoc Ending Location of the directive.
  2222.   /// \param CollapsedNum Number of collapsed loops.
  2223.   /// \param Clauses List of clauses.
  2224.   /// \param AssociatedStmt Statement, associated with the directive.
  2225.   /// \param Exprs Helper expressions for CodeGen.
  2226.   ///
  2227.   static OMPParallelForSimdDirective *
  2228.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  2229.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  2230.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  2231.  
  2232.   /// Creates an empty directive with the place
  2233.   /// for \a NumClauses clauses.
  2234.   ///
  2235.   /// \param C AST context.
  2236.   /// \param CollapsedNum Number of collapsed nested loops.
  2237.   /// \param NumClauses Number of clauses.
  2238.   ///
  2239.   static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
  2240.                                                   unsigned NumClauses,
  2241.                                                   unsigned CollapsedNum,
  2242.                                                   EmptyShell);
  2243.  
  2244.   static bool classof(const Stmt *T) {
  2245.     return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
  2246.   }
  2247. };
  2248.  
  2249. /// This represents '#pragma omp parallel master' directive.
  2250. ///
  2251. /// \code
  2252. /// #pragma omp parallel master private(a,b)
  2253. /// \endcode
  2254. /// In this example directive '#pragma omp parallel master' has clauses
  2255. /// 'private' with the variables 'a' and 'b'
  2256. ///
  2257. class OMPParallelMasterDirective : public OMPExecutableDirective {
  2258.   friend class ASTStmtReader;
  2259.   friend class OMPExecutableDirective;
  2260.  
  2261.   OMPParallelMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  2262.       : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
  2263.                                llvm::omp::OMPD_parallel_master, StartLoc,
  2264.                                EndLoc) {}
  2265.  
  2266.   explicit OMPParallelMasterDirective()
  2267.       : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
  2268.                                llvm::omp::OMPD_parallel_master,
  2269.                                SourceLocation(), SourceLocation()) {}
  2270.  
  2271.   /// Sets special task reduction descriptor.
  2272.   void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
  2273.  
  2274. public:
  2275.   /// Creates directive with a list of \a Clauses.
  2276.   ///
  2277.   /// \param C AST context.
  2278.   /// \param StartLoc Starting location of the directive kind.
  2279.   /// \param EndLoc Ending Location of the directive.
  2280.   /// \param Clauses List of clauses.
  2281.   /// \param AssociatedStmt Statement, associated with the directive.
  2282.   /// \param TaskRedRef Task reduction special reference expression to handle
  2283.   /// taskgroup descriptor.
  2284.   ///
  2285.   static OMPParallelMasterDirective *
  2286.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  2287.          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
  2288.  
  2289.   /// Creates an empty directive with the place for \a NumClauses
  2290.   /// clauses.
  2291.   ///
  2292.   /// \param C AST context.
  2293.   /// \param NumClauses Number of clauses.
  2294.   ///
  2295.   static OMPParallelMasterDirective *
  2296.   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
  2297.  
  2298.   /// Returns special task reduction reference expression.
  2299.   Expr *getTaskReductionRefExpr() {
  2300.     return cast_or_null<Expr>(Data->getChildren()[0]);
  2301.   }
  2302.   const Expr *getTaskReductionRefExpr() const {
  2303.     return const_cast<OMPParallelMasterDirective *>(this)
  2304.         ->getTaskReductionRefExpr();
  2305.   }
  2306.  
  2307.   static bool classof(const Stmt *T) {
  2308.     return T->getStmtClass() == OMPParallelMasterDirectiveClass;
  2309.   }
  2310. };
  2311.  
  2312. /// This represents '#pragma omp parallel masked' directive.
  2313. ///
  2314. /// \code
  2315. /// #pragma omp parallel masked filter(tid)
  2316. /// \endcode
  2317. /// In this example directive '#pragma omp parallel masked' has a clause
  2318. /// 'filter' with the variable tid
  2319. ///
  2320. class OMPParallelMaskedDirective final : public OMPExecutableDirective {
  2321.   friend class ASTStmtReader;
  2322.   friend class OMPExecutableDirective;
  2323.  
  2324.   OMPParallelMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  2325.       : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
  2326.                                llvm::omp::OMPD_parallel_masked, StartLoc,
  2327.                                EndLoc) {}
  2328.  
  2329.   explicit OMPParallelMaskedDirective()
  2330.       : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
  2331.                                llvm::omp::OMPD_parallel_masked,
  2332.                                SourceLocation(), SourceLocation()) {}
  2333.  
  2334.   /// Sets special task reduction descriptor.
  2335.   void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
  2336.  
  2337. public:
  2338.   /// Creates directive with a list of \a Clauses.
  2339.   ///
  2340.   /// \param C AST context.
  2341.   /// \param StartLoc Starting location of the directive kind.
  2342.   /// \param EndLoc Ending Location of the directive.
  2343.   /// \param Clauses List of clauses.
  2344.   /// \param AssociatedStmt Statement, associated with the directive.
  2345.   /// \param TaskRedRef Task reduction special reference expression to handle
  2346.   /// taskgroup descriptor.
  2347.   ///
  2348.   static OMPParallelMaskedDirective *
  2349.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  2350.          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
  2351.  
  2352.   /// Creates an empty directive with the place for \a NumClauses
  2353.   /// clauses.
  2354.   ///
  2355.   /// \param C AST context.
  2356.   /// \param NumClauses Number of clauses.
  2357.   ///
  2358.   static OMPParallelMaskedDirective *
  2359.   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
  2360.  
  2361.   /// Returns special task reduction reference expression.
  2362.   Expr *getTaskReductionRefExpr() {
  2363.     return cast_or_null<Expr>(Data->getChildren()[0]);
  2364.   }
  2365.   const Expr *getTaskReductionRefExpr() const {
  2366.     return const_cast<OMPParallelMaskedDirective *>(this)
  2367.         ->getTaskReductionRefExpr();
  2368.   }
  2369.  
  2370.   static bool classof(const Stmt *T) {
  2371.     return T->getStmtClass() == OMPParallelMaskedDirectiveClass;
  2372.   }
  2373. };
  2374.  
  2375. /// This represents '#pragma omp parallel sections' directive.
  2376. ///
  2377. /// \code
  2378. /// #pragma omp parallel sections private(a,b) reduction(+:c,d)
  2379. /// \endcode
  2380. /// In this example directive '#pragma omp parallel sections' has clauses
  2381. /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
  2382. /// and variables 'c' and 'd'.
  2383. ///
  2384. class OMPParallelSectionsDirective : public OMPExecutableDirective {
  2385.   friend class ASTStmtReader;
  2386.   friend class OMPExecutableDirective;
  2387.  
  2388.   /// true if current directive has inner cancel directive.
  2389.   bool HasCancel = false;
  2390.  
  2391.   /// Build directive with the given start and end location.
  2392.   ///
  2393.   /// \param StartLoc Starting location of the directive kind.
  2394.   /// \param EndLoc Ending location of the directive.
  2395.   ///
  2396.   OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  2397.       : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
  2398.                                llvm::omp::OMPD_parallel_sections, StartLoc,
  2399.                                EndLoc) {}
  2400.  
  2401.   /// Build an empty directive.
  2402.   ///
  2403.   explicit OMPParallelSectionsDirective()
  2404.       : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
  2405.                                llvm::omp::OMPD_parallel_sections,
  2406.                                SourceLocation(), SourceLocation()) {}
  2407.  
  2408.   /// Sets special task reduction descriptor.
  2409.   void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
  2410.  
  2411.   /// Set cancel state.
  2412.   void setHasCancel(bool Has) { HasCancel = Has; }
  2413.  
  2414. public:
  2415.   /// Creates directive with a list of \a Clauses.
  2416.   ///
  2417.   /// \param C AST context.
  2418.   /// \param StartLoc Starting location of the directive kind.
  2419.   /// \param EndLoc Ending Location of the directive.
  2420.   /// \param Clauses List of clauses.
  2421.   /// \param AssociatedStmt Statement, associated with the directive.
  2422.   /// \param TaskRedRef Task reduction special reference expression to handle
  2423.   /// taskgroup descriptor.
  2424.   /// \param HasCancel true if current directive has inner cancel directive.
  2425.   ///
  2426.   static OMPParallelSectionsDirective *
  2427.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  2428.          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
  2429.          bool HasCancel);
  2430.  
  2431.   /// Creates an empty directive with the place for \a NumClauses
  2432.   /// clauses.
  2433.   ///
  2434.   /// \param C AST context.
  2435.   /// \param NumClauses Number of clauses.
  2436.   ///
  2437.   static OMPParallelSectionsDirective *
  2438.   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
  2439.  
  2440.   /// Returns special task reduction reference expression.
  2441.   Expr *getTaskReductionRefExpr() {
  2442.     return cast_or_null<Expr>(Data->getChildren()[0]);
  2443.   }
  2444.   const Expr *getTaskReductionRefExpr() const {
  2445.     return const_cast<OMPParallelSectionsDirective *>(this)
  2446.         ->getTaskReductionRefExpr();
  2447.   }
  2448.  
  2449.   /// Return true if current directive has inner cancel directive.
  2450.   bool hasCancel() const { return HasCancel; }
  2451.  
  2452.   static bool classof(const Stmt *T) {
  2453.     return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
  2454.   }
  2455. };
  2456.  
  2457. /// This represents '#pragma omp task' directive.
  2458. ///
  2459. /// \code
  2460. /// #pragma omp task private(a,b) final(d)
  2461. /// \endcode
  2462. /// In this example directive '#pragma omp task' has clauses 'private' with the
  2463. /// variables 'a' and 'b' and 'final' with condition 'd'.
  2464. ///
  2465. class OMPTaskDirective : public OMPExecutableDirective {
  2466.   friend class ASTStmtReader;
  2467.   friend class OMPExecutableDirective;
  2468.   /// true if this directive has inner cancel directive.
  2469.   bool HasCancel = false;
  2470.  
  2471.   /// Build directive with the given start and end location.
  2472.   ///
  2473.   /// \param StartLoc Starting location of the directive kind.
  2474.   /// \param EndLoc Ending location of the directive.
  2475.   ///
  2476.   OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  2477.       : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
  2478.                                StartLoc, EndLoc) {}
  2479.  
  2480.   /// Build an empty directive.
  2481.   ///
  2482.   explicit OMPTaskDirective()
  2483.       : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
  2484.                                SourceLocation(), SourceLocation()) {}
  2485.  
  2486.   /// Set cancel state.
  2487.   void setHasCancel(bool Has) { HasCancel = Has; }
  2488.  
  2489. public:
  2490.   /// Creates directive with a list of \a Clauses.
  2491.   ///
  2492.   /// \param C AST context.
  2493.   /// \param StartLoc Starting location of the directive kind.
  2494.   /// \param EndLoc Ending Location of the directive.
  2495.   /// \param Clauses List of clauses.
  2496.   /// \param AssociatedStmt Statement, associated with the directive.
  2497.   /// \param HasCancel true, if current directive has inner cancel directive.
  2498.   ///
  2499.   static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
  2500.                                   SourceLocation EndLoc,
  2501.                                   ArrayRef<OMPClause *> Clauses,
  2502.                                   Stmt *AssociatedStmt, bool HasCancel);
  2503.  
  2504.   /// Creates an empty directive with the place for \a NumClauses
  2505.   /// clauses.
  2506.   ///
  2507.   /// \param C AST context.
  2508.   /// \param NumClauses Number of clauses.
  2509.   ///
  2510.   static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
  2511.                                        EmptyShell);
  2512.  
  2513.   /// Return true if current directive has inner cancel directive.
  2514.   bool hasCancel() const { return HasCancel; }
  2515.  
  2516.   static bool classof(const Stmt *T) {
  2517.     return T->getStmtClass() == OMPTaskDirectiveClass;
  2518.   }
  2519. };
  2520.  
  2521. /// This represents '#pragma omp taskyield' directive.
  2522. ///
  2523. /// \code
  2524. /// #pragma omp taskyield
  2525. /// \endcode
  2526. ///
  2527. class OMPTaskyieldDirective : public OMPExecutableDirective {
  2528.   friend class ASTStmtReader;
  2529.   friend class OMPExecutableDirective;
  2530.   /// Build directive with the given start and end location.
  2531.   ///
  2532.   /// \param StartLoc Starting location of the directive kind.
  2533.   /// \param EndLoc Ending location of the directive.
  2534.   ///
  2535.   OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  2536.       : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
  2537.                                llvm::omp::OMPD_taskyield, StartLoc, EndLoc) {}
  2538.  
  2539.   /// Build an empty directive.
  2540.   ///
  2541.   explicit OMPTaskyieldDirective()
  2542.       : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
  2543.                                llvm::omp::OMPD_taskyield, SourceLocation(),
  2544.                                SourceLocation()) {}
  2545.  
  2546. public:
  2547.   /// Creates directive.
  2548.   ///
  2549.   /// \param C AST context.
  2550.   /// \param StartLoc Starting location of the directive kind.
  2551.   /// \param EndLoc Ending Location of the directive.
  2552.   ///
  2553.   static OMPTaskyieldDirective *
  2554.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
  2555.  
  2556.   /// Creates an empty directive.
  2557.   ///
  2558.   /// \param C AST context.
  2559.   ///
  2560.   static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
  2561.  
  2562.   static bool classof(const Stmt *T) {
  2563.     return T->getStmtClass() == OMPTaskyieldDirectiveClass;
  2564.   }
  2565. };
  2566.  
  2567. /// This represents '#pragma omp barrier' directive.
  2568. ///
  2569. /// \code
  2570. /// #pragma omp barrier
  2571. /// \endcode
  2572. ///
  2573. class OMPBarrierDirective : public OMPExecutableDirective {
  2574.   friend class ASTStmtReader;
  2575.   friend class OMPExecutableDirective;
  2576.   /// Build directive with the given start and end location.
  2577.   ///
  2578.   /// \param StartLoc Starting location of the directive kind.
  2579.   /// \param EndLoc Ending location of the directive.
  2580.   ///
  2581.   OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  2582.       : OMPExecutableDirective(OMPBarrierDirectiveClass,
  2583.                                llvm::omp::OMPD_barrier, StartLoc, EndLoc) {}
  2584.  
  2585.   /// Build an empty directive.
  2586.   ///
  2587.   explicit OMPBarrierDirective()
  2588.       : OMPExecutableDirective(OMPBarrierDirectiveClass,
  2589.                                llvm::omp::OMPD_barrier, SourceLocation(),
  2590.                                SourceLocation()) {}
  2591.  
  2592. public:
  2593.   /// Creates directive.
  2594.   ///
  2595.   /// \param C AST context.
  2596.   /// \param StartLoc Starting location of the directive kind.
  2597.   /// \param EndLoc Ending Location of the directive.
  2598.   ///
  2599.   static OMPBarrierDirective *
  2600.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
  2601.  
  2602.   /// Creates an empty directive.
  2603.   ///
  2604.   /// \param C AST context.
  2605.   ///
  2606.   static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
  2607.  
  2608.   static bool classof(const Stmt *T) {
  2609.     return T->getStmtClass() == OMPBarrierDirectiveClass;
  2610.   }
  2611. };
  2612.  
  2613. /// This represents '#pragma omp taskwait' directive.
  2614. ///
  2615. /// \code
  2616. /// #pragma omp taskwait
  2617. /// \endcode
  2618. ///
  2619. class OMPTaskwaitDirective : public OMPExecutableDirective {
  2620.   friend class ASTStmtReader;
  2621.   friend class OMPExecutableDirective;
  2622.   /// Build directive with the given start and end location.
  2623.   ///
  2624.   /// \param StartLoc Starting location of the directive kind.
  2625.   /// \param EndLoc Ending location of the directive.
  2626.   ///
  2627.   OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  2628.       : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
  2629.                                llvm::omp::OMPD_taskwait, StartLoc, EndLoc) {}
  2630.  
  2631.   /// Build an empty directive.
  2632.   ///
  2633.   explicit OMPTaskwaitDirective()
  2634.       : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
  2635.                                llvm::omp::OMPD_taskwait, SourceLocation(),
  2636.                                SourceLocation()) {}
  2637.  
  2638. public:
  2639.   /// Creates directive.
  2640.   ///
  2641.   /// \param C AST context.
  2642.   /// \param StartLoc Starting location of the directive kind.
  2643.   /// \param EndLoc Ending Location of the directive.
  2644.   /// \param Clauses List of clauses.
  2645.   ///
  2646.   static OMPTaskwaitDirective *Create(const ASTContext &C,
  2647.                                       SourceLocation StartLoc,
  2648.                                       SourceLocation EndLoc,
  2649.                                       ArrayRef<OMPClause *> Clauses);
  2650.  
  2651.   /// Creates an empty directive.
  2652.   ///
  2653.   /// \param C AST context.
  2654.   /// \param NumClauses Number of clauses.
  2655.   ///
  2656.   static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C,
  2657.                                            unsigned NumClauses, EmptyShell);
  2658.  
  2659.   static bool classof(const Stmt *T) {
  2660.     return T->getStmtClass() == OMPTaskwaitDirectiveClass;
  2661.   }
  2662. };
  2663.  
  2664. /// This represents '#pragma omp taskgroup' directive.
  2665. ///
  2666. /// \code
  2667. /// #pragma omp taskgroup
  2668. /// \endcode
  2669. ///
  2670. class OMPTaskgroupDirective : public OMPExecutableDirective {
  2671.   friend class ASTStmtReader;
  2672.   friend class OMPExecutableDirective;
  2673.   /// Build directive with the given start and end location.
  2674.   ///
  2675.   /// \param StartLoc Starting location of the directive kind.
  2676.   /// \param EndLoc Ending location of the directive.
  2677.   ///
  2678.   OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  2679.       : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
  2680.                                llvm::omp::OMPD_taskgroup, StartLoc, EndLoc) {}
  2681.  
  2682.   /// Build an empty directive.
  2683.   ///
  2684.   explicit OMPTaskgroupDirective()
  2685.       : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
  2686.                                llvm::omp::OMPD_taskgroup, SourceLocation(),
  2687.                                SourceLocation()) {}
  2688.  
  2689.   /// Sets the task_reduction return variable.
  2690.   void setReductionRef(Expr *RR) { Data->getChildren()[0] = RR; }
  2691.  
  2692. public:
  2693.   /// Creates directive.
  2694.   ///
  2695.   /// \param C AST context.
  2696.   /// \param StartLoc Starting location of the directive kind.
  2697.   /// \param EndLoc Ending Location of the directive.
  2698.   /// \param Clauses List of clauses.
  2699.   /// \param AssociatedStmt Statement, associated with the directive.
  2700.   /// \param ReductionRef Reference to the task_reduction return variable.
  2701.   ///
  2702.   static OMPTaskgroupDirective *
  2703.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  2704.          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
  2705.          Expr *ReductionRef);
  2706.  
  2707.   /// Creates an empty directive.
  2708.   ///
  2709.   /// \param C AST context.
  2710.   /// \param NumClauses Number of clauses.
  2711.   ///
  2712.   static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C,
  2713.                                             unsigned NumClauses, EmptyShell);
  2714.  
  2715.  
  2716.   /// Returns reference to the task_reduction return variable.
  2717.   const Expr *getReductionRef() const {
  2718.     return const_cast<OMPTaskgroupDirective *>(this)->getReductionRef();
  2719.   }
  2720.   Expr *getReductionRef() { return cast_or_null<Expr>(Data->getChildren()[0]); }
  2721.  
  2722.   static bool classof(const Stmt *T) {
  2723.     return T->getStmtClass() == OMPTaskgroupDirectiveClass;
  2724.   }
  2725. };
  2726.  
  2727. /// This represents '#pragma omp flush' directive.
  2728. ///
  2729. /// \code
  2730. /// #pragma omp flush(a,b)
  2731. /// \endcode
  2732. /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
  2733. /// and 'b'.
  2734. /// 'omp flush' directive does not have clauses but have an optional list of
  2735. /// variables to flush. This list of variables is stored within some fake clause
  2736. /// FlushClause.
  2737. class OMPFlushDirective : public OMPExecutableDirective {
  2738.   friend class ASTStmtReader;
  2739.   friend class OMPExecutableDirective;
  2740.   /// Build directive with the given start and end location.
  2741.   ///
  2742.   /// \param StartLoc Starting location of the directive kind.
  2743.   /// \param EndLoc Ending location of the directive.
  2744.   ///
  2745.   OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  2746.       : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
  2747.                                StartLoc, EndLoc) {}
  2748.  
  2749.   /// Build an empty directive.
  2750.   ///
  2751.   explicit OMPFlushDirective()
  2752.       : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
  2753.                                SourceLocation(), SourceLocation()) {}
  2754.  
  2755. public:
  2756.   /// Creates directive with a list of \a Clauses.
  2757.   ///
  2758.   /// \param C AST context.
  2759.   /// \param StartLoc Starting location of the directive kind.
  2760.   /// \param EndLoc Ending Location of the directive.
  2761.   /// \param Clauses List of clauses (only single OMPFlushClause clause is
  2762.   /// allowed).
  2763.   ///
  2764.   static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
  2765.                                    SourceLocation EndLoc,
  2766.                                    ArrayRef<OMPClause *> Clauses);
  2767.  
  2768.   /// Creates an empty directive with the place for \a NumClauses
  2769.   /// clauses.
  2770.   ///
  2771.   /// \param C AST context.
  2772.   /// \param NumClauses Number of clauses.
  2773.   ///
  2774.   static OMPFlushDirective *CreateEmpty(const ASTContext &C,
  2775.                                         unsigned NumClauses, EmptyShell);
  2776.  
  2777.   static bool classof(const Stmt *T) {
  2778.     return T->getStmtClass() == OMPFlushDirectiveClass;
  2779.   }
  2780. };
  2781.  
  2782. /// This represents '#pragma omp depobj' directive.
  2783. ///
  2784. /// \code
  2785. /// #pragma omp depobj(a) depend(in:x,y)
  2786. /// \endcode
  2787. /// In this example directive '#pragma omp  depobj' initializes a depobj object
  2788. /// 'a' with dependence type 'in' and a list with 'x' and 'y' locators.
  2789. class OMPDepobjDirective final : public OMPExecutableDirective {
  2790.   friend class ASTStmtReader;
  2791.   friend class OMPExecutableDirective;
  2792.  
  2793.   /// Build directive with the given start and end location.
  2794.   ///
  2795.   /// \param StartLoc Starting location of the directive kind.
  2796.   /// \param EndLoc Ending location of the directive.
  2797.   ///
  2798.   OMPDepobjDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  2799.       : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
  2800.                                StartLoc, EndLoc) {}
  2801.  
  2802.   /// Build an empty directive.
  2803.   ///
  2804.   explicit OMPDepobjDirective()
  2805.       : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
  2806.                                SourceLocation(), SourceLocation()) {}
  2807.  
  2808. public:
  2809.   /// Creates directive with a list of \a Clauses.
  2810.   ///
  2811.   /// \param C AST context.
  2812.   /// \param StartLoc Starting location of the directive kind.
  2813.   /// \param EndLoc Ending Location of the directive.
  2814.   /// \param Clauses List of clauses.
  2815.   ///
  2816.   static OMPDepobjDirective *Create(const ASTContext &C,
  2817.                                     SourceLocation StartLoc,
  2818.                                     SourceLocation EndLoc,
  2819.                                     ArrayRef<OMPClause *> Clauses);
  2820.  
  2821.   /// Creates an empty directive with the place for \a NumClauses
  2822.   /// clauses.
  2823.   ///
  2824.   /// \param C AST context.
  2825.   /// \param NumClauses Number of clauses.
  2826.   ///
  2827.   static OMPDepobjDirective *CreateEmpty(const ASTContext &C,
  2828.                                          unsigned NumClauses, EmptyShell);
  2829.  
  2830.   static bool classof(const Stmt *T) {
  2831.     return T->getStmtClass() == OMPDepobjDirectiveClass;
  2832.   }
  2833. };
  2834.  
  2835. /// This represents '#pragma omp ordered' directive.
  2836. ///
  2837. /// \code
  2838. /// #pragma omp ordered
  2839. /// \endcode
  2840. ///
  2841. class OMPOrderedDirective : public OMPExecutableDirective {
  2842.   friend class ASTStmtReader;
  2843.   friend class OMPExecutableDirective;
  2844.   /// Build directive with the given start and end location.
  2845.   ///
  2846.   /// \param StartLoc Starting location of the directive kind.
  2847.   /// \param EndLoc Ending location of the directive.
  2848.   ///
  2849.   OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  2850.       : OMPExecutableDirective(OMPOrderedDirectiveClass,
  2851.                                llvm::omp::OMPD_ordered, StartLoc, EndLoc) {}
  2852.  
  2853.   /// Build an empty directive.
  2854.   ///
  2855.   explicit OMPOrderedDirective()
  2856.       : OMPExecutableDirective(OMPOrderedDirectiveClass,
  2857.                                llvm::omp::OMPD_ordered, SourceLocation(),
  2858.                                SourceLocation()) {}
  2859.  
  2860. public:
  2861.   /// Creates directive.
  2862.   ///
  2863.   /// \param C AST context.
  2864.   /// \param StartLoc Starting location of the directive kind.
  2865.   /// \param EndLoc Ending Location of the directive.
  2866.   /// \param Clauses List of clauses.
  2867.   /// \param AssociatedStmt Statement, associated with the directive.
  2868.   ///
  2869.   static OMPOrderedDirective *
  2870.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  2871.          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
  2872.  
  2873.   /// Creates an empty directive.
  2874.   ///
  2875.   /// \param C AST context.
  2876.   /// \param NumClauses Number of clauses.
  2877.   /// \param IsStandalone true, if the standalone directive is created.
  2878.   ///
  2879.   static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
  2880.                                           unsigned NumClauses,
  2881.                                           bool IsStandalone, EmptyShell);
  2882.  
  2883.   static bool classof(const Stmt *T) {
  2884.     return T->getStmtClass() == OMPOrderedDirectiveClass;
  2885.   }
  2886. };
  2887.  
  2888. /// This represents '#pragma omp atomic' directive.
  2889. ///
  2890. /// \code
  2891. /// #pragma omp atomic capture
  2892. /// \endcode
  2893. /// In this example directive '#pragma omp atomic' has clause 'capture'.
  2894. ///
  2895. class OMPAtomicDirective : public OMPExecutableDirective {
  2896.   friend class ASTStmtReader;
  2897.   friend class OMPExecutableDirective;
  2898.  
  2899.   struct FlagTy {
  2900.     /// Used for 'atomic update' or 'atomic capture' constructs. They may
  2901.     /// have atomic expressions of forms:
  2902.     /// \code
  2903.     /// x = x binop expr;
  2904.     /// x = expr binop x;
  2905.     /// \endcode
  2906.     /// This field is 1 for the first form of the expression and 0 for the
  2907.     /// second. Required for correct codegen of non-associative operations (like
  2908.     /// << or >>).
  2909.     uint8_t IsXLHSInRHSPart : 1;
  2910.     /// Used for 'atomic update' or 'atomic capture' constructs. They may
  2911.     /// have atomic expressions of forms:
  2912.     /// \code
  2913.     /// v = x; <update x>;
  2914.     /// <update x>; v = x;
  2915.     /// \endcode
  2916.     /// This field is 1 for the first(postfix) form of the expression and 0
  2917.     /// otherwise.
  2918.     uint8_t IsPostfixUpdate : 1;
  2919.     /// 1 if 'v' is updated only when the condition is false (compare capture
  2920.     /// only).
  2921.     uint8_t IsFailOnly : 1;
  2922.   } Flags;
  2923.  
  2924.   /// Build directive with the given start and end location.
  2925.   ///
  2926.   /// \param StartLoc Starting location of the directive kind.
  2927.   /// \param EndLoc Ending location of the directive.
  2928.   ///
  2929.   OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  2930.       : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
  2931.                                StartLoc, EndLoc) {}
  2932.  
  2933.   /// Build an empty directive.
  2934.   ///
  2935.   explicit OMPAtomicDirective()
  2936.       : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
  2937.                                SourceLocation(), SourceLocation()) {}
  2938.  
  2939.   enum DataPositionTy : size_t {
  2940.     POS_X = 0,
  2941.     POS_V,
  2942.     POS_E,
  2943.     POS_UpdateExpr,
  2944.     POS_D,
  2945.     POS_Cond,
  2946.     POS_R,
  2947.   };
  2948.  
  2949.   /// Set 'x' part of the associated expression/statement.
  2950.   void setX(Expr *X) { Data->getChildren()[DataPositionTy::POS_X] = X; }
  2951.   /// Set helper expression of the form
  2952.   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
  2953.   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
  2954.   void setUpdateExpr(Expr *UE) {
  2955.     Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE;
  2956.   }
  2957.   /// Set 'v' part of the associated expression/statement.
  2958.   void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; }
  2959.   /// Set 'r' part of the associated expression/statement.
  2960.   void setR(Expr *R) { Data->getChildren()[DataPositionTy::POS_R] = R; }
  2961.   /// Set 'expr' part of the associated expression/statement.
  2962.   void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; }
  2963.   /// Set 'd' part of the associated expression/statement.
  2964.   void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; }
  2965.   /// Set conditional expression in `atomic compare`.
  2966.   void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; }
  2967.  
  2968. public:
  2969.   struct Expressions {
  2970.     /// 'x' part of the associated expression/statement.
  2971.     Expr *X = nullptr;
  2972.     /// 'v' part of the associated expression/statement.
  2973.     Expr *V = nullptr;
  2974.     // 'r' part of the associated expression/statement.
  2975.     Expr *R = nullptr;
  2976.     /// 'expr' part of the associated expression/statement.
  2977.     Expr *E = nullptr;
  2978.     /// UE Helper expression of the form:
  2979.     /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
  2980.     /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
  2981.     Expr *UE = nullptr;
  2982.     /// 'd' part of the associated expression/statement.
  2983.     Expr *D = nullptr;
  2984.     /// Conditional expression in `atomic compare` construct.
  2985.     Expr *Cond = nullptr;
  2986.     /// True if UE has the first form and false if the second.
  2987.     bool IsXLHSInRHSPart;
  2988.     /// True if original value of 'x' must be stored in 'v', not an updated one.
  2989.     bool IsPostfixUpdate;
  2990.     /// True if 'v' is updated only when the condition is false (compare capture
  2991.     /// only).
  2992.     bool IsFailOnly;
  2993.   };
  2994.  
  2995.   /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
  2996.   /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
  2997.   /// detailed description of 'x', 'v' and 'expr').
  2998.   ///
  2999.   /// \param C AST context.
  3000.   /// \param StartLoc Starting location of the directive kind.
  3001.   /// \param EndLoc Ending Location of the directive.
  3002.   /// \param Clauses List of clauses.
  3003.   /// \param AssociatedStmt Statement, associated with the directive.
  3004.   /// \param Exprs Associated expressions or statements.
  3005.   static OMPAtomicDirective *Create(const ASTContext &C,
  3006.                                     SourceLocation StartLoc,
  3007.                                     SourceLocation EndLoc,
  3008.                                     ArrayRef<OMPClause *> Clauses,
  3009.                                     Stmt *AssociatedStmt, Expressions Exprs);
  3010.  
  3011.   /// Creates an empty directive with the place for \a NumClauses
  3012.   /// clauses.
  3013.   ///
  3014.   /// \param C AST context.
  3015.   /// \param NumClauses Number of clauses.
  3016.   ///
  3017.   static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
  3018.                                          unsigned NumClauses, EmptyShell);
  3019.  
  3020.   /// Get 'x' part of the associated expression/statement.
  3021.   Expr *getX() {
  3022.     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
  3023.   }
  3024.   const Expr *getX() const {
  3025.     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
  3026.   }
  3027.   /// Get helper expression of the form
  3028.   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
  3029.   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
  3030.   Expr *getUpdateExpr() {
  3031.     return cast_or_null<Expr>(
  3032.         Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
  3033.   }
  3034.   const Expr *getUpdateExpr() const {
  3035.     return cast_or_null<Expr>(
  3036.         Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
  3037.   }
  3038.   /// Return true if helper update expression has form
  3039.   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
  3040.   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
  3041.   bool isXLHSInRHSPart() const { return Flags.IsXLHSInRHSPart; }
  3042.   /// Return true if 'v' expression must be updated to original value of
  3043.   /// 'x', false if 'v' must be updated to the new value of 'x'.
  3044.   bool isPostfixUpdate() const { return Flags.IsPostfixUpdate; }
  3045.   /// Return true if 'v' is updated only when the condition is evaluated false
  3046.   /// (compare capture only).
  3047.   bool isFailOnly() const { return Flags.IsFailOnly; }
  3048.   /// Get 'v' part of the associated expression/statement.
  3049.   Expr *getV() {
  3050.     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
  3051.   }
  3052.   const Expr *getV() const {
  3053.     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
  3054.   }
  3055.   /// Get 'r' part of the associated expression/statement.
  3056.   Expr *getR() {
  3057.     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
  3058.   }
  3059.   const Expr *getR() const {
  3060.     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
  3061.   }
  3062.   /// Get 'expr' part of the associated expression/statement.
  3063.   Expr *getExpr() {
  3064.     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
  3065.   }
  3066.   const Expr *getExpr() const {
  3067.     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
  3068.   }
  3069.   /// Get 'd' part of the associated expression/statement.
  3070.   Expr *getD() {
  3071.     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
  3072.   }
  3073.   Expr *getD() const {
  3074.     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
  3075.   }
  3076.   /// Get the 'cond' part of the source atomic expression.
  3077.   Expr *getCondExpr() {
  3078.     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
  3079.   }
  3080.   Expr *getCondExpr() const {
  3081.     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
  3082.   }
  3083.  
  3084.   static bool classof(const Stmt *T) {
  3085.     return T->getStmtClass() == OMPAtomicDirectiveClass;
  3086.   }
  3087. };
  3088.  
  3089. /// This represents '#pragma omp target' directive.
  3090. ///
  3091. /// \code
  3092. /// #pragma omp target if(a)
  3093. /// \endcode
  3094. /// In this example directive '#pragma omp target' has clause 'if' with
  3095. /// condition 'a'.
  3096. ///
  3097. class OMPTargetDirective : public OMPExecutableDirective {
  3098.   friend class ASTStmtReader;
  3099.   friend class OMPExecutableDirective;
  3100.   /// Build directive with the given start and end location.
  3101.   ///
  3102.   /// \param StartLoc Starting location of the directive kind.
  3103.   /// \param EndLoc Ending location of the directive.
  3104.   ///
  3105.   OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  3106.       : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
  3107.                                StartLoc, EndLoc) {}
  3108.  
  3109.   /// Build an empty directive.
  3110.   ///
  3111.   explicit OMPTargetDirective()
  3112.       : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
  3113.                                SourceLocation(), SourceLocation()) {}
  3114.  
  3115. public:
  3116.   /// Creates directive with a list of \a Clauses.
  3117.   ///
  3118.   /// \param C AST context.
  3119.   /// \param StartLoc Starting location of the directive kind.
  3120.   /// \param EndLoc Ending Location of the directive.
  3121.   /// \param Clauses List of clauses.
  3122.   /// \param AssociatedStmt Statement, associated with the directive.
  3123.   ///
  3124.   static OMPTargetDirective *
  3125.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  3126.          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
  3127.  
  3128.   /// Creates an empty directive with the place for \a NumClauses
  3129.   /// clauses.
  3130.   ///
  3131.   /// \param C AST context.
  3132.   /// \param NumClauses Number of clauses.
  3133.   ///
  3134.   static OMPTargetDirective *CreateEmpty(const ASTContext &C,
  3135.                                          unsigned NumClauses, EmptyShell);
  3136.  
  3137.   static bool classof(const Stmt *T) {
  3138.     return T->getStmtClass() == OMPTargetDirectiveClass;
  3139.   }
  3140. };
  3141.  
  3142. /// This represents '#pragma omp target data' directive.
  3143. ///
  3144. /// \code
  3145. /// #pragma omp target data device(0) if(a) map(b[:])
  3146. /// \endcode
  3147. /// In this example directive '#pragma omp target data' has clauses 'device'
  3148. /// with the value '0', 'if' with condition 'a' and 'map' with array
  3149. /// section 'b[:]'.
  3150. ///
  3151. class OMPTargetDataDirective : public OMPExecutableDirective {
  3152.   friend class ASTStmtReader;
  3153.   friend class OMPExecutableDirective;
  3154.   /// Build directive with the given start and end location.
  3155.   ///
  3156.   /// \param StartLoc Starting location of the directive kind.
  3157.   /// \param EndLoc Ending Location of the directive.
  3158.   ///
  3159.   OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  3160.       : OMPExecutableDirective(OMPTargetDataDirectiveClass,
  3161.                                llvm::omp::OMPD_target_data, StartLoc, EndLoc) {}
  3162.  
  3163.   /// Build an empty directive.
  3164.   ///
  3165.   explicit OMPTargetDataDirective()
  3166.       : OMPExecutableDirective(OMPTargetDataDirectiveClass,
  3167.                                llvm::omp::OMPD_target_data, SourceLocation(),
  3168.                                SourceLocation()) {}
  3169.  
  3170. public:
  3171.   /// Creates directive with a list of \a Clauses.
  3172.   ///
  3173.   /// \param C AST context.
  3174.   /// \param StartLoc Starting location of the directive kind.
  3175.   /// \param EndLoc Ending Location of the directive.
  3176.   /// \param Clauses List of clauses.
  3177.   /// \param AssociatedStmt Statement, associated with the directive.
  3178.   ///
  3179.   static OMPTargetDataDirective *
  3180.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  3181.          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
  3182.  
  3183.   /// Creates an empty directive with the place for \a N clauses.
  3184.   ///
  3185.   /// \param C AST context.
  3186.   /// \param N The number of clauses.
  3187.   ///
  3188.   static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
  3189.                                              EmptyShell);
  3190.  
  3191.   static bool classof(const Stmt *T) {
  3192.     return T->getStmtClass() == OMPTargetDataDirectiveClass;
  3193.   }
  3194. };
  3195.  
  3196. /// This represents '#pragma omp target enter data' directive.
  3197. ///
  3198. /// \code
  3199. /// #pragma omp target enter data device(0) if(a) map(b[:])
  3200. /// \endcode
  3201. /// In this example directive '#pragma omp target enter data' has clauses
  3202. /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
  3203. /// section 'b[:]'.
  3204. ///
  3205. class OMPTargetEnterDataDirective : public OMPExecutableDirective {
  3206.   friend class ASTStmtReader;
  3207.   friend class OMPExecutableDirective;
  3208.   /// Build directive with the given start and end location.
  3209.   ///
  3210.   /// \param StartLoc Starting location of the directive kind.
  3211.   /// \param EndLoc Ending Location of the directive.
  3212.   ///
  3213.   OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  3214.       : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
  3215.                                llvm::omp::OMPD_target_enter_data, StartLoc,
  3216.                                EndLoc) {}
  3217.  
  3218.   /// Build an empty directive.
  3219.   ///
  3220.   explicit OMPTargetEnterDataDirective()
  3221.       : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
  3222.                                llvm::omp::OMPD_target_enter_data,
  3223.                                SourceLocation(), SourceLocation()) {}
  3224.  
  3225. public:
  3226.   /// Creates directive with a list of \a Clauses.
  3227.   ///
  3228.   /// \param C AST context.
  3229.   /// \param StartLoc Starting location of the directive kind.
  3230.   /// \param EndLoc Ending Location of the directive.
  3231.   /// \param Clauses List of clauses.
  3232.   /// \param AssociatedStmt Statement, associated with the directive.
  3233.   ///
  3234.   static OMPTargetEnterDataDirective *
  3235.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  3236.          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
  3237.  
  3238.   /// Creates an empty directive with the place for \a N clauses.
  3239.   ///
  3240.   /// \param C AST context.
  3241.   /// \param N The number of clauses.
  3242.   ///
  3243.   static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C,
  3244.                                                   unsigned N, EmptyShell);
  3245.  
  3246.   static bool classof(const Stmt *T) {
  3247.     return T->getStmtClass() == OMPTargetEnterDataDirectiveClass;
  3248.   }
  3249. };
  3250.  
  3251. /// This represents '#pragma omp target exit data' directive.
  3252. ///
  3253. /// \code
  3254. /// #pragma omp target exit data device(0) if(a) map(b[:])
  3255. /// \endcode
  3256. /// In this example directive '#pragma omp target exit data' has clauses
  3257. /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
  3258. /// section 'b[:]'.
  3259. ///
  3260. class OMPTargetExitDataDirective : public OMPExecutableDirective {
  3261.   friend class ASTStmtReader;
  3262.   friend class OMPExecutableDirective;
  3263.   /// Build directive with the given start and end location.
  3264.   ///
  3265.   /// \param StartLoc Starting location of the directive kind.
  3266.   /// \param EndLoc Ending Location of the directive.
  3267.   ///
  3268.   OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  3269.       : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
  3270.                                llvm::omp::OMPD_target_exit_data, StartLoc,
  3271.                                EndLoc) {}
  3272.  
  3273.   /// Build an empty directive.
  3274.   ///
  3275.   explicit OMPTargetExitDataDirective()
  3276.       : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
  3277.                                llvm::omp::OMPD_target_exit_data,
  3278.                                SourceLocation(), SourceLocation()) {}
  3279.  
  3280. public:
  3281.   /// Creates directive with a list of \a Clauses.
  3282.   ///
  3283.   /// \param C AST context.
  3284.   /// \param StartLoc Starting location of the directive kind.
  3285.   /// \param EndLoc Ending Location of the directive.
  3286.   /// \param Clauses List of clauses.
  3287.   /// \param AssociatedStmt Statement, associated with the directive.
  3288.   ///
  3289.   static OMPTargetExitDataDirective *
  3290.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  3291.          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
  3292.  
  3293.   /// Creates an empty directive with the place for \a N clauses.
  3294.   ///
  3295.   /// \param C AST context.
  3296.   /// \param N The number of clauses.
  3297.   ///
  3298.   static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
  3299.                                                  unsigned N, EmptyShell);
  3300.  
  3301.   static bool classof(const Stmt *T) {
  3302.     return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
  3303.   }
  3304. };
  3305.  
  3306. /// This represents '#pragma omp target parallel' directive.
  3307. ///
  3308. /// \code
  3309. /// #pragma omp target parallel if(a)
  3310. /// \endcode
  3311. /// In this example directive '#pragma omp target parallel' has clause 'if' with
  3312. /// condition 'a'.
  3313. ///
  3314. class OMPTargetParallelDirective : public OMPExecutableDirective {
  3315.   friend class ASTStmtReader;
  3316.   friend class OMPExecutableDirective;
  3317.   /// true if the construct has inner cancel directive.
  3318.   bool HasCancel = false;
  3319.  
  3320.   /// Build directive with the given start and end location.
  3321.   ///
  3322.   /// \param StartLoc Starting location of the directive kind.
  3323.   /// \param EndLoc Ending location of the directive.
  3324.   ///
  3325.   OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  3326.       : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
  3327.                                llvm::omp::OMPD_target_parallel, StartLoc,
  3328.                                EndLoc) {}
  3329.  
  3330.   /// Build an empty directive.
  3331.   ///
  3332.   explicit OMPTargetParallelDirective()
  3333.       : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
  3334.                                llvm::omp::OMPD_target_parallel,
  3335.                                SourceLocation(), SourceLocation()) {}
  3336.  
  3337.   /// Sets special task reduction descriptor.
  3338.   void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
  3339.   /// Set cancel state.
  3340.   void setHasCancel(bool Has) { HasCancel = Has; }
  3341.  
  3342. public:
  3343.   /// Creates directive with a list of \a Clauses.
  3344.   ///
  3345.   /// \param C AST context.
  3346.   /// \param StartLoc Starting location of the directive kind.
  3347.   /// \param EndLoc Ending Location of the directive.
  3348.   /// \param Clauses List of clauses.
  3349.   /// \param AssociatedStmt Statement, associated with the directive.
  3350.   /// \param TaskRedRef Task reduction special reference expression to handle
  3351.   /// taskgroup descriptor.
  3352.   /// \param HasCancel true if this directive has inner cancel directive.
  3353.   ///
  3354.   static OMPTargetParallelDirective *
  3355.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  3356.          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
  3357.          bool HasCancel);
  3358.  
  3359.   /// Creates an empty directive with the place for \a NumClauses
  3360.   /// clauses.
  3361.   ///
  3362.   /// \param C AST context.
  3363.   /// \param NumClauses Number of clauses.
  3364.   ///
  3365.   static OMPTargetParallelDirective *
  3366.   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
  3367.  
  3368.   /// Returns special task reduction reference expression.
  3369.   Expr *getTaskReductionRefExpr() {
  3370.     return cast_or_null<Expr>(Data->getChildren()[0]);
  3371.   }
  3372.   const Expr *getTaskReductionRefExpr() const {
  3373.     return const_cast<OMPTargetParallelDirective *>(this)
  3374.         ->getTaskReductionRefExpr();
  3375.   }
  3376.  
  3377.   /// Return true if current directive has inner cancel directive.
  3378.   bool hasCancel() const { return HasCancel; }
  3379.  
  3380.   static bool classof(const Stmt *T) {
  3381.     return T->getStmtClass() == OMPTargetParallelDirectiveClass;
  3382.   }
  3383. };
  3384.  
  3385. /// This represents '#pragma omp target parallel for' directive.
  3386. ///
  3387. /// \code
  3388. /// #pragma omp target parallel for private(a,b) reduction(+:c,d)
  3389. /// \endcode
  3390. /// In this example directive '#pragma omp target parallel for' has clauses
  3391. /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
  3392. /// and variables 'c' and 'd'.
  3393. ///
  3394. class OMPTargetParallelForDirective : public OMPLoopDirective {
  3395.   friend class ASTStmtReader;
  3396.   friend class OMPExecutableDirective;
  3397.  
  3398.   /// true if current region has inner cancel directive.
  3399.   bool HasCancel = false;
  3400.  
  3401.   /// Build directive with the given start and end location.
  3402.   ///
  3403.   /// \param StartLoc Starting location of the directive kind.
  3404.   /// \param EndLoc Ending location of the directive.
  3405.   /// \param CollapsedNum Number of collapsed nested loops.
  3406.   ///
  3407.   OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
  3408.                                 unsigned CollapsedNum)
  3409.       : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
  3410.                          llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc,
  3411.                          CollapsedNum) {}
  3412.  
  3413.   /// Build an empty directive.
  3414.   ///
  3415.   /// \param CollapsedNum Number of collapsed nested loops.
  3416.   ///
  3417.   explicit OMPTargetParallelForDirective(unsigned CollapsedNum)
  3418.       : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
  3419.                          llvm::omp::OMPD_target_parallel_for, SourceLocation(),
  3420.                          SourceLocation(), CollapsedNum) {}
  3421.  
  3422.   /// Sets special task reduction descriptor.
  3423.   void setTaskReductionRefExpr(Expr *E) {
  3424.     Data->getChildren()[numLoopChildren(
  3425.         getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E;
  3426.   }
  3427.  
  3428.   /// Set cancel state.
  3429.   void setHasCancel(bool Has) { HasCancel = Has; }
  3430.  
  3431. public:
  3432.   /// Creates directive with a list of \a Clauses.
  3433.   ///
  3434.   /// \param C AST context.
  3435.   /// \param StartLoc Starting location of the directive kind.
  3436.   /// \param EndLoc Ending Location of the directive.
  3437.   /// \param CollapsedNum Number of collapsed loops.
  3438.   /// \param Clauses List of clauses.
  3439.   /// \param AssociatedStmt Statement, associated with the directive.
  3440.   /// \param Exprs Helper expressions for CodeGen.
  3441.   /// \param TaskRedRef Task reduction special reference expression to handle
  3442.   /// taskgroup descriptor.
  3443.   /// \param HasCancel true if current directive has inner cancel directive.
  3444.   ///
  3445.   static OMPTargetParallelForDirective *
  3446.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  3447.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  3448.          Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
  3449.          bool HasCancel);
  3450.  
  3451.   /// Creates an empty directive with the place
  3452.   /// for \a NumClauses clauses.
  3453.   ///
  3454.   /// \param C AST context.
  3455.   /// \param CollapsedNum Number of collapsed nested loops.
  3456.   /// \param NumClauses Number of clauses.
  3457.   ///
  3458.   static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C,
  3459.                                                     unsigned NumClauses,
  3460.                                                     unsigned CollapsedNum,
  3461.                                                     EmptyShell);
  3462.  
  3463.   /// Returns special task reduction reference expression.
  3464.   Expr *getTaskReductionRefExpr() {
  3465.     return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
  3466.         getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]);
  3467.   }
  3468.   const Expr *getTaskReductionRefExpr() const {
  3469.     return const_cast<OMPTargetParallelForDirective *>(this)
  3470.         ->getTaskReductionRefExpr();
  3471.   }
  3472.  
  3473.   /// Return true if current directive has inner cancel directive.
  3474.   bool hasCancel() const { return HasCancel; }
  3475.  
  3476.   static bool classof(const Stmt *T) {
  3477.     return T->getStmtClass() == OMPTargetParallelForDirectiveClass;
  3478.   }
  3479. };
  3480.  
  3481. /// This represents '#pragma omp teams' directive.
  3482. ///
  3483. /// \code
  3484. /// #pragma omp teams if(a)
  3485. /// \endcode
  3486. /// In this example directive '#pragma omp teams' has clause 'if' with
  3487. /// condition 'a'.
  3488. ///
  3489. class OMPTeamsDirective : public OMPExecutableDirective {
  3490.   friend class ASTStmtReader;
  3491.   friend class OMPExecutableDirective;
  3492.   /// Build directive with the given start and end location.
  3493.   ///
  3494.   /// \param StartLoc Starting location of the directive kind.
  3495.   /// \param EndLoc Ending location of the directive.
  3496.   ///
  3497.   OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  3498.       : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
  3499.                                StartLoc, EndLoc) {}
  3500.  
  3501.   /// Build an empty directive.
  3502.   ///
  3503.   explicit OMPTeamsDirective()
  3504.       : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
  3505.                                SourceLocation(), SourceLocation()) {}
  3506.  
  3507. public:
  3508.   /// Creates directive with a list of \a Clauses.
  3509.   ///
  3510.   /// \param C AST context.
  3511.   /// \param StartLoc Starting location of the directive kind.
  3512.   /// \param EndLoc Ending Location of the directive.
  3513.   /// \param Clauses List of clauses.
  3514.   /// \param AssociatedStmt Statement, associated with the directive.
  3515.   ///
  3516.   static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
  3517.                                    SourceLocation EndLoc,
  3518.                                    ArrayRef<OMPClause *> Clauses,
  3519.                                    Stmt *AssociatedStmt);
  3520.  
  3521.   /// Creates an empty directive with the place for \a NumClauses
  3522.   /// clauses.
  3523.   ///
  3524.   /// \param C AST context.
  3525.   /// \param NumClauses Number of clauses.
  3526.   ///
  3527.   static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
  3528.                                         unsigned NumClauses, EmptyShell);
  3529.  
  3530.   static bool classof(const Stmt *T) {
  3531.     return T->getStmtClass() == OMPTeamsDirectiveClass;
  3532.   }
  3533. };
  3534.  
  3535. /// This represents '#pragma omp cancellation point' directive.
  3536. ///
  3537. /// \code
  3538. /// #pragma omp cancellation point for
  3539. /// \endcode
  3540. ///
  3541. /// In this example a cancellation point is created for innermost 'for' region.
  3542. class OMPCancellationPointDirective : public OMPExecutableDirective {
  3543.   friend class ASTStmtReader;
  3544.   friend class OMPExecutableDirective;
  3545.   OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
  3546.   /// Build directive with the given start and end location.
  3547.   ///
  3548.   /// \param StartLoc Starting location of the directive kind.
  3549.   /// \param EndLoc Ending location of the directive.
  3550.   /// statements and child expressions.
  3551.   ///
  3552.   OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  3553.       : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
  3554.                                llvm::omp::OMPD_cancellation_point, StartLoc,
  3555.                                EndLoc) {}
  3556.  
  3557.   /// Build an empty directive.
  3558.   explicit OMPCancellationPointDirective()
  3559.       : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
  3560.                                llvm::omp::OMPD_cancellation_point,
  3561.                                SourceLocation(), SourceLocation()) {}
  3562.  
  3563.   /// Set cancel region for current cancellation point.
  3564.   /// \param CR Cancellation region.
  3565.   void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
  3566.  
  3567. public:
  3568.   /// Creates directive.
  3569.   ///
  3570.   /// \param C AST context.
  3571.   /// \param StartLoc Starting location of the directive kind.
  3572.   /// \param EndLoc Ending Location of the directive.
  3573.   ///
  3574.   static OMPCancellationPointDirective *
  3575.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  3576.          OpenMPDirectiveKind CancelRegion);
  3577.  
  3578.   /// Creates an empty directive.
  3579.   ///
  3580.   /// \param C AST context.
  3581.   ///
  3582.   static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
  3583.                                                     EmptyShell);
  3584.  
  3585.   /// Get cancellation region for the current cancellation point.
  3586.   OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
  3587.  
  3588.   static bool classof(const Stmt *T) {
  3589.     return T->getStmtClass() == OMPCancellationPointDirectiveClass;
  3590.   }
  3591. };
  3592.  
  3593. /// This represents '#pragma omp cancel' directive.
  3594. ///
  3595. /// \code
  3596. /// #pragma omp cancel for
  3597. /// \endcode
  3598. ///
  3599. /// In this example a cancel is created for innermost 'for' region.
  3600. class OMPCancelDirective : public OMPExecutableDirective {
  3601.   friend class ASTStmtReader;
  3602.   friend class OMPExecutableDirective;
  3603.   OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
  3604.   /// Build directive with the given start and end location.
  3605.   ///
  3606.   /// \param StartLoc Starting location of the directive kind.
  3607.   /// \param EndLoc Ending location of the directive.
  3608.   ///
  3609.   OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  3610.       : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
  3611.                                StartLoc, EndLoc) {}
  3612.  
  3613.   /// Build an empty directive.
  3614.   ///
  3615.   explicit OMPCancelDirective()
  3616.       : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
  3617.                                SourceLocation(), SourceLocation()) {}
  3618.  
  3619.   /// Set cancel region for current cancellation point.
  3620.   /// \param CR Cancellation region.
  3621.   void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
  3622.  
  3623. public:
  3624.   /// Creates directive.
  3625.   ///
  3626.   /// \param C AST context.
  3627.   /// \param StartLoc Starting location of the directive kind.
  3628.   /// \param EndLoc Ending Location of the directive.
  3629.   /// \param Clauses List of clauses.
  3630.   ///
  3631.   static OMPCancelDirective *
  3632.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  3633.          ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
  3634.  
  3635.   /// Creates an empty directive.
  3636.   ///
  3637.   /// \param C AST context.
  3638.   /// \param NumClauses Number of clauses.
  3639.   ///
  3640.   static OMPCancelDirective *CreateEmpty(const ASTContext &C,
  3641.                                          unsigned NumClauses, EmptyShell);
  3642.  
  3643.   /// Get cancellation region for the current cancellation point.
  3644.   OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
  3645.  
  3646.   static bool classof(const Stmt *T) {
  3647.     return T->getStmtClass() == OMPCancelDirectiveClass;
  3648.   }
  3649. };
  3650.  
  3651. /// This represents '#pragma omp taskloop' directive.
  3652. ///
  3653. /// \code
  3654. /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
  3655. /// \endcode
  3656. /// In this example directive '#pragma omp taskloop' has clauses 'private'
  3657. /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
  3658. /// 'num_tasks' with expression 'num'.
  3659. ///
  3660. class OMPTaskLoopDirective : public OMPLoopDirective {
  3661.   friend class ASTStmtReader;
  3662.   friend class OMPExecutableDirective;
  3663.   /// true if the construct has inner cancel directive.
  3664.   bool HasCancel = false;
  3665.  
  3666.   /// Build directive with the given start and end location.
  3667.   ///
  3668.   /// \param StartLoc Starting location of the directive kind.
  3669.   /// \param EndLoc Ending location of the directive.
  3670.   /// \param CollapsedNum Number of collapsed nested loops.
  3671.   ///
  3672.   OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
  3673.                        unsigned CollapsedNum)
  3674.       : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
  3675.                          StartLoc, EndLoc, CollapsedNum) {}
  3676.  
  3677.   /// Build an empty directive.
  3678.   ///
  3679.   /// \param CollapsedNum Number of collapsed nested loops.
  3680.   ///
  3681.   explicit OMPTaskLoopDirective(unsigned CollapsedNum)
  3682.       : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
  3683.                          SourceLocation(), SourceLocation(), CollapsedNum) {}
  3684.  
  3685.   /// Set cancel state.
  3686.   void setHasCancel(bool Has) { HasCancel = Has; }
  3687.  
  3688. public:
  3689.   /// Creates directive with a list of \a Clauses.
  3690.   ///
  3691.   /// \param C AST context.
  3692.   /// \param StartLoc Starting location of the directive kind.
  3693.   /// \param EndLoc Ending Location of the directive.
  3694.   /// \param CollapsedNum Number of collapsed loops.
  3695.   /// \param Clauses List of clauses.
  3696.   /// \param AssociatedStmt Statement, associated with the directive.
  3697.   /// \param Exprs Helper expressions for CodeGen.
  3698.   /// \param HasCancel true if this directive has inner cancel directive.
  3699.   ///
  3700.   static OMPTaskLoopDirective *
  3701.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  3702.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  3703.          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
  3704.  
  3705.   /// Creates an empty directive with the place
  3706.   /// for \a NumClauses clauses.
  3707.   ///
  3708.   /// \param C AST context.
  3709.   /// \param CollapsedNum Number of collapsed nested loops.
  3710.   /// \param NumClauses Number of clauses.
  3711.   ///
  3712.   static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
  3713.                                            unsigned NumClauses,
  3714.                                            unsigned CollapsedNum, EmptyShell);
  3715.  
  3716.   /// Return true if current directive has inner cancel directive.
  3717.   bool hasCancel() const { return HasCancel; }
  3718.  
  3719.   static bool classof(const Stmt *T) {
  3720.     return T->getStmtClass() == OMPTaskLoopDirectiveClass;
  3721.   }
  3722. };
  3723.  
  3724. /// This represents '#pragma omp taskloop simd' directive.
  3725. ///
  3726. /// \code
  3727. /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
  3728. /// \endcode
  3729. /// In this example directive '#pragma omp taskloop simd' has clauses 'private'
  3730. /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
  3731. /// 'num_tasks' with expression 'num'.
  3732. ///
  3733. class OMPTaskLoopSimdDirective : public OMPLoopDirective {
  3734.   friend class ASTStmtReader;
  3735.   friend class OMPExecutableDirective;
  3736.   /// Build directive with the given start and end location.
  3737.   ///
  3738.   /// \param StartLoc Starting location of the directive kind.
  3739.   /// \param EndLoc Ending location of the directive.
  3740.   /// \param CollapsedNum Number of collapsed nested loops.
  3741.   ///
  3742.   OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
  3743.                            unsigned CollapsedNum)
  3744.       : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
  3745.                          llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc,
  3746.                          CollapsedNum) {}
  3747.  
  3748.   /// Build an empty directive.
  3749.   ///
  3750.   /// \param CollapsedNum Number of collapsed nested loops.
  3751.   ///
  3752.   explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum)
  3753.       : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
  3754.                          llvm::omp::OMPD_taskloop_simd, SourceLocation(),
  3755.                          SourceLocation(), CollapsedNum) {}
  3756.  
  3757. public:
  3758.   /// Creates directive with a list of \a Clauses.
  3759.   ///
  3760.   /// \param C AST context.
  3761.   /// \param StartLoc Starting location of the directive kind.
  3762.   /// \param EndLoc Ending Location of the directive.
  3763.   /// \param CollapsedNum Number of collapsed loops.
  3764.   /// \param Clauses List of clauses.
  3765.   /// \param AssociatedStmt Statement, associated with the directive.
  3766.   /// \param Exprs Helper expressions for CodeGen.
  3767.   ///
  3768.   static OMPTaskLoopSimdDirective *
  3769.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  3770.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  3771.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  3772.  
  3773.   /// Creates an empty directive with the place
  3774.   /// for \a NumClauses clauses.
  3775.   ///
  3776.   /// \param C AST context.
  3777.   /// \param CollapsedNum Number of collapsed nested loops.
  3778.   /// \param NumClauses Number of clauses.
  3779.   ///
  3780.   static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
  3781.                                                unsigned NumClauses,
  3782.                                                unsigned CollapsedNum,
  3783.                                                EmptyShell);
  3784.  
  3785.   static bool classof(const Stmt *T) {
  3786.     return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
  3787.   }
  3788. };
  3789.  
  3790. /// This represents '#pragma omp master taskloop' directive.
  3791. ///
  3792. /// \code
  3793. /// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num)
  3794. /// \endcode
  3795. /// In this example directive '#pragma omp master taskloop' has clauses
  3796. /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
  3797. /// and 'num_tasks' with expression 'num'.
  3798. ///
  3799. class OMPMasterTaskLoopDirective : public OMPLoopDirective {
  3800.   friend class ASTStmtReader;
  3801.   friend class OMPExecutableDirective;
  3802.   /// true if the construct has inner cancel directive.
  3803.   bool HasCancel = false;
  3804.  
  3805.   /// Build directive with the given start and end location.
  3806.   ///
  3807.   /// \param StartLoc Starting location of the directive kind.
  3808.   /// \param EndLoc Ending location of the directive.
  3809.   /// \param CollapsedNum Number of collapsed nested loops.
  3810.   ///
  3811.   OMPMasterTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
  3812.                              unsigned CollapsedNum)
  3813.       : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
  3814.                          llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc,
  3815.                          CollapsedNum) {}
  3816.  
  3817.   /// Build an empty directive.
  3818.   ///
  3819.   /// \param CollapsedNum Number of collapsed nested loops.
  3820.   ///
  3821.   explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum)
  3822.       : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
  3823.                          llvm::omp::OMPD_master_taskloop, SourceLocation(),
  3824.                          SourceLocation(), CollapsedNum) {}
  3825.  
  3826.   /// Set cancel state.
  3827.   void setHasCancel(bool Has) { HasCancel = Has; }
  3828.  
  3829. public:
  3830.   /// Creates directive with a list of \a Clauses.
  3831.   ///
  3832.   /// \param C AST context.
  3833.   /// \param StartLoc Starting location of the directive kind.
  3834.   /// \param EndLoc Ending Location of the directive.
  3835.   /// \param CollapsedNum Number of collapsed loops.
  3836.   /// \param Clauses List of clauses.
  3837.   /// \param AssociatedStmt Statement, associated with the directive.
  3838.   /// \param Exprs Helper expressions for CodeGen.
  3839.   /// \param HasCancel true if this directive has inner cancel directive.
  3840.   ///
  3841.   static OMPMasterTaskLoopDirective *
  3842.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  3843.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  3844.          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
  3845.  
  3846.   /// Creates an empty directive with the place
  3847.   /// for \a NumClauses clauses.
  3848.   ///
  3849.   /// \param C AST context.
  3850.   /// \param CollapsedNum Number of collapsed nested loops.
  3851.   /// \param NumClauses Number of clauses.
  3852.   ///
  3853.   static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
  3854.                                                  unsigned NumClauses,
  3855.                                                  unsigned CollapsedNum,
  3856.                                                  EmptyShell);
  3857.  
  3858.   /// Return true if current directive has inner cancel directive.
  3859.   bool hasCancel() const { return HasCancel; }
  3860.  
  3861.   static bool classof(const Stmt *T) {
  3862.     return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass;
  3863.   }
  3864. };
  3865.  
  3866. /// This represents '#pragma omp masked taskloop' directive.
  3867. ///
  3868. /// \code
  3869. /// #pragma omp masked taskloop private(a,b) grainsize(val) num_tasks(num)
  3870. /// \endcode
  3871. /// In this example directive '#pragma omp masked taskloop' has clauses
  3872. /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
  3873. /// and 'num_tasks' with expression 'num'.
  3874. ///
  3875. class OMPMaskedTaskLoopDirective final : public OMPLoopDirective {
  3876.   friend class ASTStmtReader;
  3877.   friend class OMPExecutableDirective;
  3878.   /// true if the construct has inner cancel directive.
  3879.   bool HasCancel = false;
  3880.  
  3881.   /// Build directive with the given start and end location.
  3882.   ///
  3883.   /// \param StartLoc Starting location of the directive kind.
  3884.   /// \param EndLoc Ending location of the directive.
  3885.   /// \param CollapsedNum Number of collapsed nested loops.
  3886.   ///
  3887.   OMPMaskedTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
  3888.                              unsigned CollapsedNum)
  3889.       : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
  3890.                          llvm::omp::OMPD_masked_taskloop, StartLoc, EndLoc,
  3891.                          CollapsedNum) {}
  3892.  
  3893.   /// Build an empty directive.
  3894.   ///
  3895.   /// \param CollapsedNum Number of collapsed nested loops.
  3896.   ///
  3897.   explicit OMPMaskedTaskLoopDirective(unsigned CollapsedNum)
  3898.       : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
  3899.                          llvm::omp::OMPD_masked_taskloop, SourceLocation(),
  3900.                          SourceLocation(), CollapsedNum) {}
  3901.  
  3902.   /// Set cancel state.
  3903.   void setHasCancel(bool Has) { HasCancel = Has; }
  3904.  
  3905. public:
  3906.   /// Creates directive with a list of \a Clauses.
  3907.   ///
  3908.   /// \param C AST context.
  3909.   /// \param StartLoc Starting location of the directive kind.
  3910.   /// \param EndLoc Ending Location of the directive.
  3911.   /// \param CollapsedNum Number of collapsed loops.
  3912.   /// \param Clauses List of clauses.
  3913.   /// \param AssociatedStmt Statement, associated with the directive.
  3914.   /// \param Exprs Helper expressions for CodeGen.
  3915.   /// \param HasCancel true if this directive has inner cancel directive.
  3916.   ///
  3917.   static OMPMaskedTaskLoopDirective *
  3918.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  3919.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  3920.          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
  3921.  
  3922.   /// Creates an empty directive with the place
  3923.   /// for \a NumClauses clauses.
  3924.   ///
  3925.   /// \param C AST context.
  3926.   /// \param CollapsedNum Number of collapsed nested loops.
  3927.   /// \param NumClauses Number of clauses.
  3928.   ///
  3929.   static OMPMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
  3930.                                                  unsigned NumClauses,
  3931.                                                  unsigned CollapsedNum,
  3932.                                                  EmptyShell);
  3933.  
  3934.   /// Return true if current directive has inner cancel directive.
  3935.   bool hasCancel() const { return HasCancel; }
  3936.  
  3937.   static bool classof(const Stmt *T) {
  3938.     return T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass;
  3939.   }
  3940. };
  3941.  
  3942. /// This represents '#pragma omp master taskloop simd' directive.
  3943. ///
  3944. /// \code
  3945. /// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num)
  3946. /// \endcode
  3947. /// In this example directive '#pragma omp master taskloop simd' has clauses
  3948. /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
  3949. /// and 'num_tasks' with expression 'num'.
  3950. ///
  3951. class OMPMasterTaskLoopSimdDirective : public OMPLoopDirective {
  3952.   friend class ASTStmtReader;
  3953.   friend class OMPExecutableDirective;
  3954.   /// Build directive with the given start and end location.
  3955.   ///
  3956.   /// \param StartLoc Starting location of the directive kind.
  3957.   /// \param EndLoc Ending location of the directive.
  3958.   /// \param CollapsedNum Number of collapsed nested loops.
  3959.   ///
  3960.   OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
  3961.                                  unsigned CollapsedNum)
  3962.       : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
  3963.                          llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc,
  3964.                          CollapsedNum) {}
  3965.  
  3966.   /// Build an empty directive.
  3967.   ///
  3968.   /// \param CollapsedNum Number of collapsed nested loops.
  3969.   ///
  3970.   explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum)
  3971.       : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
  3972.                          llvm::omp::OMPD_master_taskloop_simd, SourceLocation(),
  3973.                          SourceLocation(), CollapsedNum) {}
  3974.  
  3975. public:
  3976.   /// Creates directive with a list of \p Clauses.
  3977.   ///
  3978.   /// \param C AST context.
  3979.   /// \param StartLoc Starting location of the directive kind.
  3980.   /// \param EndLoc Ending Location of the directive.
  3981.   /// \param CollapsedNum Number of collapsed loops.
  3982.   /// \param Clauses List of clauses.
  3983.   /// \param AssociatedStmt Statement, associated with the directive.
  3984.   /// \param Exprs Helper expressions for CodeGen.
  3985.   ///
  3986.   static OMPMasterTaskLoopSimdDirective *
  3987.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  3988.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  3989.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  3990.  
  3991.   /// Creates an empty directive with the place for \p NumClauses clauses.
  3992.   ///
  3993.   /// \param C AST context.
  3994.   /// \param CollapsedNum Number of collapsed nested loops.
  3995.   /// \param NumClauses Number of clauses.
  3996.   ///
  3997.   static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
  3998.                                                      unsigned NumClauses,
  3999.                                                      unsigned CollapsedNum,
  4000.                                                      EmptyShell);
  4001.  
  4002.   static bool classof(const Stmt *T) {
  4003.     return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass;
  4004.   }
  4005. };
  4006.  
  4007. /// This represents '#pragma omp masked taskloop simd' directive.
  4008. ///
  4009. /// \code
  4010. /// #pragma omp masked taskloop simd private(a,b) grainsize(val) num_tasks(num)
  4011. /// \endcode
  4012. /// In this example directive '#pragma omp masked taskloop simd' has clauses
  4013. /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
  4014. /// and 'num_tasks' with expression 'num'.
  4015. ///
  4016. class OMPMaskedTaskLoopSimdDirective final : public OMPLoopDirective {
  4017.   friend class ASTStmtReader;
  4018.   friend class OMPExecutableDirective;
  4019.   /// Build directive with the given start and end location.
  4020.   ///
  4021.   /// \param StartLoc Starting location of the directive kind.
  4022.   /// \param EndLoc Ending location of the directive.
  4023.   /// \param CollapsedNum Number of collapsed nested loops.
  4024.   ///
  4025.   OMPMaskedTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
  4026.                                  unsigned CollapsedNum)
  4027.       : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
  4028.                          llvm::omp::OMPD_masked_taskloop_simd, StartLoc, EndLoc,
  4029.                          CollapsedNum) {}
  4030.  
  4031.   /// Build an empty directive.
  4032.   ///
  4033.   /// \param CollapsedNum Number of collapsed nested loops.
  4034.   ///
  4035.   explicit OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
  4036.       : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
  4037.                          llvm::omp::OMPD_masked_taskloop_simd, SourceLocation(),
  4038.                          SourceLocation(), CollapsedNum) {}
  4039.  
  4040. public:
  4041.   /// Creates directive with a list of \p Clauses.
  4042.   ///
  4043.   /// \param C AST context.
  4044.   /// \param StartLoc Starting location of the directive kind.
  4045.   /// \param EndLoc Ending Location of the directive.
  4046.   /// \param CollapsedNum Number of collapsed loops.
  4047.   /// \param Clauses List of clauses.
  4048.   /// \param AssociatedStmt Statement, associated with the directive.
  4049.   /// \param Exprs Helper expressions for CodeGen.
  4050.   ///
  4051.   static OMPMaskedTaskLoopSimdDirective *
  4052.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  4053.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  4054.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  4055.  
  4056.   /// Creates an empty directive with the place for \p NumClauses clauses.
  4057.   ///
  4058.   /// \param C AST context.
  4059.   /// \param CollapsedNum Number of collapsed nested loops.
  4060.   /// \param NumClauses Number of clauses.
  4061.   ///
  4062.   static OMPMaskedTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
  4063.                                                      unsigned NumClauses,
  4064.                                                      unsigned CollapsedNum,
  4065.                                                      EmptyShell);
  4066.  
  4067.   static bool classof(const Stmt *T) {
  4068.     return T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass;
  4069.   }
  4070. };
  4071.  
  4072. /// This represents '#pragma omp parallel master taskloop' directive.
  4073. ///
  4074. /// \code
  4075. /// #pragma omp parallel master taskloop private(a,b) grainsize(val)
  4076. /// num_tasks(num)
  4077. /// \endcode
  4078. /// In this example directive '#pragma omp parallel master taskloop' has clauses
  4079. /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
  4080. /// and 'num_tasks' with expression 'num'.
  4081. ///
  4082. class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective {
  4083.   friend class ASTStmtReader;
  4084.   friend class OMPExecutableDirective;
  4085.   /// true if the construct has inner cancel directive.
  4086.   bool HasCancel = false;
  4087.  
  4088.   /// Build directive with the given start and end location.
  4089.   ///
  4090.   /// \param StartLoc Starting location of the directive kind.
  4091.   /// \param EndLoc Ending location of the directive.
  4092.   /// \param CollapsedNum Number of collapsed nested loops.
  4093.   ///
  4094.   OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc,
  4095.                                      SourceLocation EndLoc,
  4096.                                      unsigned CollapsedNum)
  4097.       : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
  4098.                          llvm::omp::OMPD_parallel_master_taskloop, StartLoc,
  4099.                          EndLoc, CollapsedNum) {}
  4100.  
  4101.   /// Build an empty directive.
  4102.   ///
  4103.   /// \param CollapsedNum Number of collapsed nested loops.
  4104.   ///
  4105.   explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum)
  4106.       : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
  4107.                          llvm::omp::OMPD_parallel_master_taskloop,
  4108.                          SourceLocation(), SourceLocation(), CollapsedNum) {}
  4109.  
  4110.   /// Set cancel state.
  4111.   void setHasCancel(bool Has) { HasCancel = Has; }
  4112.  
  4113. public:
  4114.   /// Creates directive with a list of \a Clauses.
  4115.   ///
  4116.   /// \param C AST context.
  4117.   /// \param StartLoc Starting location of the directive kind.
  4118.   /// \param EndLoc Ending Location of the directive.
  4119.   /// \param CollapsedNum Number of collapsed loops.
  4120.   /// \param Clauses List of clauses.
  4121.   /// \param AssociatedStmt Statement, associated with the directive.
  4122.   /// \param Exprs Helper expressions for CodeGen.
  4123.   /// \param HasCancel true if this directive has inner cancel directive.
  4124.   ///
  4125.   static OMPParallelMasterTaskLoopDirective *
  4126.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  4127.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  4128.          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
  4129.  
  4130.   /// Creates an empty directive with the place
  4131.   /// for \a NumClauses clauses.
  4132.   ///
  4133.   /// \param C AST context.
  4134.   /// \param CollapsedNum Number of collapsed nested loops.
  4135.   /// \param NumClauses Number of clauses.
  4136.   ///
  4137.   static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
  4138.                                                          unsigned NumClauses,
  4139.                                                          unsigned CollapsedNum,
  4140.                                                          EmptyShell);
  4141.  
  4142.   /// Return true if current directive has inner cancel directive.
  4143.   bool hasCancel() const { return HasCancel; }
  4144.  
  4145.   static bool classof(const Stmt *T) {
  4146.     return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass;
  4147.   }
  4148. };
  4149.  
  4150. /// This represents '#pragma omp parallel masked taskloop' directive.
  4151. ///
  4152. /// \code
  4153. /// #pragma omp parallel masked taskloop private(a,b) grainsize(val)
  4154. /// num_tasks(num)
  4155. /// \endcode
  4156. /// In this example directive '#pragma omp parallel masked taskloop' has clauses
  4157. /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
  4158. /// and 'num_tasks' with expression 'num'.
  4159. ///
  4160. class OMPParallelMaskedTaskLoopDirective final : public OMPLoopDirective {
  4161.   friend class ASTStmtReader;
  4162.   friend class OMPExecutableDirective;
  4163.   /// true if the construct has inner cancel directive.
  4164.   bool HasCancel = false;
  4165.  
  4166.   /// Build directive with the given start and end location.
  4167.   ///
  4168.   /// \param StartLoc Starting location of the directive kind.
  4169.   /// \param EndLoc Ending location of the directive.
  4170.   /// \param CollapsedNum Number of collapsed nested loops.
  4171.   ///
  4172.   OMPParallelMaskedTaskLoopDirective(SourceLocation StartLoc,
  4173.                                      SourceLocation EndLoc,
  4174.                                      unsigned CollapsedNum)
  4175.       : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
  4176.                          llvm::omp::OMPD_parallel_masked_taskloop, StartLoc,
  4177.                          EndLoc, CollapsedNum) {}
  4178.  
  4179.   /// Build an empty directive.
  4180.   ///
  4181.   /// \param CollapsedNum Number of collapsed nested loops.
  4182.   ///
  4183.   explicit OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum)
  4184.       : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
  4185.                          llvm::omp::OMPD_parallel_masked_taskloop,
  4186.                          SourceLocation(), SourceLocation(), CollapsedNum) {}
  4187.  
  4188.   /// Set cancel state.
  4189.   void setHasCancel(bool Has) { HasCancel = Has; }
  4190.  
  4191. public:
  4192.   /// Creates directive with a list of \a Clauses.
  4193.   ///
  4194.   /// \param C AST context.
  4195.   /// \param StartLoc Starting location of the directive kind.
  4196.   /// \param EndLoc Ending Location of the directive.
  4197.   /// \param CollapsedNum Number of collapsed loops.
  4198.   /// \param Clauses List of clauses.
  4199.   /// \param AssociatedStmt Statement, associated with the directive.
  4200.   /// \param Exprs Helper expressions for CodeGen.
  4201.   /// \param HasCancel true if this directive has inner cancel directive.
  4202.   ///
  4203.   static OMPParallelMaskedTaskLoopDirective *
  4204.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  4205.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  4206.          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
  4207.  
  4208.   /// Creates an empty directive with the place
  4209.   /// for \a NumClauses clauses.
  4210.   ///
  4211.   /// \param C AST context.
  4212.   /// \param CollapsedNum Number of collapsed nested loops.
  4213.   /// \param NumClauses Number of clauses.
  4214.   ///
  4215.   static OMPParallelMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
  4216.                                                          unsigned NumClauses,
  4217.                                                          unsigned CollapsedNum,
  4218.                                                          EmptyShell);
  4219.  
  4220.   /// Return true if current directive has inner cancel directive.
  4221.   bool hasCancel() const { return HasCancel; }
  4222.  
  4223.   static bool classof(const Stmt *T) {
  4224.     return T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass;
  4225.   }
  4226. };
  4227.  
  4228. /// This represents '#pragma omp parallel master taskloop simd' directive.
  4229. ///
  4230. /// \code
  4231. /// #pragma omp parallel master taskloop simd private(a,b) grainsize(val)
  4232. /// num_tasks(num)
  4233. /// \endcode
  4234. /// In this example directive '#pragma omp parallel master taskloop simd' has
  4235. /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
  4236. /// expression 'val' and 'num_tasks' with expression 'num'.
  4237. ///
  4238. class OMPParallelMasterTaskLoopSimdDirective : public OMPLoopDirective {
  4239.   friend class ASTStmtReader;
  4240.   friend class OMPExecutableDirective;
  4241.   /// Build directive with the given start and end location.
  4242.   ///
  4243.   /// \param StartLoc Starting location of the directive kind.
  4244.   /// \param EndLoc Ending location of the directive.
  4245.   /// \param CollapsedNum Number of collapsed nested loops.
  4246.   ///
  4247.   OMPParallelMasterTaskLoopSimdDirective(SourceLocation StartLoc,
  4248.                                          SourceLocation EndLoc,
  4249.                                          unsigned CollapsedNum)
  4250.       : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
  4251.                          llvm::omp::OMPD_parallel_master_taskloop_simd,
  4252.                          StartLoc, EndLoc, CollapsedNum) {}
  4253.  
  4254.   /// Build an empty directive.
  4255.   ///
  4256.   /// \param CollapsedNum Number of collapsed nested loops.
  4257.   ///
  4258.   explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum)
  4259.       : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
  4260.                          llvm::omp::OMPD_parallel_master_taskloop_simd,
  4261.                          SourceLocation(), SourceLocation(), CollapsedNum) {}
  4262.  
  4263. public:
  4264.   /// Creates directive with a list of \p Clauses.
  4265.   ///
  4266.   /// \param C AST context.
  4267.   /// \param StartLoc Starting location of the directive kind.
  4268.   /// \param EndLoc Ending Location of the directive.
  4269.   /// \param CollapsedNum Number of collapsed loops.
  4270.   /// \param Clauses List of clauses.
  4271.   /// \param AssociatedStmt Statement, associated with the directive.
  4272.   /// \param Exprs Helper expressions for CodeGen.
  4273.   ///
  4274.   static OMPParallelMasterTaskLoopSimdDirective *
  4275.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  4276.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  4277.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  4278.  
  4279.   /// Creates an empty directive with the place
  4280.   /// for \a NumClauses clauses.
  4281.   ///
  4282.   /// \param C AST context.
  4283.   /// \param CollapsedNum Number of collapsed nested loops.
  4284.   /// \param NumClauses Number of clauses.
  4285.   ///
  4286.   static OMPParallelMasterTaskLoopSimdDirective *
  4287.   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
  4288.               EmptyShell);
  4289.  
  4290.   static bool classof(const Stmt *T) {
  4291.     return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass;
  4292.   }
  4293. };
  4294.  
  4295. /// This represents '#pragma omp parallel masked taskloop simd' directive.
  4296. ///
  4297. /// \code
  4298. /// #pragma omp parallel masked taskloop simd private(a,b) grainsize(val)
  4299. /// num_tasks(num)
  4300. /// \endcode
  4301. /// In this example directive '#pragma omp parallel masked taskloop simd' has
  4302. /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
  4303. /// expression 'val' and 'num_tasks' with expression 'num'.
  4304. ///
  4305. class OMPParallelMaskedTaskLoopSimdDirective final : public OMPLoopDirective {
  4306.   friend class ASTStmtReader;
  4307.   friend class OMPExecutableDirective;
  4308.   /// Build directive with the given start and end location.
  4309.   ///
  4310.   /// \param StartLoc Starting location of the directive kind.
  4311.   /// \param EndLoc Ending location of the directive.
  4312.   /// \param CollapsedNum Number of collapsed nested loops.
  4313.   ///
  4314.   OMPParallelMaskedTaskLoopSimdDirective(SourceLocation StartLoc,
  4315.                                          SourceLocation EndLoc,
  4316.                                          unsigned CollapsedNum)
  4317.       : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
  4318.                          llvm::omp::OMPD_parallel_masked_taskloop_simd,
  4319.                          StartLoc, EndLoc, CollapsedNum) {}
  4320.  
  4321.   /// Build an empty directive.
  4322.   ///
  4323.   /// \param CollapsedNum Number of collapsed nested loops.
  4324.   ///
  4325.   explicit OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
  4326.       : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
  4327.                          llvm::omp::OMPD_parallel_masked_taskloop_simd,
  4328.                          SourceLocation(), SourceLocation(), CollapsedNum) {}
  4329.  
  4330. public:
  4331.   /// Creates directive with a list of \p Clauses.
  4332.   ///
  4333.   /// \param C AST context.
  4334.   /// \param StartLoc Starting location of the directive kind.
  4335.   /// \param EndLoc Ending Location of the directive.
  4336.   /// \param CollapsedNum Number of collapsed loops.
  4337.   /// \param Clauses List of clauses.
  4338.   /// \param AssociatedStmt Statement, associated with the directive.
  4339.   /// \param Exprs Helper expressions for CodeGen.
  4340.   ///
  4341.   static OMPParallelMaskedTaskLoopSimdDirective *
  4342.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  4343.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  4344.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  4345.  
  4346.   /// Creates an empty directive with the place
  4347.   /// for \a NumClauses clauses.
  4348.   ///
  4349.   /// \param C AST context.
  4350.   /// \param CollapsedNum Number of collapsed nested loops.
  4351.   /// \param NumClauses Number of clauses.
  4352.   ///
  4353.   static OMPParallelMaskedTaskLoopSimdDirective *
  4354.   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
  4355.               EmptyShell);
  4356.  
  4357.   static bool classof(const Stmt *T) {
  4358.     return T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass;
  4359.   }
  4360. };
  4361.  
  4362. /// This represents '#pragma omp distribute' directive.
  4363. ///
  4364. /// \code
  4365. /// #pragma omp distribute private(a,b)
  4366. /// \endcode
  4367. /// In this example directive '#pragma omp distribute' has clauses 'private'
  4368. /// with the variables 'a' and 'b'
  4369. ///
  4370. class OMPDistributeDirective : public OMPLoopDirective {
  4371.   friend class ASTStmtReader;
  4372.   friend class OMPExecutableDirective;
  4373.  
  4374.   /// Build directive with the given start and end location.
  4375.   ///
  4376.   /// \param StartLoc Starting location of the directive kind.
  4377.   /// \param EndLoc Ending location of the directive.
  4378.   /// \param CollapsedNum Number of collapsed nested loops.
  4379.   ///
  4380.   OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
  4381.                          unsigned CollapsedNum)
  4382.       : OMPLoopDirective(OMPDistributeDirectiveClass,
  4383.                          llvm::omp::OMPD_distribute, StartLoc, EndLoc,
  4384.                          CollapsedNum) {}
  4385.  
  4386.   /// Build an empty directive.
  4387.   ///
  4388.   /// \param CollapsedNum Number of collapsed nested loops.
  4389.   ///
  4390.   explicit OMPDistributeDirective(unsigned CollapsedNum)
  4391.       : OMPLoopDirective(OMPDistributeDirectiveClass,
  4392.                          llvm::omp::OMPD_distribute, SourceLocation(),
  4393.                          SourceLocation(), CollapsedNum) {}
  4394.  
  4395. public:
  4396.   /// Creates directive with a list of \a Clauses.
  4397.   ///
  4398.   /// \param C AST context.
  4399.   /// \param StartLoc Starting location of the directive kind.
  4400.   /// \param EndLoc Ending Location of the directive.
  4401.   /// \param CollapsedNum Number of collapsed loops.
  4402.   /// \param Clauses List of clauses.
  4403.   /// \param AssociatedStmt Statement, associated with the directive.
  4404.   /// \param Exprs Helper expressions for CodeGen.
  4405.   ///
  4406.   static OMPDistributeDirective *
  4407.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  4408.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  4409.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  4410.  
  4411.   /// Creates an empty directive with the place
  4412.   /// for \a NumClauses clauses.
  4413.   ///
  4414.   /// \param C AST context.
  4415.   /// \param CollapsedNum Number of collapsed nested loops.
  4416.   /// \param NumClauses Number of clauses.
  4417.   ///
  4418.   static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
  4419.                                              unsigned NumClauses,
  4420.                                              unsigned CollapsedNum, EmptyShell);
  4421.  
  4422.   static bool classof(const Stmt *T) {
  4423.     return T->getStmtClass() == OMPDistributeDirectiveClass;
  4424.   }
  4425. };
  4426.  
  4427. /// This represents '#pragma omp target update' directive.
  4428. ///
  4429. /// \code
  4430. /// #pragma omp target update to(a) from(b) device(1)
  4431. /// \endcode
  4432. /// In this example directive '#pragma omp target update' has clause 'to' with
  4433. /// argument 'a', clause 'from' with argument 'b' and clause 'device' with
  4434. /// argument '1'.
  4435. ///
  4436. class OMPTargetUpdateDirective : public OMPExecutableDirective {
  4437.   friend class ASTStmtReader;
  4438.   friend class OMPExecutableDirective;
  4439.   /// Build directive with the given start and end location.
  4440.   ///
  4441.   /// \param StartLoc Starting location of the directive kind.
  4442.   /// \param EndLoc Ending Location of the directive.
  4443.   ///
  4444.   OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  4445.       : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
  4446.                                llvm::omp::OMPD_target_update, StartLoc,
  4447.                                EndLoc) {}
  4448.  
  4449.   /// Build an empty directive.
  4450.   ///
  4451.   explicit OMPTargetUpdateDirective()
  4452.       : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
  4453.                                llvm::omp::OMPD_target_update, SourceLocation(),
  4454.                                SourceLocation()) {}
  4455.  
  4456. public:
  4457.   /// Creates directive with a list of \a Clauses.
  4458.   ///
  4459.   /// \param C AST context.
  4460.   /// \param StartLoc Starting location of the directive kind.
  4461.   /// \param EndLoc Ending Location of the directive.
  4462.   /// \param Clauses List of clauses.
  4463.   /// \param AssociatedStmt Statement, associated with the directive.
  4464.   ///
  4465.   static OMPTargetUpdateDirective *
  4466.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  4467.          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
  4468.  
  4469.   /// Creates an empty directive with the place for \a NumClauses
  4470.   /// clauses.
  4471.   ///
  4472.   /// \param C AST context.
  4473.   /// \param NumClauses The number of clauses.
  4474.   ///
  4475.   static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C,
  4476.                                                unsigned NumClauses, EmptyShell);
  4477.  
  4478.   static bool classof(const Stmt *T) {
  4479.     return T->getStmtClass() == OMPTargetUpdateDirectiveClass;
  4480.   }
  4481. };
  4482.  
  4483. /// This represents '#pragma omp distribute parallel for' composite
  4484. ///  directive.
  4485. ///
  4486. /// \code
  4487. /// #pragma omp distribute parallel for private(a,b)
  4488. /// \endcode
  4489. /// In this example directive '#pragma omp distribute parallel for' has clause
  4490. /// 'private' with the variables 'a' and 'b'
  4491. ///
  4492. class OMPDistributeParallelForDirective : public OMPLoopDirective {
  4493.   friend class ASTStmtReader;
  4494.   friend class OMPExecutableDirective;
  4495.   /// true if the construct has inner cancel directive.
  4496.   bool HasCancel = false;
  4497.  
  4498.   /// Build directive with the given start and end location.
  4499.   ///
  4500.   /// \param StartLoc Starting location of the directive kind.
  4501.   /// \param EndLoc Ending location of the directive.
  4502.   /// \param CollapsedNum Number of collapsed nested loops.
  4503.   ///
  4504.   OMPDistributeParallelForDirective(SourceLocation StartLoc,
  4505.                                     SourceLocation EndLoc,
  4506.                                     unsigned CollapsedNum)
  4507.       : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
  4508.                          llvm::omp::OMPD_distribute_parallel_for, StartLoc,
  4509.                          EndLoc, CollapsedNum) {}
  4510.  
  4511.   /// Build an empty directive.
  4512.   ///
  4513.   /// \param CollapsedNum Number of collapsed nested loops.
  4514.   ///
  4515.   explicit OMPDistributeParallelForDirective(unsigned CollapsedNum)
  4516.       : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
  4517.                          llvm::omp::OMPD_distribute_parallel_for,
  4518.                          SourceLocation(), SourceLocation(), CollapsedNum) {}
  4519.  
  4520.   /// Sets special task reduction descriptor.
  4521.   void setTaskReductionRefExpr(Expr *E) {
  4522.     Data->getChildren()[numLoopChildren(
  4523.         getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E;
  4524.   }
  4525.  
  4526.   /// Set cancel state.
  4527.   void setHasCancel(bool Has) { HasCancel = Has; }
  4528.  
  4529. public:
  4530.   /// Creates directive with a list of \a Clauses.
  4531.   ///
  4532.   /// \param C AST context.
  4533.   /// \param StartLoc Starting location of the directive kind.
  4534.   /// \param EndLoc Ending Location of the directive.
  4535.   /// \param CollapsedNum Number of collapsed loops.
  4536.   /// \param Clauses List of clauses.
  4537.   /// \param AssociatedStmt Statement, associated with the directive.
  4538.   /// \param Exprs Helper expressions for CodeGen.
  4539.   /// \param TaskRedRef Task reduction special reference expression to handle
  4540.   /// taskgroup descriptor.
  4541.   /// \param HasCancel true if this directive has inner cancel directive.
  4542.   ///
  4543.   static OMPDistributeParallelForDirective *
  4544.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  4545.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  4546.          Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
  4547.          bool HasCancel);
  4548.  
  4549.   /// Creates an empty directive with the place
  4550.   /// for \a NumClauses clauses.
  4551.   ///
  4552.   /// \param C AST context.
  4553.   /// \param CollapsedNum Number of collapsed nested loops.
  4554.   /// \param NumClauses Number of clauses.
  4555.   ///
  4556.   static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C,
  4557.                                                         unsigned NumClauses,
  4558.                                                         unsigned CollapsedNum,
  4559.                                                         EmptyShell);
  4560.  
  4561.   /// Returns special task reduction reference expression.
  4562.   Expr *getTaskReductionRefExpr() {
  4563.     return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
  4564.         getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]);
  4565.   }
  4566.   const Expr *getTaskReductionRefExpr() const {
  4567.     return const_cast<OMPDistributeParallelForDirective *>(this)
  4568.         ->getTaskReductionRefExpr();
  4569.   }
  4570.  
  4571.   /// Return true if current directive has inner cancel directive.
  4572.   bool hasCancel() const { return HasCancel; }
  4573.  
  4574.   static bool classof(const Stmt *T) {
  4575.     return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
  4576.   }
  4577. };
  4578.  
  4579. /// This represents '#pragma omp distribute parallel for simd' composite
  4580. /// directive.
  4581. ///
  4582. /// \code
  4583. /// #pragma omp distribute parallel for simd private(x)
  4584. /// \endcode
  4585. /// In this example directive '#pragma omp distribute parallel for simd' has
  4586. /// clause 'private' with the variables 'x'
  4587. ///
  4588. class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective {
  4589.   friend class ASTStmtReader;
  4590.   friend class OMPExecutableDirective;
  4591.  
  4592.   /// Build directive with the given start and end location.
  4593.   ///
  4594.   /// \param StartLoc Starting location of the directive kind.
  4595.   /// \param EndLoc Ending location of the directive.
  4596.   /// \param CollapsedNum Number of collapsed nested loops.
  4597.   ///
  4598.   OMPDistributeParallelForSimdDirective(SourceLocation StartLoc,
  4599.                                         SourceLocation EndLoc,
  4600.                                         unsigned CollapsedNum)
  4601.       : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
  4602.                          llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc,
  4603.                          EndLoc, CollapsedNum) {}
  4604.  
  4605.   /// Build an empty directive.
  4606.   ///
  4607.   /// \param CollapsedNum Number of collapsed nested loops.
  4608.   ///
  4609.   explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum)
  4610.       : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
  4611.                          llvm::omp::OMPD_distribute_parallel_for_simd,
  4612.                          SourceLocation(), SourceLocation(), CollapsedNum) {}
  4613.  
  4614. public:
  4615.   /// Creates directive with a list of \a Clauses.
  4616.   ///
  4617.   /// \param C AST context.
  4618.   /// \param StartLoc Starting location of the directive kind.
  4619.   /// \param EndLoc Ending Location of the directive.
  4620.   /// \param CollapsedNum Number of collapsed loops.
  4621.   /// \param Clauses List of clauses.
  4622.   /// \param AssociatedStmt Statement, associated with the directive.
  4623.   /// \param Exprs Helper expressions for CodeGen.
  4624.   ///
  4625.   static OMPDistributeParallelForSimdDirective *Create(
  4626.       const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  4627.       unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  4628.       Stmt *AssociatedStmt, const HelperExprs &Exprs);
  4629.  
  4630.   /// Creates an empty directive with the place for \a NumClauses clauses.
  4631.   ///
  4632.   /// \param C AST context.
  4633.   /// \param CollapsedNum Number of collapsed nested loops.
  4634.   /// \param NumClauses Number of clauses.
  4635.   ///
  4636.   static OMPDistributeParallelForSimdDirective *CreateEmpty(
  4637.       const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
  4638.       EmptyShell);
  4639.  
  4640.   static bool classof(const Stmt *T) {
  4641.     return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass;
  4642.   }
  4643. };
  4644.  
  4645. /// This represents '#pragma omp distribute simd' composite directive.
  4646. ///
  4647. /// \code
  4648. /// #pragma omp distribute simd private(x)
  4649. /// \endcode
  4650. /// In this example directive '#pragma omp distribute simd' has clause
  4651. /// 'private' with the variables 'x'
  4652. ///
  4653. class OMPDistributeSimdDirective final : public OMPLoopDirective {
  4654.   friend class ASTStmtReader;
  4655.   friend class OMPExecutableDirective;
  4656.  
  4657.   /// Build directive with the given start and end location.
  4658.   ///
  4659.   /// \param StartLoc Starting location of the directive kind.
  4660.   /// \param EndLoc Ending location of the directive.
  4661.   /// \param CollapsedNum Number of collapsed nested loops.
  4662.   ///
  4663.   OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
  4664.                              unsigned CollapsedNum)
  4665.       : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
  4666.                          llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc,
  4667.                          CollapsedNum) {}
  4668.  
  4669.   /// Build an empty directive.
  4670.   ///
  4671.   /// \param CollapsedNum Number of collapsed nested loops.
  4672.   ///
  4673.   explicit OMPDistributeSimdDirective(unsigned CollapsedNum)
  4674.       : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
  4675.                          llvm::omp::OMPD_distribute_simd, SourceLocation(),
  4676.                          SourceLocation(), CollapsedNum) {}
  4677.  
  4678. public:
  4679.   /// Creates directive with a list of \a Clauses.
  4680.   ///
  4681.   /// \param C AST context.
  4682.   /// \param StartLoc Starting location of the directive kind.
  4683.   /// \param EndLoc Ending Location of the directive.
  4684.   /// \param CollapsedNum Number of collapsed loops.
  4685.   /// \param Clauses List of clauses.
  4686.   /// \param AssociatedStmt Statement, associated with the directive.
  4687.   /// \param Exprs Helper expressions for CodeGen.
  4688.   ///
  4689.   static OMPDistributeSimdDirective *
  4690.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  4691.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  4692.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  4693.  
  4694.   /// Creates an empty directive with the place for \a NumClauses clauses.
  4695.   ///
  4696.   /// \param C AST context.
  4697.   /// \param CollapsedNum Number of collapsed nested loops.
  4698.   /// \param NumClauses Number of clauses.
  4699.   ///
  4700.   static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C,
  4701.                                                  unsigned NumClauses,
  4702.                                                  unsigned CollapsedNum,
  4703.                                                  EmptyShell);
  4704.  
  4705.   static bool classof(const Stmt *T) {
  4706.     return T->getStmtClass() == OMPDistributeSimdDirectiveClass;
  4707.   }
  4708. };
  4709.  
  4710. /// This represents '#pragma omp target parallel for simd' directive.
  4711. ///
  4712. /// \code
  4713. /// #pragma omp target parallel for simd private(a) map(b) safelen(c)
  4714. /// \endcode
  4715. /// In this example directive '#pragma omp target parallel for simd' has clauses
  4716. /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen'
  4717. /// with the variable 'c'.
  4718. ///
  4719. class OMPTargetParallelForSimdDirective final : public OMPLoopDirective {
  4720.   friend class ASTStmtReader;
  4721.   friend class OMPExecutableDirective;
  4722.  
  4723.   /// Build directive with the given start and end location.
  4724.   ///
  4725.   /// \param StartLoc Starting location of the directive kind.
  4726.   /// \param EndLoc Ending location of the directive.
  4727.   /// \param CollapsedNum Number of collapsed nested loops.
  4728.   ///
  4729.   OMPTargetParallelForSimdDirective(SourceLocation StartLoc,
  4730.                                     SourceLocation EndLoc,
  4731.                                     unsigned CollapsedNum)
  4732.       : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
  4733.                          llvm::omp::OMPD_target_parallel_for_simd, StartLoc,
  4734.                          EndLoc, CollapsedNum) {}
  4735.  
  4736.   /// Build an empty directive.
  4737.   ///
  4738.   /// \param CollapsedNum Number of collapsed nested loops.
  4739.   ///
  4740.   explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum)
  4741.       : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
  4742.                          llvm::omp::OMPD_target_parallel_for_simd,
  4743.                          SourceLocation(), SourceLocation(), CollapsedNum) {}
  4744.  
  4745. public:
  4746.   /// Creates directive with a list of \a Clauses.
  4747.   ///
  4748.   /// \param C AST context.
  4749.   /// \param StartLoc Starting location of the directive kind.
  4750.   /// \param EndLoc Ending Location of the directive.
  4751.   /// \param CollapsedNum Number of collapsed loops.
  4752.   /// \param Clauses List of clauses.
  4753.   /// \param AssociatedStmt Statement, associated with the directive.
  4754.   /// \param Exprs Helper expressions for CodeGen.
  4755.   ///
  4756.   static OMPTargetParallelForSimdDirective *
  4757.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  4758.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  4759.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  4760.  
  4761.   /// Creates an empty directive with the place for \a NumClauses clauses.
  4762.   ///
  4763.   /// \param C AST context.
  4764.   /// \param CollapsedNum Number of collapsed nested loops.
  4765.   /// \param NumClauses Number of clauses.
  4766.   ///
  4767.   static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C,
  4768.                                                         unsigned NumClauses,
  4769.                                                         unsigned CollapsedNum,
  4770.                                                         EmptyShell);
  4771.  
  4772.   static bool classof(const Stmt *T) {
  4773.     return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
  4774.   }
  4775. };
  4776.  
  4777. /// This represents '#pragma omp target simd' directive.
  4778. ///
  4779. /// \code
  4780. /// #pragma omp target simd private(a) map(b) safelen(c)
  4781. /// \endcode
  4782. /// In this example directive '#pragma omp target simd' has clauses 'private'
  4783. /// with the variable 'a', 'map' with the variable 'b' and 'safelen' with
  4784. /// the variable 'c'.
  4785. ///
  4786. class OMPTargetSimdDirective final : public OMPLoopDirective {
  4787.   friend class ASTStmtReader;
  4788.   friend class OMPExecutableDirective;
  4789.  
  4790.   /// Build directive with the given start and end location.
  4791.   ///
  4792.   /// \param StartLoc Starting location of the directive kind.
  4793.   /// \param EndLoc Ending location of the directive.
  4794.   /// \param CollapsedNum Number of collapsed nested loops.
  4795.   ///
  4796.   OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
  4797.                          unsigned CollapsedNum)
  4798.       : OMPLoopDirective(OMPTargetSimdDirectiveClass,
  4799.                          llvm::omp::OMPD_target_simd, StartLoc, EndLoc,
  4800.                          CollapsedNum) {}
  4801.  
  4802.   /// Build an empty directive.
  4803.   ///
  4804.   /// \param CollapsedNum Number of collapsed nested loops.
  4805.   ///
  4806.   explicit OMPTargetSimdDirective(unsigned CollapsedNum)
  4807.       : OMPLoopDirective(OMPTargetSimdDirectiveClass,
  4808.                          llvm::omp::OMPD_target_simd, SourceLocation(),
  4809.                          SourceLocation(), CollapsedNum) {}
  4810.  
  4811. public:
  4812.   /// Creates directive with a list of \a Clauses.
  4813.   ///
  4814.   /// \param C AST context.
  4815.   /// \param StartLoc Starting location of the directive kind.
  4816.   /// \param EndLoc Ending Location of the directive.
  4817.   /// \param CollapsedNum Number of collapsed loops.
  4818.   /// \param Clauses List of clauses.
  4819.   /// \param AssociatedStmt Statement, associated with the directive.
  4820.   /// \param Exprs Helper expressions for CodeGen.
  4821.   ///
  4822.   static OMPTargetSimdDirective *
  4823.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  4824.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  4825.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  4826.  
  4827.   /// Creates an empty directive with the place for \a NumClauses clauses.
  4828.   ///
  4829.   /// \param C AST context.
  4830.   /// \param CollapsedNum Number of collapsed nested loops.
  4831.   /// \param NumClauses Number of clauses.
  4832.   ///
  4833.   static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C,
  4834.                                              unsigned NumClauses,
  4835.                                              unsigned CollapsedNum,
  4836.                                              EmptyShell);
  4837.  
  4838.   static bool classof(const Stmt *T) {
  4839.     return T->getStmtClass() == OMPTargetSimdDirectiveClass;
  4840.   }
  4841. };
  4842.  
  4843. /// This represents '#pragma omp teams distribute' directive.
  4844. ///
  4845. /// \code
  4846. /// #pragma omp teams distribute private(a,b)
  4847. /// \endcode
  4848. /// In this example directive '#pragma omp teams distribute' has clauses
  4849. /// 'private' with the variables 'a' and 'b'
  4850. ///
  4851. class OMPTeamsDistributeDirective final : public OMPLoopDirective {
  4852.   friend class ASTStmtReader;
  4853.   friend class OMPExecutableDirective;
  4854.  
  4855.   /// Build directive with the given start and end location.
  4856.   ///
  4857.   /// \param StartLoc Starting location of the directive kind.
  4858.   /// \param EndLoc Ending location of the directive.
  4859.   /// \param CollapsedNum Number of collapsed nested loops.
  4860.   ///
  4861.   OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
  4862.                               unsigned CollapsedNum)
  4863.       : OMPLoopDirective(OMPTeamsDistributeDirectiveClass,
  4864.                          llvm::omp::OMPD_teams_distribute, StartLoc, EndLoc,
  4865.                          CollapsedNum) {}
  4866.  
  4867.   /// Build an empty directive.
  4868.   ///
  4869.   /// \param CollapsedNum Number of collapsed nested loops.
  4870.   ///
  4871.   explicit OMPTeamsDistributeDirective(unsigned CollapsedNum)
  4872.       : OMPLoopDirective(OMPTeamsDistributeDirectiveClass,
  4873.                          llvm::omp::OMPD_teams_distribute, SourceLocation(),
  4874.                          SourceLocation(), CollapsedNum) {}
  4875.  
  4876. public:
  4877.   /// Creates directive with a list of \a Clauses.
  4878.   ///
  4879.   /// \param C AST context.
  4880.   /// \param StartLoc Starting location of the directive kind.
  4881.   /// \param EndLoc Ending Location of the directive.
  4882.   /// \param CollapsedNum Number of collapsed loops.
  4883.   /// \param Clauses List of clauses.
  4884.   /// \param AssociatedStmt Statement, associated with the directive.
  4885.   /// \param Exprs Helper expressions for CodeGen.
  4886.   ///
  4887.   static OMPTeamsDistributeDirective *
  4888.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  4889.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  4890.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  4891.  
  4892.   /// Creates an empty directive with the place for \a NumClauses clauses.
  4893.   ///
  4894.   /// \param C AST context.
  4895.   /// \param CollapsedNum Number of collapsed nested loops.
  4896.   /// \param NumClauses Number of clauses.
  4897.   ///
  4898.   static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C,
  4899.                                                   unsigned NumClauses,
  4900.                                                   unsigned CollapsedNum,
  4901.                                                   EmptyShell);
  4902.  
  4903.   static bool classof(const Stmt *T) {
  4904.     return T->getStmtClass() == OMPTeamsDistributeDirectiveClass;
  4905.   }
  4906. };
  4907.  
  4908. /// This represents '#pragma omp teams distribute simd'
  4909. /// combined directive.
  4910. ///
  4911. /// \code
  4912. /// #pragma omp teams distribute simd private(a,b)
  4913. /// \endcode
  4914. /// In this example directive '#pragma omp teams distribute simd'
  4915. /// has clause 'private' with the variables 'a' and 'b'
  4916. ///
  4917. class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective {
  4918.   friend class ASTStmtReader;
  4919.   friend class OMPExecutableDirective;
  4920.  
  4921.   /// Build directive with the given start and end location.
  4922.   ///
  4923.   /// \param StartLoc Starting location of the directive kind.
  4924.   /// \param EndLoc Ending location of the directive.
  4925.   /// \param CollapsedNum Number of collapsed nested loops.
  4926.   ///
  4927.   OMPTeamsDistributeSimdDirective(SourceLocation StartLoc,
  4928.                                   SourceLocation EndLoc, unsigned CollapsedNum)
  4929.       : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass,
  4930.                          llvm::omp::OMPD_teams_distribute_simd, StartLoc,
  4931.                          EndLoc, CollapsedNum) {}
  4932.  
  4933.   /// Build an empty directive.
  4934.   ///
  4935.   /// \param CollapsedNum Number of collapsed nested loops.
  4936.   ///
  4937.   explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum)
  4938.       : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass,
  4939.                          llvm::omp::OMPD_teams_distribute_simd,
  4940.                          SourceLocation(), SourceLocation(), CollapsedNum) {}
  4941.  
  4942. public:
  4943.   /// Creates directive with a list of \a Clauses.
  4944.   ///
  4945.   /// \param C AST context.
  4946.   /// \param StartLoc Starting location of the directive kind.
  4947.   /// \param EndLoc Ending Location of the directive.
  4948.   /// \param CollapsedNum Number of collapsed loops.
  4949.   /// \param Clauses List of clauses.
  4950.   /// \param AssociatedStmt Statement, associated with the directive.
  4951.   /// \param Exprs Helper expressions for CodeGen.
  4952.   ///
  4953.   static OMPTeamsDistributeSimdDirective *
  4954.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  4955.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  4956.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  4957.  
  4958.   /// Creates an empty directive with the place
  4959.   /// for \a NumClauses clauses.
  4960.   ///
  4961.   /// \param C AST context.
  4962.   /// \param CollapsedNum Number of collapsed nested loops.
  4963.   /// \param NumClauses Number of clauses.
  4964.   ///
  4965.   static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C,
  4966.                                                       unsigned NumClauses,
  4967.                                                       unsigned CollapsedNum,
  4968.                                                       EmptyShell);
  4969.  
  4970.   static bool classof(const Stmt *T) {
  4971.     return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass;
  4972.   }
  4973. };
  4974.  
  4975. /// This represents '#pragma omp teams distribute parallel for simd' composite
  4976. /// directive.
  4977. ///
  4978. /// \code
  4979. /// #pragma omp teams distribute parallel for simd private(x)
  4980. /// \endcode
  4981. /// In this example directive '#pragma omp teams distribute parallel for simd'
  4982. /// has clause 'private' with the variables 'x'
  4983. ///
  4984. class OMPTeamsDistributeParallelForSimdDirective final
  4985.     : public OMPLoopDirective {
  4986.   friend class ASTStmtReader;
  4987.   friend class OMPExecutableDirective;
  4988.  
  4989.   /// Build directive with the given start and end location.
  4990.   ///
  4991.   /// \param StartLoc Starting location of the directive kind.
  4992.   /// \param EndLoc Ending location of the directive.
  4993.   /// \param CollapsedNum Number of collapsed nested loops.
  4994.   ///
  4995.   OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
  4996.                                              SourceLocation EndLoc,
  4997.                                              unsigned CollapsedNum)
  4998.       : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass,
  4999.                          llvm::omp::OMPD_teams_distribute_parallel_for_simd,
  5000.                          StartLoc, EndLoc, CollapsedNum) {}
  5001.  
  5002.   /// Build an empty directive.
  5003.   ///
  5004.   /// \param CollapsedNum Number of collapsed nested loops.
  5005.   ///
  5006.   explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum)
  5007.       : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass,
  5008.                          llvm::omp::OMPD_teams_distribute_parallel_for_simd,
  5009.                          SourceLocation(), SourceLocation(), CollapsedNum) {}
  5010.  
  5011. public:
  5012.   /// Creates directive with a list of \a Clauses.
  5013.   ///
  5014.   /// \param C AST context.
  5015.   /// \param StartLoc Starting location of the directive kind.
  5016.   /// \param EndLoc Ending Location of the directive.
  5017.   /// \param CollapsedNum Number of collapsed loops.
  5018.   /// \param Clauses List of clauses.
  5019.   /// \param AssociatedStmt Statement, associated with the directive.
  5020.   /// \param Exprs Helper expressions for CodeGen.
  5021.   ///
  5022.   static OMPTeamsDistributeParallelForSimdDirective *
  5023.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  5024.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  5025.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  5026.  
  5027.   /// Creates an empty directive with the place for \a NumClauses clauses.
  5028.   ///
  5029.   /// \param C AST context.
  5030.   /// \param CollapsedNum Number of collapsed nested loops.
  5031.   /// \param NumClauses Number of clauses.
  5032.   ///
  5033.   static OMPTeamsDistributeParallelForSimdDirective *
  5034.   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
  5035.               EmptyShell);
  5036.  
  5037.   static bool classof(const Stmt *T) {
  5038.     return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass;
  5039.   }
  5040. };
  5041.  
  5042. /// This represents '#pragma omp teams distribute parallel for' composite
  5043. /// directive.
  5044. ///
  5045. /// \code
  5046. /// #pragma omp teams distribute parallel for private(x)
  5047. /// \endcode
  5048. /// In this example directive '#pragma omp teams distribute parallel for'
  5049. /// has clause 'private' with the variables 'x'
  5050. ///
  5051. class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
  5052.   friend class ASTStmtReader;
  5053.   friend class OMPExecutableDirective;
  5054.   /// true if the construct has inner cancel directive.
  5055.   bool HasCancel = false;
  5056.  
  5057.   /// Build directive with the given start and end location.
  5058.   ///
  5059.   /// \param StartLoc Starting location of the directive kind.
  5060.   /// \param EndLoc Ending location of the directive.
  5061.   /// \param CollapsedNum Number of collapsed nested loops.
  5062.   ///
  5063.   OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc,
  5064.                                          SourceLocation EndLoc,
  5065.                                          unsigned CollapsedNum)
  5066.       : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass,
  5067.                          llvm::omp::OMPD_teams_distribute_parallel_for,
  5068.                          StartLoc, EndLoc, CollapsedNum) {}
  5069.  
  5070.   /// Build an empty directive.
  5071.   ///
  5072.   /// \param CollapsedNum Number of collapsed nested loops.
  5073.   ///
  5074.   explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum)
  5075.       : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass,
  5076.                          llvm::omp::OMPD_teams_distribute_parallel_for,
  5077.                          SourceLocation(), SourceLocation(), CollapsedNum) {}
  5078.  
  5079.   /// Sets special task reduction descriptor.
  5080.   void setTaskReductionRefExpr(Expr *E) {
  5081.     Data->getChildren()[numLoopChildren(
  5082.         getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)] = E;
  5083.   }
  5084.  
  5085.   /// Set cancel state.
  5086.   void setHasCancel(bool Has) { HasCancel = Has; }
  5087.  
  5088. public:
  5089.   /// Creates directive with a list of \a Clauses.
  5090.   ///
  5091.   /// \param C AST context.
  5092.   /// \param StartLoc Starting location of the directive kind.
  5093.   /// \param EndLoc Ending Location of the directive.
  5094.   /// \param CollapsedNum Number of collapsed loops.
  5095.   /// \param Clauses List of clauses.
  5096.   /// \param AssociatedStmt Statement, associated with the directive.
  5097.   /// \param Exprs Helper expressions for CodeGen.
  5098.   /// \param TaskRedRef Task reduction special reference expression to handle
  5099.   /// taskgroup descriptor.
  5100.   /// \param HasCancel true if this directive has inner cancel directive.
  5101.   ///
  5102.   static OMPTeamsDistributeParallelForDirective *
  5103.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  5104.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  5105.          Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
  5106.          bool HasCancel);
  5107.  
  5108.   /// Creates an empty directive with the place for \a NumClauses clauses.
  5109.   ///
  5110.   /// \param C AST context.
  5111.   /// \param CollapsedNum Number of collapsed nested loops.
  5112.   /// \param NumClauses Number of clauses.
  5113.   ///
  5114.   static OMPTeamsDistributeParallelForDirective *
  5115.   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
  5116.               EmptyShell);
  5117.  
  5118.   /// Returns special task reduction reference expression.
  5119.   Expr *getTaskReductionRefExpr() {
  5120.     return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
  5121.         getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)]);
  5122.   }
  5123.   const Expr *getTaskReductionRefExpr() const {
  5124.     return const_cast<OMPTeamsDistributeParallelForDirective *>(this)
  5125.         ->getTaskReductionRefExpr();
  5126.   }
  5127.  
  5128.   /// Return true if current directive has inner cancel directive.
  5129.   bool hasCancel() const { return HasCancel; }
  5130.  
  5131.   static bool classof(const Stmt *T) {
  5132.     return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass;
  5133.   }
  5134. };
  5135.  
  5136. /// This represents '#pragma omp target teams' directive.
  5137. ///
  5138. /// \code
  5139. /// #pragma omp target teams if(a>0)
  5140. /// \endcode
  5141. /// In this example directive '#pragma omp target teams' has clause 'if' with
  5142. /// condition 'a>0'.
  5143. ///
  5144. class OMPTargetTeamsDirective final : public OMPExecutableDirective {
  5145.   friend class ASTStmtReader;
  5146.   friend class OMPExecutableDirective;
  5147.   /// Build directive with the given start and end location.
  5148.   ///
  5149.   /// \param StartLoc Starting location of the directive kind.
  5150.   /// \param EndLoc Ending location of the directive.
  5151.   ///
  5152.   OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  5153.       : OMPExecutableDirective(OMPTargetTeamsDirectiveClass,
  5154.                                llvm::omp::OMPD_target_teams, StartLoc, EndLoc) {
  5155.   }
  5156.  
  5157.   /// Build an empty directive.
  5158.   ///
  5159.   explicit OMPTargetTeamsDirective()
  5160.       : OMPExecutableDirective(OMPTargetTeamsDirectiveClass,
  5161.                                llvm::omp::OMPD_target_teams, SourceLocation(),
  5162.                                SourceLocation()) {}
  5163.  
  5164. public:
  5165.   /// Creates directive with a list of \a Clauses.
  5166.   ///
  5167.   /// \param C AST context.
  5168.   /// \param StartLoc Starting location of the directive kind.
  5169.   /// \param EndLoc Ending Location of the directive.
  5170.   /// \param Clauses List of clauses.
  5171.   /// \param AssociatedStmt Statement, associated with the directive.
  5172.   ///
  5173.   static OMPTargetTeamsDirective *Create(const ASTContext &C,
  5174.                                          SourceLocation StartLoc,
  5175.                                          SourceLocation EndLoc,
  5176.                                          ArrayRef<OMPClause *> Clauses,
  5177.                                          Stmt *AssociatedStmt);
  5178.  
  5179.   /// Creates an empty directive with the place for \a NumClauses clauses.
  5180.   ///
  5181.   /// \param C AST context.
  5182.   /// \param NumClauses Number of clauses.
  5183.   ///
  5184.   static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C,
  5185.                                               unsigned NumClauses, EmptyShell);
  5186.  
  5187.   static bool classof(const Stmt *T) {
  5188.     return T->getStmtClass() == OMPTargetTeamsDirectiveClass;
  5189.   }
  5190. };
  5191.  
  5192. /// This represents '#pragma omp target teams distribute' combined directive.
  5193. ///
  5194. /// \code
  5195. /// #pragma omp target teams distribute private(x)
  5196. /// \endcode
  5197. /// In this example directive '#pragma omp target teams distribute' has clause
  5198. /// 'private' with the variables 'x'
  5199. ///
  5200. class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective {
  5201.   friend class ASTStmtReader;
  5202.   friend class OMPExecutableDirective;
  5203.  
  5204.   /// Build directive with the given start and end location.
  5205.   ///
  5206.   /// \param StartLoc Starting location of the directive kind.
  5207.   /// \param EndLoc Ending location of the directive.
  5208.   /// \param CollapsedNum Number of collapsed nested loops.
  5209.   ///
  5210.   OMPTargetTeamsDistributeDirective(SourceLocation StartLoc,
  5211.                                     SourceLocation EndLoc,
  5212.                                     unsigned CollapsedNum)
  5213.       : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass,
  5214.                          llvm::omp::OMPD_target_teams_distribute, StartLoc,
  5215.                          EndLoc, CollapsedNum) {}
  5216.  
  5217.   /// Build an empty directive.
  5218.   ///
  5219.   /// \param CollapsedNum Number of collapsed nested loops.
  5220.   ///
  5221.   explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum)
  5222.       : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass,
  5223.                          llvm::omp::OMPD_target_teams_distribute,
  5224.                          SourceLocation(), SourceLocation(), CollapsedNum) {}
  5225.  
  5226. public:
  5227.   /// Creates directive with a list of \a Clauses.
  5228.   ///
  5229.   /// \param C AST context.
  5230.   /// \param StartLoc Starting location of the directive kind.
  5231.   /// \param EndLoc Ending Location of the directive.
  5232.   /// \param CollapsedNum Number of collapsed loops.
  5233.   /// \param Clauses List of clauses.
  5234.   /// \param AssociatedStmt Statement, associated with the directive.
  5235.   /// \param Exprs Helper expressions for CodeGen.
  5236.   ///
  5237.   static OMPTargetTeamsDistributeDirective *
  5238.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  5239.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  5240.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  5241.  
  5242.   /// Creates an empty directive with the place for \a NumClauses clauses.
  5243.   ///
  5244.   /// \param C AST context.
  5245.   /// \param CollapsedNum Number of collapsed nested loops.
  5246.   /// \param NumClauses Number of clauses.
  5247.   ///
  5248.   static OMPTargetTeamsDistributeDirective *
  5249.   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
  5250.               EmptyShell);
  5251.  
  5252.   static bool classof(const Stmt *T) {
  5253.     return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass;
  5254.   }
  5255. };
  5256.  
  5257. /// This represents '#pragma omp target teams distribute parallel for' combined
  5258. /// directive.
  5259. ///
  5260. /// \code
  5261. /// #pragma omp target teams distribute parallel for private(x)
  5262. /// \endcode
  5263. /// In this example directive '#pragma omp target teams distribute parallel
  5264. /// for' has clause 'private' with the variables 'x'
  5265. ///
  5266. class OMPTargetTeamsDistributeParallelForDirective final
  5267.     : public OMPLoopDirective {
  5268.   friend class ASTStmtReader;
  5269.   friend class OMPExecutableDirective;
  5270.   /// true if the construct has inner cancel directive.
  5271.   bool HasCancel = false;
  5272.  
  5273.   /// Build directive with the given start and end location.
  5274.   ///
  5275.   /// \param StartLoc Starting location of the directive kind.
  5276.   /// \param EndLoc Ending location of the directive.
  5277.   /// \param CollapsedNum Number of collapsed nested loops.
  5278.   ///
  5279.   OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc,
  5280.                                                SourceLocation EndLoc,
  5281.                                                unsigned CollapsedNum)
  5282.       : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass,
  5283.                          llvm::omp::OMPD_target_teams_distribute_parallel_for,
  5284.                          StartLoc, EndLoc, CollapsedNum) {}
  5285.  
  5286.   /// Build an empty directive.
  5287.   ///
  5288.   /// \param CollapsedNum Number of collapsed nested loops.
  5289.   ///
  5290.   explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum)
  5291.       : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass,
  5292.                          llvm::omp::OMPD_target_teams_distribute_parallel_for,
  5293.                          SourceLocation(), SourceLocation(), CollapsedNum) {}
  5294.  
  5295.   /// Sets special task reduction descriptor.
  5296.   void setTaskReductionRefExpr(Expr *E) {
  5297.     Data->getChildren()[numLoopChildren(
  5298.         getLoopsNumber(),
  5299.         llvm::omp::OMPD_target_teams_distribute_parallel_for)] = E;
  5300.   }
  5301.  
  5302.   /// Set cancel state.
  5303.   void setHasCancel(bool Has) { HasCancel = Has; }
  5304.  
  5305. public:
  5306.   /// Creates directive with a list of \a Clauses.
  5307.   ///
  5308.   /// \param C AST context.
  5309.   /// \param StartLoc Starting location of the directive kind.
  5310.   /// \param EndLoc Ending Location of the directive.
  5311.   /// \param CollapsedNum Number of collapsed loops.
  5312.   /// \param Clauses List of clauses.
  5313.   /// \param AssociatedStmt Statement, associated with the directive.
  5314.   /// \param Exprs Helper expressions for CodeGen.
  5315.   /// \param TaskRedRef Task reduction special reference expression to handle
  5316.   /// taskgroup descriptor.
  5317.   /// \param HasCancel true if this directive has inner cancel directive.
  5318.   ///
  5319.   static OMPTargetTeamsDistributeParallelForDirective *
  5320.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  5321.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  5322.          Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
  5323.          bool HasCancel);
  5324.  
  5325.   /// Creates an empty directive with the place for \a NumClauses clauses.
  5326.   ///
  5327.   /// \param C AST context.
  5328.   /// \param CollapsedNum Number of collapsed nested loops.
  5329.   /// \param NumClauses Number of clauses.
  5330.   ///
  5331.   static OMPTargetTeamsDistributeParallelForDirective *
  5332.   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
  5333.               EmptyShell);
  5334.  
  5335.   /// Returns special task reduction reference expression.
  5336.   Expr *getTaskReductionRefExpr() {
  5337.     return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
  5338.         getLoopsNumber(),
  5339.         llvm::omp::OMPD_target_teams_distribute_parallel_for)]);
  5340.   }
  5341.   const Expr *getTaskReductionRefExpr() const {
  5342.     return const_cast<OMPTargetTeamsDistributeParallelForDirective *>(this)
  5343.         ->getTaskReductionRefExpr();
  5344.   }
  5345.  
  5346.   /// Return true if current directive has inner cancel directive.
  5347.   bool hasCancel() const { return HasCancel; }
  5348.  
  5349.   static bool classof(const Stmt *T) {
  5350.     return T->getStmtClass() ==
  5351.            OMPTargetTeamsDistributeParallelForDirectiveClass;
  5352.   }
  5353. };
  5354.  
  5355. /// This represents '#pragma omp target teams distribute parallel for simd'
  5356. /// combined directive.
  5357. ///
  5358. /// \code
  5359. /// #pragma omp target teams distribute parallel for simd private(x)
  5360. /// \endcode
  5361. /// In this example directive '#pragma omp target teams distribute parallel
  5362. /// for simd' has clause 'private' with the variables 'x'
  5363. ///
  5364. class OMPTargetTeamsDistributeParallelForSimdDirective final
  5365.     : public OMPLoopDirective {
  5366.   friend class ASTStmtReader;
  5367.   friend class OMPExecutableDirective;
  5368.  
  5369.   /// Build directive with the given start and end location.
  5370.   ///
  5371.   /// \param StartLoc Starting location of the directive kind.
  5372.   /// \param EndLoc Ending location of the directive.
  5373.   /// \param CollapsedNum Number of collapsed nested loops.
  5374.   ///
  5375.   OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
  5376.                                                    SourceLocation EndLoc,
  5377.                                                    unsigned CollapsedNum)
  5378.       : OMPLoopDirective(
  5379.             OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
  5380.             llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, StartLoc,
  5381.             EndLoc, CollapsedNum) {}
  5382.  
  5383.   /// Build an empty directive.
  5384.   ///
  5385.   /// \param CollapsedNum Number of collapsed nested loops.
  5386.   ///
  5387.   explicit OMPTargetTeamsDistributeParallelForSimdDirective(
  5388.       unsigned CollapsedNum)
  5389.       : OMPLoopDirective(
  5390.             OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
  5391.             llvm::omp::OMPD_target_teams_distribute_parallel_for_simd,
  5392.             SourceLocation(), SourceLocation(), CollapsedNum) {}
  5393.  
  5394. public:
  5395.   /// Creates directive with a list of \a Clauses.
  5396.   ///
  5397.   /// \param C AST context.
  5398.   /// \param StartLoc Starting location of the directive kind.
  5399.   /// \param EndLoc Ending Location of the directive.
  5400.   /// \param CollapsedNum Number of collapsed loops.
  5401.   /// \param Clauses List of clauses.
  5402.   /// \param AssociatedStmt Statement, associated with the directive.
  5403.   /// \param Exprs Helper expressions for CodeGen.
  5404.   ///
  5405.   static OMPTargetTeamsDistributeParallelForSimdDirective *
  5406.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  5407.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  5408.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  5409.  
  5410.   /// Creates an empty directive with the place for \a NumClauses clauses.
  5411.   ///
  5412.   /// \param C AST context.
  5413.   /// \param CollapsedNum Number of collapsed nested loops.
  5414.   /// \param NumClauses Number of clauses.
  5415.   ///
  5416.   static OMPTargetTeamsDistributeParallelForSimdDirective *
  5417.   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
  5418.               EmptyShell);
  5419.  
  5420.   static bool classof(const Stmt *T) {
  5421.     return T->getStmtClass() ==
  5422.            OMPTargetTeamsDistributeParallelForSimdDirectiveClass;
  5423.   }
  5424. };
  5425.  
  5426. /// This represents '#pragma omp target teams distribute simd' combined
  5427. /// directive.
  5428. ///
  5429. /// \code
  5430. /// #pragma omp target teams distribute simd private(x)
  5431. /// \endcode
  5432. /// In this example directive '#pragma omp target teams distribute simd'
  5433. /// has clause 'private' with the variables 'x'
  5434. ///
  5435. class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective {
  5436.   friend class ASTStmtReader;
  5437.   friend class OMPExecutableDirective;
  5438.  
  5439.   /// Build directive with the given start and end location.
  5440.   ///
  5441.   /// \param StartLoc Starting location of the directive kind.
  5442.   /// \param EndLoc Ending location of the directive.
  5443.   /// \param CollapsedNum Number of collapsed nested loops.
  5444.   ///
  5445.   OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc,
  5446.                                         SourceLocation EndLoc,
  5447.                                         unsigned CollapsedNum)
  5448.       : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass,
  5449.                          llvm::omp::OMPD_target_teams_distribute_simd, StartLoc,
  5450.                          EndLoc, CollapsedNum) {}
  5451.  
  5452.   /// Build an empty directive.
  5453.   ///
  5454.   /// \param CollapsedNum Number of collapsed nested loops.
  5455.   ///
  5456.   explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum)
  5457.       : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass,
  5458.                          llvm::omp::OMPD_target_teams_distribute_simd,
  5459.                          SourceLocation(), SourceLocation(), CollapsedNum) {}
  5460.  
  5461. public:
  5462.   /// Creates directive with a list of \a Clauses.
  5463.   ///
  5464.   /// \param C AST context.
  5465.   /// \param StartLoc Starting location of the directive kind.
  5466.   /// \param EndLoc Ending Location of the directive.
  5467.   /// \param CollapsedNum Number of collapsed loops.
  5468.   /// \param Clauses List of clauses.
  5469.   /// \param AssociatedStmt Statement, associated with the directive.
  5470.   /// \param Exprs Helper expressions for CodeGen.
  5471.   ///
  5472.   static OMPTargetTeamsDistributeSimdDirective *
  5473.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  5474.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  5475.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  5476.  
  5477.   /// Creates an empty directive with the place for \a NumClauses clauses.
  5478.   ///
  5479.   /// \param C AST context.
  5480.   /// \param CollapsedNum Number of collapsed nested loops.
  5481.   /// \param NumClauses Number of clauses.
  5482.   ///
  5483.   static OMPTargetTeamsDistributeSimdDirective *
  5484.   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
  5485.               EmptyShell);
  5486.  
  5487.   static bool classof(const Stmt *T) {
  5488.     return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
  5489.   }
  5490. };
  5491.  
  5492. /// This represents the '#pragma omp tile' loop transformation directive.
  5493. class OMPTileDirective final : public OMPLoopTransformationDirective {
  5494.   friend class ASTStmtReader;
  5495.   friend class OMPExecutableDirective;
  5496.  
  5497.   /// Default list of offsets.
  5498.   enum {
  5499.     PreInitsOffset = 0,
  5500.     TransformedStmtOffset,
  5501.   };
  5502.  
  5503.   explicit OMPTileDirective(SourceLocation StartLoc, SourceLocation EndLoc,
  5504.                             unsigned NumLoops)
  5505.       : OMPLoopTransformationDirective(OMPTileDirectiveClass,
  5506.                                        llvm::omp::OMPD_tile, StartLoc, EndLoc,
  5507.                                        NumLoops) {
  5508.     setNumGeneratedLoops(3 * NumLoops);
  5509.   }
  5510.  
  5511.   void setPreInits(Stmt *PreInits) {
  5512.     Data->getChildren()[PreInitsOffset] = PreInits;
  5513.   }
  5514.  
  5515.   void setTransformedStmt(Stmt *S) {
  5516.     Data->getChildren()[TransformedStmtOffset] = S;
  5517.   }
  5518.  
  5519. public:
  5520.   /// Create a new AST node representation for '#pragma omp tile'.
  5521.   ///
  5522.   /// \param C         Context of the AST.
  5523.   /// \param StartLoc  Location of the introducer (e.g. the 'omp' token).
  5524.   /// \param EndLoc    Location of the directive's end (e.g. the tok::eod).
  5525.   /// \param Clauses   The directive's clauses.
  5526.   /// \param NumLoops  Number of associated loops (number of items in the
  5527.   ///                  'sizes' clause).
  5528.   /// \param AssociatedStmt The outermost associated loop.
  5529.   /// \param TransformedStmt The loop nest after tiling, or nullptr in
  5530.   ///                        dependent contexts.
  5531.   /// \param PreInits Helper preinits statements for the loop nest.
  5532.   static OMPTileDirective *Create(const ASTContext &C, SourceLocation StartLoc,
  5533.                                   SourceLocation EndLoc,
  5534.                                   ArrayRef<OMPClause *> Clauses,
  5535.                                   unsigned NumLoops, Stmt *AssociatedStmt,
  5536.                                   Stmt *TransformedStmt, Stmt *PreInits);
  5537.  
  5538.   /// Build an empty '#pragma omp tile' AST node for deserialization.
  5539.   ///
  5540.   /// \param C          Context of the AST.
  5541.   /// \param NumClauses Number of clauses to allocate.
  5542.   /// \param NumLoops   Number of associated loops to allocate.
  5543.   static OMPTileDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
  5544.                                        unsigned NumLoops);
  5545.  
  5546.   /// Gets/sets the associated loops after tiling.
  5547.   ///
  5548.   /// This is in de-sugared format stored as a CompoundStmt.
  5549.   ///
  5550.   /// \code
  5551.   ///   for (...)
  5552.   ///     ...
  5553.   /// \endcode
  5554.   ///
  5555.   /// Note that if the generated loops a become associated loops of another
  5556.   /// directive, they may need to be hoisted before them.
  5557.   Stmt *getTransformedStmt() const {
  5558.     return Data->getChildren()[TransformedStmtOffset];
  5559.   }
  5560.  
  5561.   /// Return preinits statement.
  5562.   Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
  5563.  
  5564.   static bool classof(const Stmt *T) {
  5565.     return T->getStmtClass() == OMPTileDirectiveClass;
  5566.   }
  5567. };
  5568.  
  5569. /// This represents the '#pragma omp unroll' loop transformation directive.
  5570. ///
  5571. /// \code
  5572. /// #pragma omp unroll
  5573. /// for (int i = 0; i < 64; ++i)
  5574. /// \endcode
  5575. class OMPUnrollDirective final : public OMPLoopTransformationDirective {
  5576.   friend class ASTStmtReader;
  5577.   friend class OMPExecutableDirective;
  5578.  
  5579.   /// Default list of offsets.
  5580.   enum {
  5581.     PreInitsOffset = 0,
  5582.     TransformedStmtOffset,
  5583.   };
  5584.  
  5585.   explicit OMPUnrollDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  5586.       : OMPLoopTransformationDirective(OMPUnrollDirectiveClass,
  5587.                                        llvm::omp::OMPD_unroll, StartLoc, EndLoc,
  5588.                                        1) {}
  5589.  
  5590.   /// Set the pre-init statements.
  5591.   void setPreInits(Stmt *PreInits) {
  5592.     Data->getChildren()[PreInitsOffset] = PreInits;
  5593.   }
  5594.  
  5595.   /// Set the de-sugared statement.
  5596.   void setTransformedStmt(Stmt *S) {
  5597.     Data->getChildren()[TransformedStmtOffset] = S;
  5598.   }
  5599.  
  5600. public:
  5601.   /// Create a new AST node representation for '#pragma omp unroll'.
  5602.   ///
  5603.   /// \param C         Context of the AST.
  5604.   /// \param StartLoc  Location of the introducer (e.g. the 'omp' token).
  5605.   /// \param EndLoc    Location of the directive's end (e.g. the tok::eod).
  5606.   /// \param Clauses   The directive's clauses.
  5607.   /// \param AssociatedStmt The outermost associated loop.
  5608.   /// \param TransformedStmt The loop nest after tiling, or nullptr in
  5609.   ///                        dependent contexts.
  5610.   /// \param PreInits   Helper preinits statements for the loop nest.
  5611.   static OMPUnrollDirective *
  5612.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  5613.          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
  5614.          unsigned NumGeneratedLoops, Stmt *TransformedStmt, Stmt *PreInits);
  5615.  
  5616.   /// Build an empty '#pragma omp unroll' AST node for deserialization.
  5617.   ///
  5618.   /// \param C          Context of the AST.
  5619.   /// \param NumClauses Number of clauses to allocate.
  5620.   static OMPUnrollDirective *CreateEmpty(const ASTContext &C,
  5621.                                          unsigned NumClauses);
  5622.  
  5623.   /// Get the de-sugared associated loops after unrolling.
  5624.   ///
  5625.   /// This is only used if the unrolled loop becomes an associated loop of
  5626.   /// another directive, otherwise the loop is emitted directly using loop
  5627.   /// transformation metadata. When the unrolled loop cannot be used by another
  5628.   /// directive (e.g. because of the full clause), the transformed stmt can also
  5629.   /// be nullptr.
  5630.   Stmt *getTransformedStmt() const {
  5631.     return Data->getChildren()[TransformedStmtOffset];
  5632.   }
  5633.  
  5634.   /// Return the pre-init statements.
  5635.   Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
  5636.  
  5637.   static bool classof(const Stmt *T) {
  5638.     return T->getStmtClass() == OMPUnrollDirectiveClass;
  5639.   }
  5640. };
  5641.  
  5642. /// This represents '#pragma omp scan' directive.
  5643. ///
  5644. /// \code
  5645. /// #pragma omp scan inclusive(a)
  5646. /// \endcode
  5647. /// In this example directive '#pragma omp scan' has clause 'inclusive' with
  5648. /// list item 'a'.
  5649. class OMPScanDirective final : public OMPExecutableDirective {
  5650.   friend class ASTStmtReader;
  5651.   friend class OMPExecutableDirective;
  5652.   /// Build directive with the given start and end location.
  5653.   ///
  5654.   /// \param StartLoc Starting location of the directive kind.
  5655.   /// \param EndLoc Ending location of the directive.
  5656.   ///
  5657.   OMPScanDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  5658.       : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan,
  5659.                                StartLoc, EndLoc) {}
  5660.  
  5661.   /// Build an empty directive.
  5662.   ///
  5663.   explicit OMPScanDirective()
  5664.       : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan,
  5665.                                SourceLocation(), SourceLocation()) {}
  5666.  
  5667. public:
  5668.   /// Creates directive with a list of \a Clauses.
  5669.   ///
  5670.   /// \param C AST context.
  5671.   /// \param StartLoc Starting location of the directive kind.
  5672.   /// \param EndLoc Ending Location of the directive.
  5673.   /// \param Clauses List of clauses (only single OMPFlushClause clause is
  5674.   /// allowed).
  5675.   ///
  5676.   static OMPScanDirective *Create(const ASTContext &C, SourceLocation StartLoc,
  5677.                                   SourceLocation EndLoc,
  5678.                                   ArrayRef<OMPClause *> Clauses);
  5679.  
  5680.   /// Creates an empty directive with the place for \a NumClauses
  5681.   /// clauses.
  5682.   ///
  5683.   /// \param C AST context.
  5684.   /// \param NumClauses Number of clauses.
  5685.   ///
  5686.   static OMPScanDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
  5687.                                        EmptyShell);
  5688.  
  5689.   static bool classof(const Stmt *T) {
  5690.     return T->getStmtClass() == OMPScanDirectiveClass;
  5691.   }
  5692. };
  5693.  
  5694. /// This represents '#pragma omp interop' directive.
  5695. ///
  5696. /// \code
  5697. /// #pragma omp interop init(target:obj) device(x) depend(inout:y) nowait
  5698. /// \endcode
  5699. /// In this example directive '#pragma omp interop' has
  5700. /// clauses 'init', 'device', 'depend' and 'nowait'.
  5701. ///
  5702. class OMPInteropDirective final : public OMPExecutableDirective {
  5703.   friend class ASTStmtReader;
  5704.   friend class OMPExecutableDirective;
  5705.  
  5706.   /// Build directive with the given start and end location.
  5707.   ///
  5708.   /// \param StartLoc Starting location of the directive.
  5709.   /// \param EndLoc Ending location of the directive.
  5710.   ///
  5711.   OMPInteropDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  5712.       : OMPExecutableDirective(OMPInteropDirectiveClass,
  5713.                                llvm::omp::OMPD_interop, StartLoc, EndLoc) {}
  5714.  
  5715.   /// Build an empty directive.
  5716.   ///
  5717.   explicit OMPInteropDirective()
  5718.       : OMPExecutableDirective(OMPInteropDirectiveClass,
  5719.                                llvm::omp::OMPD_interop, SourceLocation(),
  5720.                                SourceLocation()) {}
  5721.  
  5722. public:
  5723.   /// Creates directive.
  5724.   ///
  5725.   /// \param C AST context.
  5726.   /// \param StartLoc Starting location of the directive.
  5727.   /// \param EndLoc Ending Location of the directive.
  5728.   /// \param Clauses The directive's clauses.
  5729.   ///
  5730.   static OMPInteropDirective *Create(const ASTContext &C,
  5731.                                      SourceLocation StartLoc,
  5732.                                      SourceLocation EndLoc,
  5733.                                      ArrayRef<OMPClause *> Clauses);
  5734.  
  5735.   /// Creates an empty directive.
  5736.   ///
  5737.   /// \param C AST context.
  5738.   ///
  5739.   static OMPInteropDirective *CreateEmpty(const ASTContext &C,
  5740.                                           unsigned NumClauses, EmptyShell);
  5741.  
  5742.   static bool classof(const Stmt *T) {
  5743.     return T->getStmtClass() == OMPInteropDirectiveClass;
  5744.   }
  5745. };
  5746.  
  5747. /// This represents '#pragma omp dispatch' directive.
  5748. ///
  5749. /// \code
  5750. /// #pragma omp dispatch device(dnum)
  5751. /// \endcode
  5752. /// This example shows a directive '#pragma omp dispatch' with a
  5753. /// device clause with variable 'dnum'.
  5754. ///
  5755. class OMPDispatchDirective final : public OMPExecutableDirective {
  5756.   friend class ASTStmtReader;
  5757.   friend class OMPExecutableDirective;
  5758.  
  5759.   /// The location of the target-call.
  5760.   SourceLocation TargetCallLoc;
  5761.  
  5762.   /// Set the location of the target-call.
  5763.   void setTargetCallLoc(SourceLocation Loc) { TargetCallLoc = Loc; }
  5764.  
  5765.   /// Build directive with the given start and end location.
  5766.   ///
  5767.   /// \param StartLoc Starting location of the directive kind.
  5768.   /// \param EndLoc Ending location of the directive.
  5769.   ///
  5770.   OMPDispatchDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  5771.       : OMPExecutableDirective(OMPDispatchDirectiveClass,
  5772.                                llvm::omp::OMPD_dispatch, StartLoc, EndLoc) {}
  5773.  
  5774.   /// Build an empty directive.
  5775.   ///
  5776.   explicit OMPDispatchDirective()
  5777.       : OMPExecutableDirective(OMPDispatchDirectiveClass,
  5778.                                llvm::omp::OMPD_dispatch, SourceLocation(),
  5779.                                SourceLocation()) {}
  5780.  
  5781. public:
  5782.   /// Creates directive with a list of \a Clauses.
  5783.   ///
  5784.   /// \param C AST context.
  5785.   /// \param StartLoc Starting location of the directive kind.
  5786.   /// \param EndLoc Ending Location of the directive.
  5787.   /// \param Clauses List of clauses.
  5788.   /// \param AssociatedStmt Statement, associated with the directive.
  5789.   /// \param TargetCallLoc Location of the target-call.
  5790.   ///
  5791.   static OMPDispatchDirective *
  5792.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  5793.          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
  5794.          SourceLocation TargetCallLoc);
  5795.  
  5796.   /// Creates an empty directive with the place for \a NumClauses
  5797.   /// clauses.
  5798.   ///
  5799.   /// \param C AST context.
  5800.   /// \param NumClauses Number of clauses.
  5801.   ///
  5802.   static OMPDispatchDirective *CreateEmpty(const ASTContext &C,
  5803.                                            unsigned NumClauses, EmptyShell);
  5804.  
  5805.   /// Return location of target-call.
  5806.   SourceLocation getTargetCallLoc() const { return TargetCallLoc; }
  5807.  
  5808.   static bool classof(const Stmt *T) {
  5809.     return T->getStmtClass() == OMPDispatchDirectiveClass;
  5810.   }
  5811. };
  5812.  
  5813. /// This represents '#pragma omp masked' directive.
  5814. /// \code
  5815. /// #pragma omp masked filter(tid)
  5816. /// \endcode
  5817. /// This example shows a directive '#pragma omp masked' with a filter clause
  5818. /// with variable 'tid'.
  5819. ///
  5820. class OMPMaskedDirective final : public OMPExecutableDirective {
  5821.   friend class ASTStmtReader;
  5822.   friend class OMPExecutableDirective;
  5823.  
  5824.   /// Build directive with the given start and end location.
  5825.   ///
  5826.   /// \param StartLoc Starting location of the directive kind.
  5827.   /// \param EndLoc Ending location of the directive.
  5828.   ///
  5829.   OMPMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  5830.       : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked,
  5831.                                StartLoc, EndLoc) {}
  5832.  
  5833.   /// Build an empty directive.
  5834.   ///
  5835.   explicit OMPMaskedDirective()
  5836.       : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked,
  5837.                                SourceLocation(), SourceLocation()) {}
  5838.  
  5839. public:
  5840.   /// Creates directive.
  5841.   ///
  5842.   /// \param C AST context.
  5843.   /// \param StartLoc Starting location of the directive kind.
  5844.   /// \param EndLoc Ending Location of the directive.
  5845.   /// \param AssociatedStmt Statement, associated with the directive.
  5846.   ///
  5847.   static OMPMaskedDirective *
  5848.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  5849.          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
  5850.  
  5851.   /// Creates an empty directive.
  5852.   ///
  5853.   /// \param C AST context.
  5854.   ///
  5855.   static OMPMaskedDirective *CreateEmpty(const ASTContext &C,
  5856.                                          unsigned NumClauses, EmptyShell);
  5857.  
  5858.   static bool classof(const Stmt *T) {
  5859.     return T->getStmtClass() == OMPMaskedDirectiveClass;
  5860.   }
  5861. };
  5862.  
  5863. /// This represents '#pragma omp metadirective' directive.
  5864. ///
  5865. /// \code
  5866. /// #pragma omp metadirective when(user={condition(N>10)}: parallel for)
  5867. /// \endcode
  5868. /// In this example directive '#pragma omp metadirective' has clauses 'when'
  5869. /// with a dynamic user condition to check if a variable 'N > 10'
  5870. ///
  5871. class OMPMetaDirective final : public OMPExecutableDirective {
  5872.   friend class ASTStmtReader;
  5873.   friend class OMPExecutableDirective;
  5874.   Stmt *IfStmt;
  5875.  
  5876.   OMPMetaDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  5877.       : OMPExecutableDirective(OMPMetaDirectiveClass,
  5878.                                llvm::omp::OMPD_metadirective, StartLoc,
  5879.                                EndLoc) {}
  5880.   explicit OMPMetaDirective()
  5881.       : OMPExecutableDirective(OMPMetaDirectiveClass,
  5882.                                llvm::omp::OMPD_metadirective, SourceLocation(),
  5883.                                SourceLocation()) {}
  5884.  
  5885.   void setIfStmt(Stmt *S) { IfStmt = S; }
  5886.  
  5887. public:
  5888.   static OMPMetaDirective *Create(const ASTContext &C, SourceLocation StartLoc,
  5889.                                   SourceLocation EndLoc,
  5890.                                   ArrayRef<OMPClause *> Clauses,
  5891.                                   Stmt *AssociatedStmt, Stmt *IfStmt);
  5892.   static OMPMetaDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
  5893.                                        EmptyShell);
  5894.   Stmt *getIfStmt() const { return IfStmt; }
  5895.  
  5896.   static bool classof(const Stmt *T) {
  5897.     return T->getStmtClass() == OMPMetaDirectiveClass;
  5898.   }
  5899. };
  5900.  
  5901. /// This represents '#pragma omp loop' directive.
  5902. ///
  5903. /// \code
  5904. /// #pragma omp loop private(a,b) binding(parallel) order(concurrent)
  5905. /// \endcode
  5906. /// In this example directive '#pragma omp loop' has
  5907. /// clauses 'private' with the variables 'a' and 'b', 'binding' with
  5908. /// modifier 'parallel' and 'order(concurrent).
  5909. ///
  5910. class OMPGenericLoopDirective final : public OMPLoopDirective {
  5911.   friend class ASTStmtReader;
  5912.   friend class OMPExecutableDirective;
  5913.   /// Build directive with the given start and end location.
  5914.   ///
  5915.   /// \param StartLoc Starting location of the directive kind.
  5916.   /// \param EndLoc Ending location of the directive.
  5917.   /// \param CollapsedNum Number of collapsed nested loops.
  5918.   ///
  5919.   OMPGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
  5920.                           unsigned CollapsedNum)
  5921.       : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop,
  5922.                          StartLoc, EndLoc, CollapsedNum) {}
  5923.  
  5924.   /// Build an empty directive.
  5925.   ///
  5926.   /// \param CollapsedNum Number of collapsed nested loops.
  5927.   ///
  5928.   explicit OMPGenericLoopDirective(unsigned CollapsedNum)
  5929.       : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop,
  5930.                          SourceLocation(), SourceLocation(), CollapsedNum) {}
  5931.  
  5932. public:
  5933.   /// Creates directive with a list of \p Clauses.
  5934.   ///
  5935.   /// \param C AST context.
  5936.   /// \param StartLoc Starting location of the directive kind.
  5937.   /// \param EndLoc Ending Location of the directive.
  5938.   /// \param CollapsedNum Number of collapsed loops.
  5939.   /// \param Clauses List of clauses.
  5940.   /// \param AssociatedStmt Statement, associated with the directive.
  5941.   /// \param Exprs Helper expressions for CodeGen.
  5942.   ///
  5943.   static OMPGenericLoopDirective *
  5944.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  5945.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  5946.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  5947.  
  5948.   /// Creates an empty directive with a place for \a NumClauses clauses.
  5949.   ///
  5950.   /// \param C AST context.
  5951.   /// \param NumClauses Number of clauses.
  5952.   /// \param CollapsedNum Number of collapsed nested loops.
  5953.   ///
  5954.   static OMPGenericLoopDirective *CreateEmpty(const ASTContext &C,
  5955.                                               unsigned NumClauses,
  5956.                                               unsigned CollapsedNum,
  5957.                                               EmptyShell);
  5958.  
  5959.   static bool classof(const Stmt *T) {
  5960.     return T->getStmtClass() == OMPGenericLoopDirectiveClass;
  5961.   }
  5962. };
  5963.  
  5964. /// This represents '#pragma omp teams loop' directive.
  5965. ///
  5966. /// \code
  5967. /// #pragma omp teams loop private(a,b) order(concurrent)
  5968. /// \endcode
  5969. /// In this example directive '#pragma omp teams loop' has
  5970. /// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
  5971. ///
  5972. class OMPTeamsGenericLoopDirective final : public OMPLoopDirective {
  5973.   friend class ASTStmtReader;
  5974.   friend class OMPExecutableDirective;
  5975.   /// Build directive with the given start and end location.
  5976.   ///
  5977.   /// \param StartLoc Starting location of the directive kind.
  5978.   /// \param EndLoc Ending location of the directive.
  5979.   /// \param CollapsedNum Number of collapsed nested loops.
  5980.   ///
  5981.   OMPTeamsGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
  5982.                                unsigned CollapsedNum)
  5983.       : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass,
  5984.                          llvm::omp::OMPD_teams_loop, StartLoc, EndLoc,
  5985.                          CollapsedNum) {}
  5986.  
  5987.   /// Build an empty directive.
  5988.   ///
  5989.   /// \param CollapsedNum Number of collapsed nested loops.
  5990.   ///
  5991.   explicit OMPTeamsGenericLoopDirective(unsigned CollapsedNum)
  5992.       : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass,
  5993.                          llvm::omp::OMPD_teams_loop, SourceLocation(),
  5994.                          SourceLocation(), CollapsedNum) {}
  5995.  
  5996. public:
  5997.   /// Creates directive with a list of \p Clauses.
  5998.   ///
  5999.   /// \param C AST context.
  6000.   /// \param StartLoc Starting location of the directive kind.
  6001.   /// \param EndLoc Ending Location of the directive.
  6002.   /// \param CollapsedNum Number of collapsed loops.
  6003.   /// \param Clauses List of clauses.
  6004.   /// \param AssociatedStmt Statement, associated with the directive.
  6005.   /// \param Exprs Helper expressions for CodeGen.
  6006.   ///
  6007.   static OMPTeamsGenericLoopDirective *
  6008.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  6009.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  6010.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  6011.  
  6012.   /// Creates an empty directive with the place
  6013.   /// for \a NumClauses clauses.
  6014.   ///
  6015.   /// \param C AST context.
  6016.   /// \param CollapsedNum Number of collapsed nested loops.
  6017.   /// \param NumClauses Number of clauses.
  6018.   ///
  6019.   static OMPTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C,
  6020.                                                    unsigned NumClauses,
  6021.                                                    unsigned CollapsedNum,
  6022.                                                    EmptyShell);
  6023.  
  6024.   static bool classof(const Stmt *T) {
  6025.     return T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass;
  6026.   }
  6027. };
  6028.  
  6029. /// This represents '#pragma omp target teams loop' directive.
  6030. ///
  6031. /// \code
  6032. /// #pragma omp target teams loop private(a,b) order(concurrent)
  6033. /// \endcode
  6034. /// In this example directive '#pragma omp target teams loop' has
  6035. /// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
  6036. ///
  6037. class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective {
  6038.   friend class ASTStmtReader;
  6039.   friend class OMPExecutableDirective;
  6040.   /// Build directive with the given start and end location.
  6041.   ///
  6042.   /// \param StartLoc Starting location of the directive kind.
  6043.   /// \param EndLoc Ending location of the directive.
  6044.   /// \param CollapsedNum Number of collapsed nested loops.
  6045.   ///
  6046.   OMPTargetTeamsGenericLoopDirective(SourceLocation StartLoc,
  6047.                                      SourceLocation EndLoc,
  6048.                                      unsigned CollapsedNum)
  6049.       : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass,
  6050.                          llvm::omp::OMPD_target_teams_loop, StartLoc, EndLoc,
  6051.                          CollapsedNum) {}
  6052.  
  6053.   /// Build an empty directive.
  6054.   ///
  6055.   /// \param CollapsedNum Number of collapsed nested loops.
  6056.   ///
  6057.   explicit OMPTargetTeamsGenericLoopDirective(unsigned CollapsedNum)
  6058.       : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass,
  6059.                          llvm::omp::OMPD_target_teams_loop, SourceLocation(),
  6060.                          SourceLocation(), CollapsedNum) {}
  6061.  
  6062. public:
  6063.   /// Creates directive with a list of \p Clauses.
  6064.   ///
  6065.   /// \param C AST context.
  6066.   /// \param StartLoc Starting location of the directive kind.
  6067.   /// \param EndLoc Ending Location of the directive.
  6068.   /// \param CollapsedNum Number of collapsed loops.
  6069.   /// \param Clauses List of clauses.
  6070.   /// \param AssociatedStmt Statement, associated with the directive.
  6071.   /// \param Exprs Helper expressions for CodeGen.
  6072.   ///
  6073.   static OMPTargetTeamsGenericLoopDirective *
  6074.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  6075.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  6076.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  6077.  
  6078.   /// Creates an empty directive with the place
  6079.   /// for \a NumClauses clauses.
  6080.   ///
  6081.   /// \param C AST context.
  6082.   /// \param CollapsedNum Number of collapsed nested loops.
  6083.   /// \param NumClauses Number of clauses.
  6084.   ///
  6085.   static OMPTargetTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C,
  6086.                                                          unsigned NumClauses,
  6087.                                                          unsigned CollapsedNum,
  6088.                                                          EmptyShell);
  6089.  
  6090.   static bool classof(const Stmt *T) {
  6091.     return T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass;
  6092.   }
  6093. };
  6094.  
  6095. /// This represents '#pragma omp parallel loop' directive.
  6096. ///
  6097. /// \code
  6098. /// #pragma omp parallel loop private(a,b) order(concurrent)
  6099. /// \endcode
  6100. /// In this example directive '#pragma omp parallel loop' has
  6101. /// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
  6102. ///
  6103. class OMPParallelGenericLoopDirective final : public OMPLoopDirective {
  6104.   friend class ASTStmtReader;
  6105.   friend class OMPExecutableDirective;
  6106.   /// Build directive with the given start and end location.
  6107.   ///
  6108.   /// \param StartLoc Starting location of the directive kind.
  6109.   /// \param EndLoc Ending location of the directive.
  6110.   /// \param CollapsedNum Number of collapsed nested loops.
  6111.   ///
  6112.   OMPParallelGenericLoopDirective(SourceLocation StartLoc,
  6113.                                   SourceLocation EndLoc, unsigned CollapsedNum)
  6114.       : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass,
  6115.                          llvm::omp::OMPD_parallel_loop, StartLoc, EndLoc,
  6116.                          CollapsedNum) {}
  6117.  
  6118.   /// Build an empty directive.
  6119.   ///
  6120.   /// \param CollapsedNum Number of collapsed nested loops.
  6121.   ///
  6122.   explicit OMPParallelGenericLoopDirective(unsigned CollapsedNum)
  6123.       : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass,
  6124.                          llvm::omp::OMPD_parallel_loop, SourceLocation(),
  6125.                          SourceLocation(), CollapsedNum) {}
  6126.  
  6127. public:
  6128.   /// Creates directive with a list of \p Clauses.
  6129.   ///
  6130.   /// \param C AST context.
  6131.   /// \param StartLoc Starting location of the directive kind.
  6132.   /// \param EndLoc Ending Location of the directive.
  6133.   /// \param CollapsedNum Number of collapsed loops.
  6134.   /// \param Clauses List of clauses.
  6135.   /// \param AssociatedStmt Statement, associated with the directive.
  6136.   /// \param Exprs Helper expressions for CodeGen.
  6137.   ///
  6138.   static OMPParallelGenericLoopDirective *
  6139.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  6140.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  6141.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  6142.  
  6143.   /// Creates an empty directive with the place
  6144.   /// for \a NumClauses clauses.
  6145.   ///
  6146.   /// \param C AST context.
  6147.   /// \param CollapsedNum Number of collapsed nested loops.
  6148.   /// \param NumClauses Number of clauses.
  6149.   ///
  6150.   static OMPParallelGenericLoopDirective *CreateEmpty(const ASTContext &C,
  6151.                                                       unsigned NumClauses,
  6152.                                                       unsigned CollapsedNum,
  6153.                                                       EmptyShell);
  6154.  
  6155.   static bool classof(const Stmt *T) {
  6156.     return T->getStmtClass() == OMPParallelGenericLoopDirectiveClass;
  6157.   }
  6158. };
  6159.  
  6160. /// This represents '#pragma omp target parallel loop' directive.
  6161. ///
  6162. /// \code
  6163. /// #pragma omp target parallel loop private(a,b) order(concurrent)
  6164. /// \endcode
  6165. /// In this example directive '#pragma omp target parallel loop' has
  6166. /// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
  6167. ///
  6168. class OMPTargetParallelGenericLoopDirective final : public OMPLoopDirective {
  6169.   friend class ASTStmtReader;
  6170.   friend class OMPExecutableDirective;
  6171.   /// Build directive with the given start and end location.
  6172.   ///
  6173.   /// \param StartLoc Starting location of the directive kind.
  6174.   /// \param EndLoc Ending location of the directive.
  6175.   /// \param CollapsedNum Number of collapsed nested loops.
  6176.   ///
  6177.   OMPTargetParallelGenericLoopDirective(SourceLocation StartLoc,
  6178.                                         SourceLocation EndLoc,
  6179.                                         unsigned CollapsedNum)
  6180.       : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass,
  6181.                          llvm::omp::OMPD_target_parallel_loop, StartLoc, EndLoc,
  6182.                          CollapsedNum) {}
  6183.  
  6184.   /// Build an empty directive.
  6185.   ///
  6186.   /// \param CollapsedNum Number of collapsed nested loops.
  6187.   ///
  6188.   explicit OMPTargetParallelGenericLoopDirective(unsigned CollapsedNum)
  6189.       : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass,
  6190.                          llvm::omp::OMPD_target_parallel_loop, SourceLocation(),
  6191.                          SourceLocation(), CollapsedNum) {}
  6192.  
  6193. public:
  6194.   /// Creates directive with a list of \p Clauses.
  6195.   ///
  6196.   /// \param C AST context.
  6197.   /// \param StartLoc Starting location of the directive kind.
  6198.   /// \param EndLoc Ending Location of the directive.
  6199.   /// \param CollapsedNum Number of collapsed loops.
  6200.   /// \param Clauses List of clauses.
  6201.   /// \param AssociatedStmt Statement, associated with the directive.
  6202.   /// \param Exprs Helper expressions for CodeGen.
  6203.   ///
  6204.   static OMPTargetParallelGenericLoopDirective *
  6205.   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
  6206.          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
  6207.          Stmt *AssociatedStmt, const HelperExprs &Exprs);
  6208.  
  6209.   /// Creates an empty directive with the place
  6210.   /// for \a NumClauses clauses.
  6211.   ///
  6212.   /// \param C AST context.
  6213.   /// \param CollapsedNum Number of collapsed nested loops.
  6214.   /// \param NumClauses Number of clauses.
  6215.   ///
  6216.   static OMPTargetParallelGenericLoopDirective *
  6217.   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
  6218.               EmptyShell);
  6219.  
  6220.   static bool classof(const Stmt *T) {
  6221.     return T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass;
  6222.   }
  6223. };
  6224.  
  6225. /// This represents '#pragma omp error' directive.
  6226. ///
  6227. /// \code
  6228. /// #pragma omp error
  6229. /// \endcode
  6230. class OMPErrorDirective final : public OMPExecutableDirective {
  6231.   friend class ASTStmtReader;
  6232.   friend class OMPExecutableDirective;
  6233.   /// Build directive with the given start and end location.
  6234.   ///
  6235.   /// \param StartLoc Starting location of the directive kind.
  6236.   /// \param EndLoc Ending location of the directive.
  6237.   ///
  6238.   OMPErrorDirective(SourceLocation StartLoc, SourceLocation EndLoc)
  6239.       : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error,
  6240.                                StartLoc, EndLoc) {}
  6241.   /// Build an empty directive.
  6242.   ///
  6243.   explicit OMPErrorDirective()
  6244.       : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error,
  6245.                                SourceLocation(), SourceLocation()) {}
  6246.  
  6247. public:
  6248.   ///
  6249.   /// \param C AST context.
  6250.   /// \param StartLoc Starting location of the directive kind.
  6251.   /// \param EndLoc Ending Location of the directive.
  6252.   /// \param Clauses List of clauses.
  6253.   ///
  6254.   static OMPErrorDirective *Create(const ASTContext &C, SourceLocation StartLoc,
  6255.                                    SourceLocation EndLoc,
  6256.                                    ArrayRef<OMPClause *> Clauses);
  6257.  
  6258.   /// Creates an empty directive.
  6259.   ///
  6260.   /// \param C AST context.
  6261.   ///
  6262.   static OMPErrorDirective *CreateEmpty(const ASTContext &C,
  6263.                                         unsigned NumClauses, EmptyShell);
  6264.  
  6265.   static bool classof(const Stmt *T) {
  6266.     return T->getStmtClass() == OMPErrorDirectiveClass;
  6267.   }
  6268. };
  6269. } // end namespace clang
  6270.  
  6271. #endif
  6272.