10b57cec5SDimitry Andric //===- StmtOpenMP.h - Classes for OpenMP directives  ------------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric /// \file
90b57cec5SDimitry Andric /// This file defines OpenMP AST classes for executable directives and
100b57cec5SDimitry Andric /// clauses.
110b57cec5SDimitry Andric ///
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #ifndef LLVM_CLANG_AST_STMTOPENMP_H
150b57cec5SDimitry Andric #define LLVM_CLANG_AST_STMTOPENMP_H
160b57cec5SDimitry Andric 
17e8d8bef9SDimitry Andric #include "clang/AST/ASTContext.h"
180b57cec5SDimitry Andric #include "clang/AST/Expr.h"
190b57cec5SDimitry Andric #include "clang/AST/OpenMPClause.h"
200b57cec5SDimitry Andric #include "clang/AST/Stmt.h"
21a7dea167SDimitry Andric #include "clang/AST/StmtCXX.h"
220b57cec5SDimitry Andric #include "clang/Basic/OpenMPKinds.h"
230b57cec5SDimitry Andric #include "clang/Basic/SourceLocation.h"
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric namespace clang {
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
280b57cec5SDimitry Andric // AST classes for directives.
290b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
300b57cec5SDimitry Andric 
31fe6060f1SDimitry Andric /// Representation of an OpenMP canonical loop.
32fe6060f1SDimitry Andric ///
33fe6060f1SDimitry Andric /// OpenMP 1.0 C/C++, section 2.4.1 for Construct; canonical-shape
34fe6060f1SDimitry Andric /// OpenMP 2.0 C/C++, section 2.4.1 for Construct; canonical-shape
35fe6060f1SDimitry Andric /// OpenMP 2.5, section 2.5.1 Loop Construct; canonical form
36fe6060f1SDimitry Andric /// OpenMP 3.1, section 2.5.1 Loop Construct; canonical form
37fe6060f1SDimitry Andric /// OpenMP 4.0, section 2.6 Canonical Loop Form
38fe6060f1SDimitry Andric /// OpenMP 4.5, section 2.6 Canonical Loop Form
39fe6060f1SDimitry Andric /// OpenMP 5.0, section 2.9.1 Canonical Loop Form
40fe6060f1SDimitry Andric /// OpenMP 5.1, section 2.11.1 Canonical Loop Nest Form
41fe6060f1SDimitry Andric ///
42fe6060f1SDimitry Andric /// An OpenMP canonical loop is a for-statement or range-based for-statement
43fe6060f1SDimitry Andric /// with additional requirements that ensure that the number of iterations is
44fe6060f1SDimitry Andric /// known before entering the loop and allow skipping to an arbitrary iteration.
45fe6060f1SDimitry Andric /// The OMPCanonicalLoop AST node wraps a ForStmt or CXXForRangeStmt that is
46fe6060f1SDimitry Andric /// known to fulfill OpenMP's canonical loop requirements because of being
47fe6060f1SDimitry Andric /// associated to an OMPLoopBasedDirective. That is, the general structure is:
48fe6060f1SDimitry Andric ///
49fe6060f1SDimitry Andric ///  OMPLoopBasedDirective
50fe6060f1SDimitry Andric /// [`- CapturedStmt   ]
51fe6060f1SDimitry Andric /// [   `- CapturedDecl]
52fe6060f1SDimitry Andric ///        ` OMPCanonicalLoop
53fe6060f1SDimitry Andric ///          `- ForStmt/CXXForRangeStmt
54fe6060f1SDimitry Andric ///             `- Stmt
55fe6060f1SDimitry Andric ///
56fe6060f1SDimitry Andric /// One or multiple CapturedStmt/CapturedDecl pairs may be inserted by some
57fe6060f1SDimitry Andric /// directives such as OMPParallelForDirective, but others do not need them
58fe6060f1SDimitry Andric /// (such as OMPTileDirective). In  The OMPCanonicalLoop and
59fe6060f1SDimitry Andric /// ForStmt/CXXForRangeStmt pair is repeated for loop associated with the
60fe6060f1SDimitry Andric /// directive. A OMPCanonicalLoop must not appear in the AST unless associated
61fe6060f1SDimitry Andric /// with a OMPLoopBasedDirective. In an imperfectly nested loop nest, the
62fe6060f1SDimitry Andric /// OMPCanonicalLoop may also be wrapped in a CompoundStmt:
63fe6060f1SDimitry Andric ///
64fe6060f1SDimitry Andric /// [...]
65fe6060f1SDimitry Andric ///  ` OMPCanonicalLoop
66fe6060f1SDimitry Andric ///    `- ForStmt/CXXForRangeStmt
67fe6060f1SDimitry Andric ///       `- CompoundStmt
68fe6060f1SDimitry Andric ///          |- Leading in-between code (if any)
69fe6060f1SDimitry Andric ///          |- OMPCanonicalLoop
70fe6060f1SDimitry Andric ///          |  `- ForStmt/CXXForRangeStmt
71fe6060f1SDimitry Andric ///          |     `- ...
72fe6060f1SDimitry Andric ///          `- Trailing in-between code (if any)
73fe6060f1SDimitry Andric ///
74fe6060f1SDimitry Andric /// The leading/trailing in-between code must not itself be a OMPCanonicalLoop
75fe6060f1SDimitry Andric /// to avoid confusion which loop belongs to the nesting.
76fe6060f1SDimitry Andric ///
77fe6060f1SDimitry Andric /// There are three different kinds of iteration variables for different
78fe6060f1SDimitry Andric /// purposes:
79fe6060f1SDimitry Andric /// * Loop user variable: The user-accessible variable with different value for
80fe6060f1SDimitry Andric ///   each iteration.
81fe6060f1SDimitry Andric /// * Loop iteration variable: The variable used to identify a loop iteration;
82fe6060f1SDimitry Andric ///   for range-based for-statement, this is the hidden iterator '__begin'. For
83fe6060f1SDimitry Andric ///   other loops, it is identical to the loop user variable. Must be a
84fe6060f1SDimitry Andric ///   random-access iterator, pointer or integer type.
85fe6060f1SDimitry Andric /// * Logical iteration counter: Normalized loop counter starting at 0 and
86fe6060f1SDimitry Andric ///   incrementing by one at each iteration. Allows abstracting over the type
87fe6060f1SDimitry Andric ///   of the loop iteration variable and is always an unsigned integer type
88fe6060f1SDimitry Andric ///   appropriate to represent the range of the loop iteration variable. Its
89fe6060f1SDimitry Andric ///   value corresponds to the logical iteration number in the OpenMP
90fe6060f1SDimitry Andric ///   specification.
91fe6060f1SDimitry Andric ///
92fe6060f1SDimitry Andric /// This AST node provides two captured statements:
93fe6060f1SDimitry Andric /// * The distance function which computes the number of iterations.
94fe6060f1SDimitry Andric /// * The loop user variable function that computes the loop user variable when
95fe6060f1SDimitry Andric ///   given a logical iteration number.
96fe6060f1SDimitry Andric ///
97fe6060f1SDimitry Andric /// These captured statements provide the link between C/C++ semantics and the
98fe6060f1SDimitry Andric /// logical iteration counters used by the OpenMPIRBuilder which is
99fe6060f1SDimitry Andric /// language-agnostic and therefore does not know e.g. how to advance a
100fe6060f1SDimitry Andric /// random-access iterator. The OpenMPIRBuilder will use this information to
101fe6060f1SDimitry Andric /// apply simd, workshare-loop, distribute, taskloop and loop directives to the
102fe6060f1SDimitry Andric /// loop. For compatibility with the non-OpenMPIRBuilder codegen path, an
103fe6060f1SDimitry Andric /// OMPCanonicalLoop can itself also be wrapped into the CapturedStmts of an
104fe6060f1SDimitry Andric /// OMPLoopDirective and skipped when searching for the associated syntactical
105fe6060f1SDimitry Andric /// loop.
106fe6060f1SDimitry Andric ///
107fe6060f1SDimitry Andric /// Example:
108fe6060f1SDimitry Andric /// <code>
109fe6060f1SDimitry Andric ///   std::vector<std::string> Container{1,2,3};
110fe6060f1SDimitry Andric ///   for (std::string Str : Container)
111fe6060f1SDimitry Andric ///      Body(Str);
112fe6060f1SDimitry Andric /// </code>
113fe6060f1SDimitry Andric /// which is syntactic sugar for approximately:
114fe6060f1SDimitry Andric /// <code>
115fe6060f1SDimitry Andric ///   auto &&__range = Container;
116fe6060f1SDimitry Andric ///   auto __begin = std::begin(__range);
117fe6060f1SDimitry Andric ///   auto __end = std::end(__range);
118fe6060f1SDimitry Andric ///   for (; __begin != __end; ++__begin) {
119fe6060f1SDimitry Andric ///     std::String Str = *__begin;
120fe6060f1SDimitry Andric ///     Body(Str);
121fe6060f1SDimitry Andric ///   }
122fe6060f1SDimitry Andric /// </code>
123fe6060f1SDimitry Andric /// In this example, the loop user variable is `Str`, the loop iteration
124fe6060f1SDimitry Andric /// variable is `__begin` of type `std::vector<std::string>::iterator` and the
125fe6060f1SDimitry Andric /// logical iteration number type is `size_t` (unsigned version of
126fe6060f1SDimitry Andric /// `std::vector<std::string>::iterator::difference_type` aka `ptrdiff_t`).
127fe6060f1SDimitry Andric /// Therefore, the distance function will be
128fe6060f1SDimitry Andric /// <code>
129fe6060f1SDimitry Andric ///   [&](size_t &Result) { Result = __end - __begin; }
130fe6060f1SDimitry Andric /// </code>
131fe6060f1SDimitry Andric /// and the loop variable function is
132fe6060f1SDimitry Andric /// <code>
133fe6060f1SDimitry Andric ///   [&,__begin](std::vector<std::string>::iterator &Result, size_t Logical) {
134fe6060f1SDimitry Andric ///     Result = __begin + Logical;
135fe6060f1SDimitry Andric ///   }
136fe6060f1SDimitry Andric /// </code>
137fe6060f1SDimitry Andric /// The variable `__begin`, aka the loop iteration variable, is captured by
138fe6060f1SDimitry Andric /// value because it is modified in the loop body, but both functions require
139fe6060f1SDimitry Andric /// the initial value. The OpenMP specification explicitly leaves unspecified
140fe6060f1SDimitry Andric /// when the loop expressions are evaluated such that a capture by reference is
141fe6060f1SDimitry Andric /// sufficient.
142fe6060f1SDimitry Andric class OMPCanonicalLoop : public Stmt {
143fe6060f1SDimitry Andric   friend class ASTStmtReader;
144fe6060f1SDimitry Andric   friend class ASTStmtWriter;
145fe6060f1SDimitry Andric 
146fe6060f1SDimitry Andric   /// Children of this AST node.
147fe6060f1SDimitry Andric   enum {
148fe6060f1SDimitry Andric     LOOP_STMT,
149fe6060f1SDimitry Andric     DISTANCE_FUNC,
150fe6060f1SDimitry Andric     LOOPVAR_FUNC,
151fe6060f1SDimitry Andric     LOOPVAR_REF,
152fe6060f1SDimitry Andric     LastSubStmt = LOOPVAR_REF
153fe6060f1SDimitry Andric   };
154fe6060f1SDimitry Andric 
155fe6060f1SDimitry Andric private:
156fe6060f1SDimitry Andric   /// This AST node's children.
157fe6060f1SDimitry Andric   Stmt *SubStmts[LastSubStmt + 1] = {};
158fe6060f1SDimitry Andric 
OMPCanonicalLoop()159fe6060f1SDimitry Andric   OMPCanonicalLoop() : Stmt(StmtClass::OMPCanonicalLoopClass) {}
160fe6060f1SDimitry Andric 
161fe6060f1SDimitry Andric public:
162fe6060f1SDimitry Andric   /// Create a new OMPCanonicalLoop.
create(const ASTContext & Ctx,Stmt * LoopStmt,CapturedStmt * DistanceFunc,CapturedStmt * LoopVarFunc,DeclRefExpr * LoopVarRef)163fe6060f1SDimitry Andric   static OMPCanonicalLoop *create(const ASTContext &Ctx, Stmt *LoopStmt,
164fe6060f1SDimitry Andric                                   CapturedStmt *DistanceFunc,
165fe6060f1SDimitry Andric                                   CapturedStmt *LoopVarFunc,
166fe6060f1SDimitry Andric                                   DeclRefExpr *LoopVarRef) {
167fe6060f1SDimitry Andric     OMPCanonicalLoop *S = new (Ctx) OMPCanonicalLoop();
168fe6060f1SDimitry Andric     S->setLoopStmt(LoopStmt);
169fe6060f1SDimitry Andric     S->setDistanceFunc(DistanceFunc);
170fe6060f1SDimitry Andric     S->setLoopVarFunc(LoopVarFunc);
171fe6060f1SDimitry Andric     S->setLoopVarRef(LoopVarRef);
172fe6060f1SDimitry Andric     return S;
173fe6060f1SDimitry Andric   }
174fe6060f1SDimitry Andric 
175fe6060f1SDimitry Andric   /// Create an empty OMPCanonicalLoop for deserialization.
createEmpty(const ASTContext & Ctx)176fe6060f1SDimitry Andric   static OMPCanonicalLoop *createEmpty(const ASTContext &Ctx) {
177fe6060f1SDimitry Andric     return new (Ctx) OMPCanonicalLoop();
178fe6060f1SDimitry Andric   }
179fe6060f1SDimitry Andric 
classof(const Stmt * S)180fe6060f1SDimitry Andric   static bool classof(const Stmt *S) {
181fe6060f1SDimitry Andric     return S->getStmtClass() == StmtClass::OMPCanonicalLoopClass;
182fe6060f1SDimitry Andric   }
183fe6060f1SDimitry Andric 
getBeginLoc()184fe6060f1SDimitry Andric   SourceLocation getBeginLoc() const { return getLoopStmt()->getBeginLoc(); }
getEndLoc()185fe6060f1SDimitry Andric   SourceLocation getEndLoc() const { return getLoopStmt()->getEndLoc(); }
186fe6060f1SDimitry Andric 
187fe6060f1SDimitry Andric   /// Return this AST node's children.
188fe6060f1SDimitry Andric   /// @{
children()189fe6060f1SDimitry Andric   child_range children() {
190fe6060f1SDimitry Andric     return child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1);
191fe6060f1SDimitry Andric   }
children()192fe6060f1SDimitry Andric   const_child_range children() const {
193fe6060f1SDimitry Andric     return const_child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1);
194fe6060f1SDimitry Andric   }
195fe6060f1SDimitry Andric   /// @}
196fe6060f1SDimitry Andric 
197fe6060f1SDimitry Andric   /// The wrapped syntactic loop statement (ForStmt or CXXForRangeStmt).
198fe6060f1SDimitry Andric   /// @{
getLoopStmt()199fe6060f1SDimitry Andric   Stmt *getLoopStmt() { return SubStmts[LOOP_STMT]; }
getLoopStmt()200fe6060f1SDimitry Andric   const Stmt *getLoopStmt() const { return SubStmts[LOOP_STMT]; }
setLoopStmt(Stmt * S)201fe6060f1SDimitry Andric   void setLoopStmt(Stmt *S) {
202fe6060f1SDimitry Andric     assert((isa<ForStmt>(S) || isa<CXXForRangeStmt>(S)) &&
203fe6060f1SDimitry Andric            "Canonical loop must be a for loop (range-based or otherwise)");
204fe6060f1SDimitry Andric     SubStmts[LOOP_STMT] = S;
205fe6060f1SDimitry Andric   }
206fe6060f1SDimitry Andric   /// @}
207fe6060f1SDimitry Andric 
208fe6060f1SDimitry Andric   /// The function that computes the number of loop iterations. Can be evaluated
209fe6060f1SDimitry Andric   /// before entering the loop but after the syntactical loop's init
210fe6060f1SDimitry Andric   /// statement(s).
211fe6060f1SDimitry Andric   ///
212fe6060f1SDimitry Andric   /// Function signature: void(LogicalTy &Result)
213fe6060f1SDimitry Andric   /// Any values necessary to compute the distance are captures of the closure.
214fe6060f1SDimitry Andric   /// @{
getDistanceFunc()215fe6060f1SDimitry Andric   CapturedStmt *getDistanceFunc() {
216fe6060f1SDimitry Andric     return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]);
217fe6060f1SDimitry Andric   }
getDistanceFunc()218fe6060f1SDimitry Andric   const CapturedStmt *getDistanceFunc() const {
219fe6060f1SDimitry Andric     return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]);
220fe6060f1SDimitry Andric   }
setDistanceFunc(CapturedStmt * S)221fe6060f1SDimitry Andric   void setDistanceFunc(CapturedStmt *S) {
222fe6060f1SDimitry Andric     assert(S && "Expected non-null captured statement");
223fe6060f1SDimitry Andric     SubStmts[DISTANCE_FUNC] = S;
224fe6060f1SDimitry Andric   }
225fe6060f1SDimitry Andric   /// @}
226fe6060f1SDimitry Andric 
227fe6060f1SDimitry Andric   /// The function that computes the loop user variable from a logical iteration
228fe6060f1SDimitry Andric   /// counter. Can be evaluated as first statement in the loop.
229fe6060f1SDimitry Andric   ///
230fe6060f1SDimitry Andric   /// Function signature: void(LoopVarTy &Result, LogicalTy Number)
231fe6060f1SDimitry Andric   /// Any other values required to compute the loop user variable (such as start
232fe6060f1SDimitry Andric   /// value, step size) are captured by the closure. In particular, the initial
233fe6060f1SDimitry Andric   /// value of loop iteration variable is captured by value to be unaffected by
234fe6060f1SDimitry Andric   /// previous iterations.
235fe6060f1SDimitry Andric   /// @{
getLoopVarFunc()236fe6060f1SDimitry Andric   CapturedStmt *getLoopVarFunc() {
237fe6060f1SDimitry Andric     return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]);
238fe6060f1SDimitry Andric   }
getLoopVarFunc()239fe6060f1SDimitry Andric   const CapturedStmt *getLoopVarFunc() const {
240fe6060f1SDimitry Andric     return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]);
241fe6060f1SDimitry Andric   }
setLoopVarFunc(CapturedStmt * S)242fe6060f1SDimitry Andric   void setLoopVarFunc(CapturedStmt *S) {
243fe6060f1SDimitry Andric     assert(S && "Expected non-null captured statement");
244fe6060f1SDimitry Andric     SubStmts[LOOPVAR_FUNC] = S;
245fe6060f1SDimitry Andric   }
246fe6060f1SDimitry Andric   /// @}
247fe6060f1SDimitry Andric 
248fe6060f1SDimitry Andric   /// Reference to the loop user variable as accessed in the loop body.
249fe6060f1SDimitry Andric   /// @{
getLoopVarRef()250fe6060f1SDimitry Andric   DeclRefExpr *getLoopVarRef() {
251fe6060f1SDimitry Andric     return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]);
252fe6060f1SDimitry Andric   }
getLoopVarRef()253fe6060f1SDimitry Andric   const DeclRefExpr *getLoopVarRef() const {
254fe6060f1SDimitry Andric     return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]);
255fe6060f1SDimitry Andric   }
setLoopVarRef(DeclRefExpr * E)256fe6060f1SDimitry Andric   void setLoopVarRef(DeclRefExpr *E) {
257fe6060f1SDimitry Andric     assert(E && "Expected non-null loop variable");
258fe6060f1SDimitry Andric     SubStmts[LOOPVAR_REF] = E;
259fe6060f1SDimitry Andric   }
260fe6060f1SDimitry Andric   /// @}
261fe6060f1SDimitry Andric };
262fe6060f1SDimitry Andric 
2630b57cec5SDimitry Andric /// This is a basic class for representing single OpenMP executable
2640b57cec5SDimitry Andric /// directive.
2650b57cec5SDimitry Andric ///
2660b57cec5SDimitry Andric class OMPExecutableDirective : public Stmt {
2670b57cec5SDimitry Andric   friend class ASTStmtReader;
268e8d8bef9SDimitry Andric   friend class ASTStmtWriter;
269e8d8bef9SDimitry Andric 
2700b57cec5SDimitry Andric   /// Kind of the directive.
271e8d8bef9SDimitry Andric   OpenMPDirectiveKind Kind = llvm::omp::OMPD_unknown;
2720b57cec5SDimitry Andric   /// Starting location of the directive (directive keyword).
2730b57cec5SDimitry Andric   SourceLocation StartLoc;
2740b57cec5SDimitry Andric   /// Ending location of the directive.
2750b57cec5SDimitry Andric   SourceLocation EndLoc;
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric   /// Get the clauses storage.
getClauses()2780b57cec5SDimitry Andric   MutableArrayRef<OMPClause *> getClauses() {
279e8d8bef9SDimitry Andric     if (!Data)
280bdd1243dSDimitry Andric       return std::nullopt;
281e8d8bef9SDimitry Andric     return Data->getClauses();
2820b57cec5SDimitry Andric   }
2830b57cec5SDimitry Andric 
2845f757f3fSDimitry Andric   /// Was this directive mapped from an another directive?
2855f757f3fSDimitry Andric   /// e.g. 1) omp loop bind(parallel) is mapped to OMPD_for
2865f757f3fSDimitry Andric   ///      2) omp loop bind(teams) is mapped to OMPD_distribute
2875f757f3fSDimitry Andric   ///      3) omp loop bind(thread) is mapped to OMPD_simd
2885f757f3fSDimitry Andric   /// It was necessary to note it down in the Directive because of
2895f757f3fSDimitry Andric   /// clang::TreeTransform::TransformOMPExecutableDirective() pass in
2905f757f3fSDimitry Andric   /// the frontend.
2915f757f3fSDimitry Andric   OpenMPDirectiveKind PrevMappedDirective = llvm::omp::OMPD_unknown;
2925f757f3fSDimitry Andric 
2930b57cec5SDimitry Andric protected:
294e8d8bef9SDimitry Andric   /// Data, associated with the directive.
295e8d8bef9SDimitry Andric   OMPChildren *Data = nullptr;
296e8d8bef9SDimitry Andric 
2970b57cec5SDimitry Andric   /// Build instance of directive of class \a K.
2980b57cec5SDimitry Andric   ///
2990b57cec5SDimitry Andric   /// \param SC Statement class.
3000b57cec5SDimitry Andric   /// \param K Kind of OpenMP directive.
3010b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive (directive keyword).
3020b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
3030b57cec5SDimitry Andric   ///
OMPExecutableDirective(StmtClass SC,OpenMPDirectiveKind K,SourceLocation StartLoc,SourceLocation EndLoc)304e8d8bef9SDimitry Andric   OMPExecutableDirective(StmtClass SC, OpenMPDirectiveKind K,
305e8d8bef9SDimitry Andric                          SourceLocation StartLoc, SourceLocation EndLoc)
3060b57cec5SDimitry Andric       : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
307e8d8bef9SDimitry Andric         EndLoc(std::move(EndLoc)) {}
3080b57cec5SDimitry Andric 
309e8d8bef9SDimitry Andric   template <typename T, typename... Params>
createDirective(const ASTContext & C,ArrayRef<OMPClause * > Clauses,Stmt * AssociatedStmt,unsigned NumChildren,Params &&...P)310e8d8bef9SDimitry Andric   static T *createDirective(const ASTContext &C, ArrayRef<OMPClause *> Clauses,
311e8d8bef9SDimitry Andric                             Stmt *AssociatedStmt, unsigned NumChildren,
312e8d8bef9SDimitry Andric                             Params &&... P) {
313e8d8bef9SDimitry Andric     void *Mem =
314e8d8bef9SDimitry Andric         C.Allocate(sizeof(T) + OMPChildren::size(Clauses.size(), AssociatedStmt,
315e8d8bef9SDimitry Andric                                                  NumChildren),
316e8d8bef9SDimitry Andric                    alignof(T));
3170b57cec5SDimitry Andric 
318e8d8bef9SDimitry Andric     auto *Data = OMPChildren::Create(reinterpret_cast<T *>(Mem) + 1, Clauses,
319e8d8bef9SDimitry Andric                                      AssociatedStmt, NumChildren);
320e8d8bef9SDimitry Andric     auto *Inst = new (Mem) T(std::forward<Params>(P)...);
321e8d8bef9SDimitry Andric     Inst->Data = Data;
322e8d8bef9SDimitry Andric     return Inst;
323e8d8bef9SDimitry Andric   }
324e8d8bef9SDimitry Andric 
325e8d8bef9SDimitry Andric   template <typename T, typename... Params>
createEmptyDirective(const ASTContext & C,unsigned NumClauses,bool HasAssociatedStmt,unsigned NumChildren,Params &&...P)326e8d8bef9SDimitry Andric   static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses,
327e8d8bef9SDimitry Andric                                  bool HasAssociatedStmt, unsigned NumChildren,
328e8d8bef9SDimitry Andric                                  Params &&... P) {
329e8d8bef9SDimitry Andric     void *Mem =
330e8d8bef9SDimitry Andric         C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt,
331e8d8bef9SDimitry Andric                                                  NumChildren),
332e8d8bef9SDimitry Andric                    alignof(T));
333e8d8bef9SDimitry Andric     auto *Data =
334e8d8bef9SDimitry Andric         OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses,
335e8d8bef9SDimitry Andric                                  HasAssociatedStmt, NumChildren);
336e8d8bef9SDimitry Andric     auto *Inst = new (Mem) T(std::forward<Params>(P)...);
337e8d8bef9SDimitry Andric     Inst->Data = Data;
338e8d8bef9SDimitry Andric     return Inst;
339e8d8bef9SDimitry Andric   }
340e8d8bef9SDimitry Andric 
341e8d8bef9SDimitry Andric   template <typename T>
342e8d8bef9SDimitry Andric   static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses,
343e8d8bef9SDimitry Andric                                  bool HasAssociatedStmt = false,
344e8d8bef9SDimitry Andric                                  unsigned NumChildren = 0) {
345e8d8bef9SDimitry Andric     void *Mem =
346e8d8bef9SDimitry Andric         C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt,
347e8d8bef9SDimitry Andric                                                  NumChildren),
348e8d8bef9SDimitry Andric                    alignof(T));
349e8d8bef9SDimitry Andric     auto *Data =
350e8d8bef9SDimitry Andric         OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses,
351e8d8bef9SDimitry Andric                                  HasAssociatedStmt, NumChildren);
352e8d8bef9SDimitry Andric     auto *Inst = new (Mem) T;
353e8d8bef9SDimitry Andric     Inst->Data = Data;
354e8d8bef9SDimitry Andric     return Inst;
3550b57cec5SDimitry Andric   }
3560b57cec5SDimitry Andric 
setMappedDirective(OpenMPDirectiveKind MappedDirective)3575f757f3fSDimitry Andric   void setMappedDirective(OpenMPDirectiveKind MappedDirective) {
3585f757f3fSDimitry Andric     PrevMappedDirective = MappedDirective;
3595f757f3fSDimitry Andric   }
3605f757f3fSDimitry Andric 
3610b57cec5SDimitry Andric public:
3620b57cec5SDimitry Andric   /// Iterates over expressions/statements used in the construct.
3630b57cec5SDimitry Andric   class used_clauses_child_iterator
3640b57cec5SDimitry Andric       : public llvm::iterator_adaptor_base<
3650b57cec5SDimitry Andric             used_clauses_child_iterator, ArrayRef<OMPClause *>::iterator,
3660b57cec5SDimitry Andric             std::forward_iterator_tag, Stmt *, ptrdiff_t, Stmt *, Stmt *> {
3670b57cec5SDimitry Andric     ArrayRef<OMPClause *>::iterator End;
3680b57cec5SDimitry Andric     OMPClause::child_iterator ChildI, ChildEnd;
3690b57cec5SDimitry Andric 
MoveToNext()3700b57cec5SDimitry Andric     void MoveToNext() {
3710b57cec5SDimitry Andric       if (ChildI != ChildEnd)
3720b57cec5SDimitry Andric         return;
3730b57cec5SDimitry Andric       while (this->I != End) {
3740b57cec5SDimitry Andric         ++this->I;
3750b57cec5SDimitry Andric         if (this->I != End) {
3760b57cec5SDimitry Andric           ChildI = (*this->I)->used_children().begin();
3770b57cec5SDimitry Andric           ChildEnd = (*this->I)->used_children().end();
3780b57cec5SDimitry Andric           if (ChildI != ChildEnd)
3790b57cec5SDimitry Andric             return;
3800b57cec5SDimitry Andric         }
3810b57cec5SDimitry Andric       }
3820b57cec5SDimitry Andric     }
3830b57cec5SDimitry Andric 
3840b57cec5SDimitry Andric   public:
used_clauses_child_iterator(ArrayRef<OMPClause * > Clauses)3850b57cec5SDimitry Andric     explicit used_clauses_child_iterator(ArrayRef<OMPClause *> Clauses)
3860b57cec5SDimitry Andric         : used_clauses_child_iterator::iterator_adaptor_base(Clauses.begin()),
3870b57cec5SDimitry Andric           End(Clauses.end()) {
3880b57cec5SDimitry Andric       if (this->I != End) {
3890b57cec5SDimitry Andric         ChildI = (*this->I)->used_children().begin();
3900b57cec5SDimitry Andric         ChildEnd = (*this->I)->used_children().end();
3910b57cec5SDimitry Andric         MoveToNext();
3920b57cec5SDimitry Andric       }
3930b57cec5SDimitry Andric     }
3940b57cec5SDimitry Andric     Stmt *operator*() const { return *ChildI; }
3950b57cec5SDimitry Andric     Stmt *operator->() const { return **this; }
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric     used_clauses_child_iterator &operator++() {
3980b57cec5SDimitry Andric       ++ChildI;
3990b57cec5SDimitry Andric       if (ChildI != ChildEnd)
4000b57cec5SDimitry Andric         return *this;
4010b57cec5SDimitry Andric       if (this->I != End) {
4020b57cec5SDimitry Andric         ++this->I;
4030b57cec5SDimitry Andric         if (this->I != End) {
4040b57cec5SDimitry Andric           ChildI = (*this->I)->used_children().begin();
4050b57cec5SDimitry Andric           ChildEnd = (*this->I)->used_children().end();
4060b57cec5SDimitry Andric         }
4070b57cec5SDimitry Andric       }
4080b57cec5SDimitry Andric       MoveToNext();
4090b57cec5SDimitry Andric       return *this;
4100b57cec5SDimitry Andric     }
4110b57cec5SDimitry Andric   };
4120b57cec5SDimitry Andric 
4130b57cec5SDimitry Andric   static llvm::iterator_range<used_clauses_child_iterator>
used_clauses_children(ArrayRef<OMPClause * > Clauses)4140b57cec5SDimitry Andric   used_clauses_children(ArrayRef<OMPClause *> Clauses) {
415bdd1243dSDimitry Andric     return {
416bdd1243dSDimitry Andric         used_clauses_child_iterator(Clauses),
417bdd1243dSDimitry Andric         used_clauses_child_iterator(llvm::ArrayRef(Clauses.end(), (size_t)0))};
4180b57cec5SDimitry Andric   }
4190b57cec5SDimitry Andric 
4200b57cec5SDimitry Andric   /// Iterates over a filtered subrange of clauses applied to a
4210b57cec5SDimitry Andric   /// directive.
4220b57cec5SDimitry Andric   ///
4230b57cec5SDimitry Andric   /// This iterator visits only clauses of type SpecificClause.
4240b57cec5SDimitry Andric   template <typename SpecificClause>
4250b57cec5SDimitry Andric   class specific_clause_iterator
4260b57cec5SDimitry Andric       : public llvm::iterator_adaptor_base<
4270b57cec5SDimitry Andric             specific_clause_iterator<SpecificClause>,
4280b57cec5SDimitry Andric             ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag,
4290b57cec5SDimitry Andric             const SpecificClause *, ptrdiff_t, const SpecificClause *,
4300b57cec5SDimitry Andric             const SpecificClause *> {
4310b57cec5SDimitry Andric     ArrayRef<OMPClause *>::const_iterator End;
4320b57cec5SDimitry Andric 
SkipToNextClause()4330b57cec5SDimitry Andric     void SkipToNextClause() {
4340b57cec5SDimitry Andric       while (this->I != End && !isa<SpecificClause>(*this->I))
4350b57cec5SDimitry Andric         ++this->I;
4360b57cec5SDimitry Andric     }
4370b57cec5SDimitry Andric 
4380b57cec5SDimitry Andric   public:
specific_clause_iterator(ArrayRef<OMPClause * > Clauses)4390b57cec5SDimitry Andric     explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses)
4400b57cec5SDimitry Andric         : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()),
4410b57cec5SDimitry Andric           End(Clauses.end()) {
4420b57cec5SDimitry Andric       SkipToNextClause();
4430b57cec5SDimitry Andric     }
4440b57cec5SDimitry Andric 
4450b57cec5SDimitry Andric     const SpecificClause *operator*() const {
4460b57cec5SDimitry Andric       return cast<SpecificClause>(*this->I);
4470b57cec5SDimitry Andric     }
4480b57cec5SDimitry Andric     const SpecificClause *operator->() const { return **this; }
4490b57cec5SDimitry Andric 
4500b57cec5SDimitry Andric     specific_clause_iterator &operator++() {
4510b57cec5SDimitry Andric       ++this->I;
4520b57cec5SDimitry Andric       SkipToNextClause();
4530b57cec5SDimitry Andric       return *this;
4540b57cec5SDimitry Andric     }
4550b57cec5SDimitry Andric   };
4560b57cec5SDimitry Andric 
4570b57cec5SDimitry Andric   template <typename SpecificClause>
4580b57cec5SDimitry Andric   static llvm::iterator_range<specific_clause_iterator<SpecificClause>>
getClausesOfKind(ArrayRef<OMPClause * > Clauses)4590b57cec5SDimitry Andric   getClausesOfKind(ArrayRef<OMPClause *> Clauses) {
4600b57cec5SDimitry Andric     return {specific_clause_iterator<SpecificClause>(Clauses),
4610b57cec5SDimitry Andric             specific_clause_iterator<SpecificClause>(
462bdd1243dSDimitry Andric                 llvm::ArrayRef(Clauses.end(), (size_t)0))};
4630b57cec5SDimitry Andric   }
4640b57cec5SDimitry Andric 
4650b57cec5SDimitry Andric   template <typename SpecificClause>
4660b57cec5SDimitry Andric   llvm::iterator_range<specific_clause_iterator<SpecificClause>>
getClausesOfKind()4670b57cec5SDimitry Andric   getClausesOfKind() const {
4680b57cec5SDimitry Andric     return getClausesOfKind<SpecificClause>(clauses());
4690b57cec5SDimitry Andric   }
4700b57cec5SDimitry Andric 
4710b57cec5SDimitry Andric   /// Gets a single clause of the specified kind associated with the
4720b57cec5SDimitry Andric   /// current directive iff there is only one clause of this kind (and assertion
4730b57cec5SDimitry Andric   /// is fired if there is more than one clause is associated with the
4740b57cec5SDimitry Andric   /// directive). Returns nullptr if no clause of this kind is associated with
4750b57cec5SDimitry Andric   /// the directive.
4760b57cec5SDimitry Andric   template <typename SpecificClause>
getSingleClause(ArrayRef<OMPClause * > Clauses)477fe6060f1SDimitry Andric   static const SpecificClause *getSingleClause(ArrayRef<OMPClause *> Clauses) {
478fe6060f1SDimitry Andric     auto ClausesOfKind = getClausesOfKind<SpecificClause>(Clauses);
4790b57cec5SDimitry Andric 
480fe6060f1SDimitry Andric     if (ClausesOfKind.begin() != ClausesOfKind.end()) {
481fe6060f1SDimitry Andric       assert(std::next(ClausesOfKind.begin()) == ClausesOfKind.end() &&
4820b57cec5SDimitry Andric              "There are at least 2 clauses of the specified kind");
483fe6060f1SDimitry Andric       return *ClausesOfKind.begin();
4840b57cec5SDimitry Andric     }
4850b57cec5SDimitry Andric     return nullptr;
4860b57cec5SDimitry Andric   }
4870b57cec5SDimitry Andric 
488fe6060f1SDimitry Andric   template <typename SpecificClause>
getSingleClause()489fe6060f1SDimitry Andric   const SpecificClause *getSingleClause() const {
490fe6060f1SDimitry Andric     return getSingleClause<SpecificClause>(clauses());
491fe6060f1SDimitry Andric   }
492fe6060f1SDimitry Andric 
4930b57cec5SDimitry Andric   /// Returns true if the current directive has one or more clauses of a
4940b57cec5SDimitry Andric   /// specific kind.
4950b57cec5SDimitry Andric   template <typename SpecificClause>
hasClausesOfKind()4960b57cec5SDimitry Andric   bool hasClausesOfKind() const {
4970b57cec5SDimitry Andric     auto Clauses = getClausesOfKind<SpecificClause>();
4980b57cec5SDimitry Andric     return Clauses.begin() != Clauses.end();
4990b57cec5SDimitry Andric   }
5000b57cec5SDimitry Andric 
5010b57cec5SDimitry Andric   /// Returns starting location of directive kind.
getBeginLoc()5020b57cec5SDimitry Andric   SourceLocation getBeginLoc() const { return StartLoc; }
5030b57cec5SDimitry Andric   /// Returns ending location of directive.
getEndLoc()5040b57cec5SDimitry Andric   SourceLocation getEndLoc() const { return EndLoc; }
5050b57cec5SDimitry Andric 
5060b57cec5SDimitry Andric   /// Set starting location of directive kind.
5070b57cec5SDimitry Andric   ///
5080b57cec5SDimitry Andric   /// \param Loc New starting location of directive.
5090b57cec5SDimitry Andric   ///
setLocStart(SourceLocation Loc)5100b57cec5SDimitry Andric   void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
5110b57cec5SDimitry Andric   /// Set ending location of directive.
5120b57cec5SDimitry Andric   ///
5130b57cec5SDimitry Andric   /// \param Loc New ending location of directive.
5140b57cec5SDimitry Andric   ///
setLocEnd(SourceLocation Loc)5150b57cec5SDimitry Andric   void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
5160b57cec5SDimitry Andric 
5170b57cec5SDimitry Andric   /// Get number of clauses.
getNumClauses()518e8d8bef9SDimitry Andric   unsigned getNumClauses() const {
519e8d8bef9SDimitry Andric     if (!Data)
520e8d8bef9SDimitry Andric       return 0;
521e8d8bef9SDimitry Andric     return Data->getNumClauses();
522e8d8bef9SDimitry Andric   }
5230b57cec5SDimitry Andric 
5240b57cec5SDimitry Andric   /// Returns specified clause.
5250b57cec5SDimitry Andric   ///
526e8d8bef9SDimitry Andric   /// \param I Number of clause.
5270b57cec5SDimitry Andric   ///
getClause(unsigned I)528e8d8bef9SDimitry Andric   OMPClause *getClause(unsigned I) const { return clauses()[I]; }
5290b57cec5SDimitry Andric 
5300b57cec5SDimitry Andric   /// Returns true if directive has associated statement.
hasAssociatedStmt()531e8d8bef9SDimitry Andric   bool hasAssociatedStmt() const { return Data && Data->hasAssociatedStmt(); }
5320b57cec5SDimitry Andric 
5330b57cec5SDimitry Andric   /// Returns statement associated with the directive.
getAssociatedStmt()5340b57cec5SDimitry Andric   const Stmt *getAssociatedStmt() const {
535e8d8bef9SDimitry Andric     return const_cast<OMPExecutableDirective *>(this)->getAssociatedStmt();
5360b57cec5SDimitry Andric   }
getAssociatedStmt()5370b57cec5SDimitry Andric   Stmt *getAssociatedStmt() {
538e8d8bef9SDimitry Andric     assert(hasAssociatedStmt() &&
539e8d8bef9SDimitry Andric            "Expected directive with the associated statement.");
540e8d8bef9SDimitry Andric     return Data->getAssociatedStmt();
5410b57cec5SDimitry Andric   }
5420b57cec5SDimitry Andric 
5430b57cec5SDimitry Andric   /// Returns the captured statement associated with the
5440b57cec5SDimitry Andric   /// component region within the (combined) directive.
545e8d8bef9SDimitry Andric   ///
546e8d8bef9SDimitry Andric   /// \param RegionKind Component region kind.
getCapturedStmt(OpenMPDirectiveKind RegionKind)5470b57cec5SDimitry Andric   const CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const {
548e8d8bef9SDimitry Andric     assert(hasAssociatedStmt() &&
549e8d8bef9SDimitry Andric            "Expected directive with the associated statement.");
5500b57cec5SDimitry Andric     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5510b57cec5SDimitry Andric     getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
552e8d8bef9SDimitry Andric     return Data->getCapturedStmt(RegionKind, CaptureRegions);
5530b57cec5SDimitry Andric   }
5540b57cec5SDimitry Andric 
5550b57cec5SDimitry Andric   /// Get innermost captured statement for the construct.
getInnermostCapturedStmt()5560b57cec5SDimitry Andric   CapturedStmt *getInnermostCapturedStmt() {
557e8d8bef9SDimitry Andric     assert(hasAssociatedStmt() &&
558e8d8bef9SDimitry Andric            "Expected directive with the associated statement.");
5590b57cec5SDimitry Andric     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5600b57cec5SDimitry Andric     getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
561e8d8bef9SDimitry Andric     return Data->getInnermostCapturedStmt(CaptureRegions);
5620b57cec5SDimitry Andric   }
5630b57cec5SDimitry Andric 
getInnermostCapturedStmt()5640b57cec5SDimitry Andric   const CapturedStmt *getInnermostCapturedStmt() const {
5650b57cec5SDimitry Andric     return const_cast<OMPExecutableDirective *>(this)
5660b57cec5SDimitry Andric         ->getInnermostCapturedStmt();
5670b57cec5SDimitry Andric   }
5680b57cec5SDimitry Andric 
getDirectiveKind()5690b57cec5SDimitry Andric   OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
5700b57cec5SDimitry Andric 
classof(const Stmt * S)5710b57cec5SDimitry Andric   static bool classof(const Stmt *S) {
5720b57cec5SDimitry Andric     return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
5730b57cec5SDimitry Andric            S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
5740b57cec5SDimitry Andric   }
5750b57cec5SDimitry Andric 
children()5760b57cec5SDimitry Andric   child_range children() {
577e8d8bef9SDimitry Andric     if (!Data)
5780b57cec5SDimitry Andric       return child_range(child_iterator(), child_iterator());
579e8d8bef9SDimitry Andric     return Data->getAssociatedStmtAsRange();
5800b57cec5SDimitry Andric   }
5810b57cec5SDimitry Andric 
children()5820b57cec5SDimitry Andric   const_child_range children() const {
583e8d8bef9SDimitry Andric     return const_cast<OMPExecutableDirective *>(this)->children();
5840b57cec5SDimitry Andric   }
5850b57cec5SDimitry Andric 
clauses()5860b57cec5SDimitry Andric   ArrayRef<OMPClause *> clauses() const {
587e8d8bef9SDimitry Andric     if (!Data)
588bdd1243dSDimitry Andric       return std::nullopt;
589e8d8bef9SDimitry Andric     return Data->getClauses();
5900b57cec5SDimitry Andric   }
5910b57cec5SDimitry Andric 
5920b57cec5SDimitry Andric   /// Returns whether or not this is a Standalone directive.
5930b57cec5SDimitry Andric   ///
5940b57cec5SDimitry Andric   /// Stand-alone directives are executable directives
5950b57cec5SDimitry Andric   /// that have no associated user code.
5960b57cec5SDimitry Andric   bool isStandaloneDirective() const;
5970b57cec5SDimitry Andric 
5980b57cec5SDimitry Andric   /// Returns the AST node representing OpenMP structured-block of this
5990b57cec5SDimitry Andric   /// OpenMP executable directive,
6000b57cec5SDimitry Andric   /// Prerequisite: Executable Directive must not be Standalone directive.
getStructuredBlock()601e8d8bef9SDimitry Andric   const Stmt *getStructuredBlock() const {
602e8d8bef9SDimitry Andric     return const_cast<OMPExecutableDirective *>(this)->getStructuredBlock();
603e8d8bef9SDimitry Andric   }
604e8d8bef9SDimitry Andric   Stmt *getStructuredBlock();
6050b57cec5SDimitry Andric 
getRawStmt()606e8d8bef9SDimitry Andric   const Stmt *getRawStmt() const {
607e8d8bef9SDimitry Andric     return const_cast<OMPExecutableDirective *>(this)->getRawStmt();
608e8d8bef9SDimitry Andric   }
getRawStmt()609e8d8bef9SDimitry Andric   Stmt *getRawStmt() {
610e8d8bef9SDimitry Andric     assert(hasAssociatedStmt() &&
611e8d8bef9SDimitry Andric            "Expected directive with the associated statement.");
612e8d8bef9SDimitry Andric     return Data->getRawStmt();
6130b57cec5SDimitry Andric   }
6145f757f3fSDimitry Andric 
getMappedDirective()6155f757f3fSDimitry Andric   OpenMPDirectiveKind getMappedDirective() const { return PrevMappedDirective; }
6160b57cec5SDimitry Andric };
6170b57cec5SDimitry Andric 
6180b57cec5SDimitry Andric /// This represents '#pragma omp parallel' directive.
6190b57cec5SDimitry Andric ///
6200b57cec5SDimitry Andric /// \code
6210b57cec5SDimitry Andric /// #pragma omp parallel private(a,b) reduction(+: c,d)
6220b57cec5SDimitry Andric /// \endcode
6230b57cec5SDimitry Andric /// In this example directive '#pragma omp parallel' has clauses 'private'
6240b57cec5SDimitry Andric /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
6250b57cec5SDimitry Andric /// variables 'c' and 'd'.
6260b57cec5SDimitry Andric ///
6270b57cec5SDimitry Andric class OMPParallelDirective : public OMPExecutableDirective {
6280b57cec5SDimitry Andric   friend class ASTStmtReader;
629e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
6300b57cec5SDimitry Andric   /// true if the construct has inner cancel directive.
631e8d8bef9SDimitry Andric   bool HasCancel = false;
6320b57cec5SDimitry Andric 
6330b57cec5SDimitry Andric   /// Build directive with the given start and end location.
6340b57cec5SDimitry Andric   ///
6350b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive (directive keyword).
6360b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
6370b57cec5SDimitry Andric   ///
OMPParallelDirective(SourceLocation StartLoc,SourceLocation EndLoc)638e8d8bef9SDimitry Andric   OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc)
639e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPParallelDirectiveClass,
640e8d8bef9SDimitry Andric                                llvm::omp::OMPD_parallel, StartLoc, EndLoc) {}
6410b57cec5SDimitry Andric 
6420b57cec5SDimitry Andric   /// Build an empty directive.
6430b57cec5SDimitry Andric   ///
OMPParallelDirective()644e8d8bef9SDimitry Andric   explicit OMPParallelDirective()
645e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPParallelDirectiveClass,
646480093f4SDimitry Andric                                llvm::omp::OMPD_parallel, SourceLocation(),
647e8d8bef9SDimitry Andric                                SourceLocation()) {}
6480b57cec5SDimitry Andric 
6495ffd83dbSDimitry Andric   /// Sets special task reduction descriptor.
setTaskReductionRefExpr(Expr * E)650e8d8bef9SDimitry Andric   void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
6515ffd83dbSDimitry Andric 
6520b57cec5SDimitry Andric   /// Set cancel state.
setHasCancel(bool Has)6530b57cec5SDimitry Andric   void setHasCancel(bool Has) { HasCancel = Has; }
6540b57cec5SDimitry Andric 
6550b57cec5SDimitry Andric public:
6560b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
6570b57cec5SDimitry Andric   ///
6580b57cec5SDimitry Andric   /// \param C AST context.
6590b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
6600b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
6610b57cec5SDimitry Andric   /// \param Clauses List of clauses.
6620b57cec5SDimitry Andric   /// \param AssociatedStmt Statement associated with the directive.
6635ffd83dbSDimitry Andric   /// \param TaskRedRef Task reduction special reference expression to handle
6645ffd83dbSDimitry Andric   /// taskgroup descriptor.
6650b57cec5SDimitry Andric   /// \param HasCancel true if this directive has inner cancel directive.
6660b57cec5SDimitry Andric   ///
6670b57cec5SDimitry Andric   static OMPParallelDirective *
6680b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
6695ffd83dbSDimitry Andric          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
6705ffd83dbSDimitry Andric          bool HasCancel);
6710b57cec5SDimitry Andric 
6720b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a N clauses.
6730b57cec5SDimitry Andric   ///
6740b57cec5SDimitry Andric   /// \param C AST context.
6750b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
6760b57cec5SDimitry Andric   ///
6770b57cec5SDimitry Andric   static OMPParallelDirective *CreateEmpty(const ASTContext &C,
6780b57cec5SDimitry Andric                                            unsigned NumClauses, EmptyShell);
6790b57cec5SDimitry Andric 
6805ffd83dbSDimitry Andric   /// Returns special task reduction reference expression.
getTaskReductionRefExpr()681e8d8bef9SDimitry Andric   Expr *getTaskReductionRefExpr() {
682e8d8bef9SDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[0]);
683e8d8bef9SDimitry Andric   }
getTaskReductionRefExpr()684e8d8bef9SDimitry Andric   const Expr *getTaskReductionRefExpr() const {
685e8d8bef9SDimitry Andric     return const_cast<OMPParallelDirective *>(this)->getTaskReductionRefExpr();
686e8d8bef9SDimitry Andric   }
6875ffd83dbSDimitry Andric 
6880b57cec5SDimitry Andric   /// Return true if current directive has inner cancel directive.
hasCancel()6890b57cec5SDimitry Andric   bool hasCancel() const { return HasCancel; }
6900b57cec5SDimitry Andric 
classof(const Stmt * T)6910b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
6920b57cec5SDimitry Andric     return T->getStmtClass() == OMPParallelDirectiveClass;
6930b57cec5SDimitry Andric   }
6940b57cec5SDimitry Andric };
6950b57cec5SDimitry Andric 
696fe6060f1SDimitry Andric /// The base class for all loop-based directives, including loop transformation
697fe6060f1SDimitry Andric /// directives.
698fe6060f1SDimitry Andric class OMPLoopBasedDirective : public OMPExecutableDirective {
699fe6060f1SDimitry Andric   friend class ASTStmtReader;
700fe6060f1SDimitry Andric 
701fe6060f1SDimitry Andric protected:
702fe6060f1SDimitry Andric   /// Number of collapsed loops as specified by 'collapse' clause.
703fe6060f1SDimitry Andric   unsigned NumAssociatedLoops = 0;
704fe6060f1SDimitry Andric 
705fe6060f1SDimitry Andric   /// Build instance of loop directive of class \a Kind.
706fe6060f1SDimitry Andric   ///
707fe6060f1SDimitry Andric   /// \param SC Statement class.
708fe6060f1SDimitry Andric   /// \param Kind Kind of OpenMP directive.
709fe6060f1SDimitry Andric   /// \param StartLoc Starting location of the directive (directive keyword).
710fe6060f1SDimitry Andric   /// \param EndLoc Ending location of the directive.
711fe6060f1SDimitry Andric   /// \param NumAssociatedLoops Number of loops associated with the construct.
712fe6060f1SDimitry Andric   ///
OMPLoopBasedDirective(StmtClass SC,OpenMPDirectiveKind Kind,SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumAssociatedLoops)713fe6060f1SDimitry Andric   OMPLoopBasedDirective(StmtClass SC, OpenMPDirectiveKind Kind,
714fe6060f1SDimitry Andric                         SourceLocation StartLoc, SourceLocation EndLoc,
715fe6060f1SDimitry Andric                         unsigned NumAssociatedLoops)
716fe6060f1SDimitry Andric       : OMPExecutableDirective(SC, Kind, StartLoc, EndLoc),
717fe6060f1SDimitry Andric         NumAssociatedLoops(NumAssociatedLoops) {}
718fe6060f1SDimitry Andric 
719fe6060f1SDimitry Andric public:
720fe6060f1SDimitry Andric   /// The expressions built to support OpenMP loops in combined/composite
721fe6060f1SDimitry Andric   /// pragmas (e.g. pragma omp distribute parallel for)
722fe6060f1SDimitry Andric   struct DistCombinedHelperExprs {
723fe6060f1SDimitry Andric     /// DistributeLowerBound - used when composing 'omp distribute' with
724fe6060f1SDimitry Andric     /// 'omp for' in a same construct.
725fe6060f1SDimitry Andric     Expr *LB;
726fe6060f1SDimitry Andric     /// DistributeUpperBound - used when composing 'omp distribute' with
727fe6060f1SDimitry Andric     /// 'omp for' in a same construct.
728fe6060f1SDimitry Andric     Expr *UB;
729fe6060f1SDimitry Andric     /// DistributeEnsureUpperBound - used when composing 'omp distribute'
730fe6060f1SDimitry Andric     ///  with 'omp for' in a same construct, EUB depends on DistUB
731fe6060f1SDimitry Andric     Expr *EUB;
732fe6060f1SDimitry Andric     /// Distribute loop iteration variable init used when composing 'omp
733fe6060f1SDimitry Andric     /// distribute'
734fe6060f1SDimitry Andric     ///  with 'omp for' in a same construct
735fe6060f1SDimitry Andric     Expr *Init;
736fe6060f1SDimitry Andric     /// Distribute Loop condition used when composing 'omp distribute'
737fe6060f1SDimitry Andric     ///  with 'omp for' in a same construct
738fe6060f1SDimitry Andric     Expr *Cond;
739fe6060f1SDimitry Andric     /// Update of LowerBound for statically scheduled omp loops for
740fe6060f1SDimitry Andric     /// outer loop in combined constructs (e.g. 'distribute parallel for')
741fe6060f1SDimitry Andric     Expr *NLB;
742fe6060f1SDimitry Andric     /// Update of UpperBound for statically scheduled omp loops for
743fe6060f1SDimitry Andric     /// outer loop in combined constructs (e.g. 'distribute parallel for')
744fe6060f1SDimitry Andric     Expr *NUB;
745fe6060f1SDimitry Andric     /// Distribute Loop condition used when composing 'omp distribute'
746fe6060f1SDimitry Andric     ///  with 'omp for' in a same construct when schedule is chunked.
747fe6060f1SDimitry Andric     Expr *DistCond;
748fe6060f1SDimitry Andric     /// 'omp parallel for' loop condition used when composed with
749fe6060f1SDimitry Andric     /// 'omp distribute' in the same construct and when schedule is
750fe6060f1SDimitry Andric     /// chunked and the chunk size is 1.
751fe6060f1SDimitry Andric     Expr *ParForInDistCond;
752fe6060f1SDimitry Andric   };
753fe6060f1SDimitry Andric 
754fe6060f1SDimitry Andric   /// The expressions built for the OpenMP loop CodeGen for the
755fe6060f1SDimitry Andric   /// whole collapsed loop nest.
756fe6060f1SDimitry Andric   struct HelperExprs {
757fe6060f1SDimitry Andric     /// Loop iteration variable.
758fe6060f1SDimitry Andric     Expr *IterationVarRef;
759fe6060f1SDimitry Andric     /// Loop last iteration number.
760fe6060f1SDimitry Andric     Expr *LastIteration;
761fe6060f1SDimitry Andric     /// Loop number of iterations.
762fe6060f1SDimitry Andric     Expr *NumIterations;
763fe6060f1SDimitry Andric     /// Calculation of last iteration.
764fe6060f1SDimitry Andric     Expr *CalcLastIteration;
765fe6060f1SDimitry Andric     /// Loop pre-condition.
766fe6060f1SDimitry Andric     Expr *PreCond;
767fe6060f1SDimitry Andric     /// Loop condition.
768fe6060f1SDimitry Andric     Expr *Cond;
769fe6060f1SDimitry Andric     /// Loop iteration variable init.
770fe6060f1SDimitry Andric     Expr *Init;
771fe6060f1SDimitry Andric     /// Loop increment.
772fe6060f1SDimitry Andric     Expr *Inc;
773fe6060f1SDimitry Andric     /// IsLastIteration - local flag variable passed to runtime.
774fe6060f1SDimitry Andric     Expr *IL;
775fe6060f1SDimitry Andric     /// LowerBound - local variable passed to runtime.
776fe6060f1SDimitry Andric     Expr *LB;
777fe6060f1SDimitry Andric     /// UpperBound - local variable passed to runtime.
778fe6060f1SDimitry Andric     Expr *UB;
779fe6060f1SDimitry Andric     /// Stride - local variable passed to runtime.
780fe6060f1SDimitry Andric     Expr *ST;
781fe6060f1SDimitry Andric     /// EnsureUpperBound -- expression UB = min(UB, NumIterations).
782fe6060f1SDimitry Andric     Expr *EUB;
783fe6060f1SDimitry Andric     /// Update of LowerBound for statically scheduled 'omp for' loops.
784fe6060f1SDimitry Andric     Expr *NLB;
785fe6060f1SDimitry Andric     /// Update of UpperBound for statically scheduled 'omp for' loops.
786fe6060f1SDimitry Andric     Expr *NUB;
787fe6060f1SDimitry Andric     /// PreviousLowerBound - local variable passed to runtime in the
788fe6060f1SDimitry Andric     /// enclosing schedule or null if that does not apply.
789fe6060f1SDimitry Andric     Expr *PrevLB;
790fe6060f1SDimitry Andric     /// PreviousUpperBound - local variable passed to runtime in the
791fe6060f1SDimitry Andric     /// enclosing schedule or null if that does not apply.
792fe6060f1SDimitry Andric     Expr *PrevUB;
793fe6060f1SDimitry Andric     /// DistInc - increment expression for distribute loop when found
794fe6060f1SDimitry Andric     /// combined with a further loop level (e.g. in 'distribute parallel for')
795fe6060f1SDimitry Andric     /// expression IV = IV + ST
796fe6060f1SDimitry Andric     Expr *DistInc;
797fe6060f1SDimitry Andric     /// PrevEUB - expression similar to EUB but to be used when loop
798fe6060f1SDimitry Andric     /// scheduling uses PrevLB and PrevUB (e.g.  in 'distribute parallel for'
799fe6060f1SDimitry Andric     /// when ensuring that the UB is either the calculated UB by the runtime or
800fe6060f1SDimitry Andric     /// the end of the assigned distribute chunk)
801fe6060f1SDimitry Andric     /// expression UB = min (UB, PrevUB)
802fe6060f1SDimitry Andric     Expr *PrevEUB;
803fe6060f1SDimitry Andric     /// Counters Loop counters.
804fe6060f1SDimitry Andric     SmallVector<Expr *, 4> Counters;
805fe6060f1SDimitry Andric     /// PrivateCounters Loop counters.
806fe6060f1SDimitry Andric     SmallVector<Expr *, 4> PrivateCounters;
807fe6060f1SDimitry Andric     /// Expressions for loop counters inits for CodeGen.
808fe6060f1SDimitry Andric     SmallVector<Expr *, 4> Inits;
809fe6060f1SDimitry Andric     /// Expressions for loop counters update for CodeGen.
810fe6060f1SDimitry Andric     SmallVector<Expr *, 4> Updates;
811fe6060f1SDimitry Andric     /// Final loop counter values for GodeGen.
812fe6060f1SDimitry Andric     SmallVector<Expr *, 4> Finals;
813fe6060f1SDimitry Andric     /// List of counters required for the generation of the non-rectangular
814fe6060f1SDimitry Andric     /// loops.
815fe6060f1SDimitry Andric     SmallVector<Expr *, 4> DependentCounters;
816fe6060f1SDimitry Andric     /// List of initializers required for the generation of the non-rectangular
817fe6060f1SDimitry Andric     /// loops.
818fe6060f1SDimitry Andric     SmallVector<Expr *, 4> DependentInits;
819fe6060f1SDimitry Andric     /// List of final conditions required for the generation of the
820fe6060f1SDimitry Andric     /// non-rectangular loops.
821fe6060f1SDimitry Andric     SmallVector<Expr *, 4> FinalsConditions;
822fe6060f1SDimitry Andric     /// Init statement for all captured expressions.
823fe6060f1SDimitry Andric     Stmt *PreInits;
824fe6060f1SDimitry Andric 
825fe6060f1SDimitry Andric     /// Expressions used when combining OpenMP loop pragmas
826fe6060f1SDimitry Andric     DistCombinedHelperExprs DistCombinedFields;
827fe6060f1SDimitry Andric 
828fe6060f1SDimitry Andric     /// Check if all the expressions are built (does not check the
829fe6060f1SDimitry Andric     /// worksharing ones).
builtAllHelperExprs830fe6060f1SDimitry Andric     bool builtAll() {
831fe6060f1SDimitry Andric       return IterationVarRef != nullptr && LastIteration != nullptr &&
832fe6060f1SDimitry Andric              NumIterations != nullptr && PreCond != nullptr &&
833fe6060f1SDimitry Andric              Cond != nullptr && Init != nullptr && Inc != nullptr;
834fe6060f1SDimitry Andric     }
835fe6060f1SDimitry Andric 
836fe6060f1SDimitry Andric     /// Initialize all the fields to null.
837fe6060f1SDimitry Andric     /// \param Size Number of elements in the
838fe6060f1SDimitry Andric     /// counters/finals/updates/dependent_counters/dependent_inits/finals_conditions
839fe6060f1SDimitry Andric     /// arrays.
clearHelperExprs840fe6060f1SDimitry Andric     void clear(unsigned Size) {
841fe6060f1SDimitry Andric       IterationVarRef = nullptr;
842fe6060f1SDimitry Andric       LastIteration = nullptr;
843fe6060f1SDimitry Andric       CalcLastIteration = nullptr;
844fe6060f1SDimitry Andric       PreCond = nullptr;
845fe6060f1SDimitry Andric       Cond = nullptr;
846fe6060f1SDimitry Andric       Init = nullptr;
847fe6060f1SDimitry Andric       Inc = nullptr;
848fe6060f1SDimitry Andric       IL = nullptr;
849fe6060f1SDimitry Andric       LB = nullptr;
850fe6060f1SDimitry Andric       UB = nullptr;
851fe6060f1SDimitry Andric       ST = nullptr;
852fe6060f1SDimitry Andric       EUB = nullptr;
853fe6060f1SDimitry Andric       NLB = nullptr;
854fe6060f1SDimitry Andric       NUB = nullptr;
855fe6060f1SDimitry Andric       NumIterations = nullptr;
856fe6060f1SDimitry Andric       PrevLB = nullptr;
857fe6060f1SDimitry Andric       PrevUB = nullptr;
858fe6060f1SDimitry Andric       DistInc = nullptr;
859fe6060f1SDimitry Andric       PrevEUB = nullptr;
860fe6060f1SDimitry Andric       Counters.resize(Size);
861fe6060f1SDimitry Andric       PrivateCounters.resize(Size);
862fe6060f1SDimitry Andric       Inits.resize(Size);
863fe6060f1SDimitry Andric       Updates.resize(Size);
864fe6060f1SDimitry Andric       Finals.resize(Size);
865fe6060f1SDimitry Andric       DependentCounters.resize(Size);
866fe6060f1SDimitry Andric       DependentInits.resize(Size);
867fe6060f1SDimitry Andric       FinalsConditions.resize(Size);
868fe6060f1SDimitry Andric       for (unsigned I = 0; I < Size; ++I) {
869fe6060f1SDimitry Andric         Counters[I] = nullptr;
870fe6060f1SDimitry Andric         PrivateCounters[I] = nullptr;
871fe6060f1SDimitry Andric         Inits[I] = nullptr;
872fe6060f1SDimitry Andric         Updates[I] = nullptr;
873fe6060f1SDimitry Andric         Finals[I] = nullptr;
874fe6060f1SDimitry Andric         DependentCounters[I] = nullptr;
875fe6060f1SDimitry Andric         DependentInits[I] = nullptr;
876fe6060f1SDimitry Andric         FinalsConditions[I] = nullptr;
877fe6060f1SDimitry Andric       }
878fe6060f1SDimitry Andric       PreInits = nullptr;
879fe6060f1SDimitry Andric       DistCombinedFields.LB = nullptr;
880fe6060f1SDimitry Andric       DistCombinedFields.UB = nullptr;
881fe6060f1SDimitry Andric       DistCombinedFields.EUB = nullptr;
882fe6060f1SDimitry Andric       DistCombinedFields.Init = nullptr;
883fe6060f1SDimitry Andric       DistCombinedFields.Cond = nullptr;
884fe6060f1SDimitry Andric       DistCombinedFields.NLB = nullptr;
885fe6060f1SDimitry Andric       DistCombinedFields.NUB = nullptr;
886fe6060f1SDimitry Andric       DistCombinedFields.DistCond = nullptr;
887fe6060f1SDimitry Andric       DistCombinedFields.ParForInDistCond = nullptr;
888fe6060f1SDimitry Andric     }
889fe6060f1SDimitry Andric   };
890fe6060f1SDimitry Andric 
891fe6060f1SDimitry Andric   /// Get number of collapsed loops.
getLoopsNumber()892fe6060f1SDimitry Andric   unsigned getLoopsNumber() const { return NumAssociatedLoops; }
893fe6060f1SDimitry Andric 
894fe6060f1SDimitry Andric   /// Try to find the next loop sub-statement in the specified statement \p
895fe6060f1SDimitry Andric   /// CurStmt.
896fe6060f1SDimitry Andric   /// \param TryImperfectlyNestedLoops true, if we need to try to look for the
897fe6060f1SDimitry Andric   /// imperfectly nested loop.
898fe6060f1SDimitry Andric   static Stmt *tryToFindNextInnerLoop(Stmt *CurStmt,
899fe6060f1SDimitry Andric                                       bool TryImperfectlyNestedLoops);
tryToFindNextInnerLoop(const Stmt * CurStmt,bool TryImperfectlyNestedLoops)900fe6060f1SDimitry Andric   static const Stmt *tryToFindNextInnerLoop(const Stmt *CurStmt,
901fe6060f1SDimitry Andric                                             bool TryImperfectlyNestedLoops) {
902fe6060f1SDimitry Andric     return tryToFindNextInnerLoop(const_cast<Stmt *>(CurStmt),
903fe6060f1SDimitry Andric                                   TryImperfectlyNestedLoops);
904fe6060f1SDimitry Andric   }
905fe6060f1SDimitry Andric 
906fe6060f1SDimitry Andric   /// Calls the specified callback function for all the loops in \p CurStmt,
907fe6060f1SDimitry Andric   /// from the outermost to the innermost.
908349cc55cSDimitry Andric   static bool
909349cc55cSDimitry Andric   doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
910fe6060f1SDimitry Andric                 unsigned NumLoops,
911fe6060f1SDimitry Andric                 llvm::function_ref<bool(unsigned, Stmt *)> Callback,
912349cc55cSDimitry Andric                 llvm::function_ref<void(OMPLoopTransformationDirective *)>
913fe6060f1SDimitry Andric                     OnTransformationCallback);
914fe6060f1SDimitry Andric   static bool
doForAllLoops(const Stmt * CurStmt,bool TryImperfectlyNestedLoops,unsigned NumLoops,llvm::function_ref<bool (unsigned,const Stmt *)> Callback,llvm::function_ref<void (const OMPLoopTransformationDirective *)> OnTransformationCallback)915fe6060f1SDimitry Andric   doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
916fe6060f1SDimitry Andric                 unsigned NumLoops,
917fe6060f1SDimitry Andric                 llvm::function_ref<bool(unsigned, const Stmt *)> Callback,
918349cc55cSDimitry Andric                 llvm::function_ref<void(const OMPLoopTransformationDirective *)>
919fe6060f1SDimitry Andric                     OnTransformationCallback) {
920fe6060f1SDimitry Andric     auto &&NewCallback = [Callback](unsigned Cnt, Stmt *CurStmt) {
921fe6060f1SDimitry Andric       return Callback(Cnt, CurStmt);
922fe6060f1SDimitry Andric     };
923fe6060f1SDimitry Andric     auto &&NewTransformCb =
924349cc55cSDimitry Andric         [OnTransformationCallback](OMPLoopTransformationDirective *A) {
925fe6060f1SDimitry Andric           OnTransformationCallback(A);
926fe6060f1SDimitry Andric         };
927fe6060f1SDimitry Andric     return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
928fe6060f1SDimitry Andric                          NumLoops, NewCallback, NewTransformCb);
929fe6060f1SDimitry Andric   }
930fe6060f1SDimitry Andric 
931fe6060f1SDimitry Andric   /// Calls the specified callback function for all the loops in \p CurStmt,
932fe6060f1SDimitry Andric   /// from the outermost to the innermost.
933fe6060f1SDimitry Andric   static bool
doForAllLoops(Stmt * CurStmt,bool TryImperfectlyNestedLoops,unsigned NumLoops,llvm::function_ref<bool (unsigned,Stmt *)> Callback)934fe6060f1SDimitry Andric   doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
935fe6060f1SDimitry Andric                 unsigned NumLoops,
936fe6060f1SDimitry Andric                 llvm::function_ref<bool(unsigned, Stmt *)> Callback) {
937349cc55cSDimitry Andric     auto &&TransformCb = [](OMPLoopTransformationDirective *) {};
938fe6060f1SDimitry Andric     return doForAllLoops(CurStmt, TryImperfectlyNestedLoops, NumLoops, Callback,
939fe6060f1SDimitry Andric                          TransformCb);
940fe6060f1SDimitry Andric   }
941fe6060f1SDimitry Andric   static bool
doForAllLoops(const Stmt * CurStmt,bool TryImperfectlyNestedLoops,unsigned NumLoops,llvm::function_ref<bool (unsigned,const Stmt *)> Callback)942fe6060f1SDimitry Andric   doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
943fe6060f1SDimitry Andric                 unsigned NumLoops,
944fe6060f1SDimitry Andric                 llvm::function_ref<bool(unsigned, const Stmt *)> Callback) {
945fe6060f1SDimitry Andric     auto &&NewCallback = [Callback](unsigned Cnt, const Stmt *CurStmt) {
946fe6060f1SDimitry Andric       return Callback(Cnt, CurStmt);
947fe6060f1SDimitry Andric     };
948fe6060f1SDimitry Andric     return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
949fe6060f1SDimitry Andric                          NumLoops, NewCallback);
950fe6060f1SDimitry Andric   }
951fe6060f1SDimitry Andric 
952fe6060f1SDimitry Andric   /// Calls the specified callback function for all the loop bodies in \p
953fe6060f1SDimitry Andric   /// CurStmt, from the outermost loop to the innermost.
954fe6060f1SDimitry Andric   static void doForAllLoopsBodies(
955fe6060f1SDimitry Andric       Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops,
956fe6060f1SDimitry Andric       llvm::function_ref<void(unsigned, Stmt *, Stmt *)> Callback);
doForAllLoopsBodies(const Stmt * CurStmt,bool TryImperfectlyNestedLoops,unsigned NumLoops,llvm::function_ref<void (unsigned,const Stmt *,const Stmt *)> Callback)957fe6060f1SDimitry Andric   static void doForAllLoopsBodies(
958fe6060f1SDimitry Andric       const Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops,
959fe6060f1SDimitry Andric       llvm::function_ref<void(unsigned, const Stmt *, const Stmt *)> Callback) {
960fe6060f1SDimitry Andric     auto &&NewCallback = [Callback](unsigned Cnt, Stmt *Loop, Stmt *Body) {
961fe6060f1SDimitry Andric       Callback(Cnt, Loop, Body);
962fe6060f1SDimitry Andric     };
963fe6060f1SDimitry Andric     doForAllLoopsBodies(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
964fe6060f1SDimitry Andric                         NumLoops, NewCallback);
965fe6060f1SDimitry Andric   }
966fe6060f1SDimitry Andric 
classof(const Stmt * T)967fe6060f1SDimitry Andric   static bool classof(const Stmt *T) {
968fe6060f1SDimitry Andric     if (auto *D = dyn_cast<OMPExecutableDirective>(T))
969fe6060f1SDimitry Andric       return isOpenMPLoopDirective(D->getDirectiveKind());
970fe6060f1SDimitry Andric     return false;
971fe6060f1SDimitry Andric   }
972fe6060f1SDimitry Andric };
973fe6060f1SDimitry Andric 
974349cc55cSDimitry Andric /// The base class for all loop transformation directives.
975349cc55cSDimitry Andric class OMPLoopTransformationDirective : public OMPLoopBasedDirective {
976349cc55cSDimitry Andric   friend class ASTStmtReader;
977349cc55cSDimitry Andric 
978349cc55cSDimitry Andric   /// Number of loops generated by this loop transformation.
979349cc55cSDimitry Andric   unsigned NumGeneratedLoops = 0;
980349cc55cSDimitry Andric 
981349cc55cSDimitry Andric protected:
OMPLoopTransformationDirective(StmtClass SC,OpenMPDirectiveKind Kind,SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumAssociatedLoops)982349cc55cSDimitry Andric   explicit OMPLoopTransformationDirective(StmtClass SC,
983349cc55cSDimitry Andric                                           OpenMPDirectiveKind Kind,
984349cc55cSDimitry Andric                                           SourceLocation StartLoc,
985349cc55cSDimitry Andric                                           SourceLocation EndLoc,
986349cc55cSDimitry Andric                                           unsigned NumAssociatedLoops)
987349cc55cSDimitry Andric       : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, NumAssociatedLoops) {}
988349cc55cSDimitry Andric 
989349cc55cSDimitry Andric   /// Set the number of loops generated by this loop transformation.
setNumGeneratedLoops(unsigned Num)990349cc55cSDimitry Andric   void setNumGeneratedLoops(unsigned Num) { NumGeneratedLoops = Num; }
991349cc55cSDimitry Andric 
992349cc55cSDimitry Andric public:
993349cc55cSDimitry Andric   /// Return the number of associated (consumed) loops.
getNumAssociatedLoops()994349cc55cSDimitry Andric   unsigned getNumAssociatedLoops() const { return getLoopsNumber(); }
995349cc55cSDimitry Andric 
996349cc55cSDimitry Andric   /// Return the number of loops generated by this loop transformation.
getNumGeneratedLoops()9975f757f3fSDimitry Andric   unsigned getNumGeneratedLoops() const { return NumGeneratedLoops; }
998349cc55cSDimitry Andric 
999bdd1243dSDimitry Andric   /// Get the de-sugared statements after the loop transformation.
1000349cc55cSDimitry Andric   ///
1001349cc55cSDimitry Andric   /// Might be nullptr if either the directive generates no loops and is handled
1002349cc55cSDimitry Andric   /// directly in CodeGen, or resolving a template-dependence context is
1003349cc55cSDimitry Andric   /// required.
1004349cc55cSDimitry Andric   Stmt *getTransformedStmt() const;
1005349cc55cSDimitry Andric 
1006349cc55cSDimitry Andric   /// Return preinits statement.
1007349cc55cSDimitry Andric   Stmt *getPreInits() const;
1008349cc55cSDimitry Andric 
classof(const Stmt * T)1009349cc55cSDimitry Andric   static bool classof(const Stmt *T) {
1010349cc55cSDimitry Andric     return T->getStmtClass() == OMPTileDirectiveClass ||
1011349cc55cSDimitry Andric            T->getStmtClass() == OMPUnrollDirectiveClass;
1012349cc55cSDimitry Andric   }
1013349cc55cSDimitry Andric };
1014349cc55cSDimitry Andric 
10150b57cec5SDimitry Andric /// This is a common base class for loop directives ('omp simd', 'omp
10160b57cec5SDimitry Andric /// for', 'omp for simd' etc.). It is responsible for the loop code generation.
10170b57cec5SDimitry Andric ///
1018fe6060f1SDimitry Andric class OMPLoopDirective : public OMPLoopBasedDirective {
10190b57cec5SDimitry Andric   friend class ASTStmtReader;
10200b57cec5SDimitry Andric 
10210b57cec5SDimitry Andric   /// Offsets to the stored exprs.
10220b57cec5SDimitry Andric   /// This enumeration contains offsets to all the pointers to children
10230b57cec5SDimitry Andric   /// expressions stored in OMPLoopDirective.
10240b57cec5SDimitry Andric   /// The first 9 children are necessary for all the loop directives,
10250b57cec5SDimitry Andric   /// the next 8 are specific to the worksharing ones, and the next 11 are
10260b57cec5SDimitry Andric   /// used for combined constructs containing two pragmas associated to loops.
1027fe6060f1SDimitry Andric   /// After the fixed children, three arrays of length NumAssociatedLoops are
10280b57cec5SDimitry Andric   /// allocated: loop counters, their updates and final values.
10290b57cec5SDimitry Andric   /// PrevLowerBound and PrevUpperBound are used to communicate blocking
10300b57cec5SDimitry Andric   /// information in composite constructs which require loop blocking
10310b57cec5SDimitry Andric   /// DistInc is used to generate the increment expression for the distribute
10320b57cec5SDimitry Andric   /// loop when combined with a further nested loop
10330b57cec5SDimitry Andric   /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the
10340b57cec5SDimitry Andric   /// for loop when combined with a previous distribute loop in the same pragma
10350b57cec5SDimitry Andric   /// (e.g. 'distribute parallel for')
10360b57cec5SDimitry Andric   ///
10370b57cec5SDimitry Andric   enum {
1038e8d8bef9SDimitry Andric     IterationVariableOffset = 0,
1039e8d8bef9SDimitry Andric     LastIterationOffset = 1,
1040e8d8bef9SDimitry Andric     CalcLastIterationOffset = 2,
1041e8d8bef9SDimitry Andric     PreConditionOffset = 3,
1042e8d8bef9SDimitry Andric     CondOffset = 4,
1043e8d8bef9SDimitry Andric     InitOffset = 5,
1044e8d8bef9SDimitry Andric     IncOffset = 6,
1045e8d8bef9SDimitry Andric     PreInitsOffset = 7,
10460b57cec5SDimitry Andric     // The '...End' enumerators do not correspond to child expressions - they
10470b57cec5SDimitry Andric     // specify the offset to the end (and start of the following counters/
1048a7dea167SDimitry Andric     // updates/finals/dependent_counters/dependent_inits/finals_conditions
1049a7dea167SDimitry Andric     // arrays).
1050e8d8bef9SDimitry Andric     DefaultEnd = 8,
10510b57cec5SDimitry Andric     // The following 8 exprs are used by worksharing and distribute loops only.
1052e8d8bef9SDimitry Andric     IsLastIterVariableOffset = 8,
1053e8d8bef9SDimitry Andric     LowerBoundVariableOffset = 9,
1054e8d8bef9SDimitry Andric     UpperBoundVariableOffset = 10,
1055e8d8bef9SDimitry Andric     StrideVariableOffset = 11,
1056e8d8bef9SDimitry Andric     EnsureUpperBoundOffset = 12,
1057e8d8bef9SDimitry Andric     NextLowerBoundOffset = 13,
1058e8d8bef9SDimitry Andric     NextUpperBoundOffset = 14,
1059e8d8bef9SDimitry Andric     NumIterationsOffset = 15,
10600b57cec5SDimitry Andric     // Offset to the end for worksharing loop directives.
1061e8d8bef9SDimitry Andric     WorksharingEnd = 16,
1062e8d8bef9SDimitry Andric     PrevLowerBoundVariableOffset = 16,
1063e8d8bef9SDimitry Andric     PrevUpperBoundVariableOffset = 17,
1064e8d8bef9SDimitry Andric     DistIncOffset = 18,
1065e8d8bef9SDimitry Andric     PrevEnsureUpperBoundOffset = 19,
1066e8d8bef9SDimitry Andric     CombinedLowerBoundVariableOffset = 20,
1067e8d8bef9SDimitry Andric     CombinedUpperBoundVariableOffset = 21,
1068e8d8bef9SDimitry Andric     CombinedEnsureUpperBoundOffset = 22,
1069e8d8bef9SDimitry Andric     CombinedInitOffset = 23,
1070e8d8bef9SDimitry Andric     CombinedConditionOffset = 24,
1071e8d8bef9SDimitry Andric     CombinedNextLowerBoundOffset = 25,
1072e8d8bef9SDimitry Andric     CombinedNextUpperBoundOffset = 26,
1073e8d8bef9SDimitry Andric     CombinedDistConditionOffset = 27,
1074e8d8bef9SDimitry Andric     CombinedParForInDistConditionOffset = 28,
1075a7dea167SDimitry Andric     // Offset to the end (and start of the following
1076a7dea167SDimitry Andric     // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions
10770b57cec5SDimitry Andric     // arrays) for combined distribute loop directives.
1078e8d8bef9SDimitry Andric     CombinedDistributeEnd = 29,
10790b57cec5SDimitry Andric   };
10800b57cec5SDimitry Andric 
10810b57cec5SDimitry Andric   /// Get the counters storage.
getCounters()10820b57cec5SDimitry Andric   MutableArrayRef<Expr *> getCounters() {
1083e8d8bef9SDimitry Andric     auto **Storage = reinterpret_cast<Expr **>(
1084e8d8bef9SDimitry Andric         &Data->getChildren()[getArraysOffset(getDirectiveKind())]);
1085bdd1243dSDimitry Andric     return llvm::MutableArrayRef(Storage, getLoopsNumber());
10860b57cec5SDimitry Andric   }
10870b57cec5SDimitry Andric 
10880b57cec5SDimitry Andric   /// Get the private counters storage.
getPrivateCounters()10890b57cec5SDimitry Andric   MutableArrayRef<Expr *> getPrivateCounters() {
1090e8d8bef9SDimitry Andric     auto **Storage = reinterpret_cast<Expr **>(
1091e8d8bef9SDimitry Andric         &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1092fe6060f1SDimitry Andric                              getLoopsNumber()]);
1093bdd1243dSDimitry Andric     return llvm::MutableArrayRef(Storage, getLoopsNumber());
10940b57cec5SDimitry Andric   }
10950b57cec5SDimitry Andric 
10960b57cec5SDimitry Andric   /// Get the updates storage.
getInits()10970b57cec5SDimitry Andric   MutableArrayRef<Expr *> getInits() {
1098e8d8bef9SDimitry Andric     auto **Storage = reinterpret_cast<Expr **>(
1099e8d8bef9SDimitry Andric         &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1100fe6060f1SDimitry Andric                              2 * getLoopsNumber()]);
1101bdd1243dSDimitry Andric     return llvm::MutableArrayRef(Storage, getLoopsNumber());
11020b57cec5SDimitry Andric   }
11030b57cec5SDimitry Andric 
11040b57cec5SDimitry Andric   /// Get the updates storage.
getUpdates()11050b57cec5SDimitry Andric   MutableArrayRef<Expr *> getUpdates() {
1106e8d8bef9SDimitry Andric     auto **Storage = reinterpret_cast<Expr **>(
1107e8d8bef9SDimitry Andric         &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1108fe6060f1SDimitry Andric                              3 * getLoopsNumber()]);
1109bdd1243dSDimitry Andric     return llvm::MutableArrayRef(Storage, getLoopsNumber());
11100b57cec5SDimitry Andric   }
11110b57cec5SDimitry Andric 
11120b57cec5SDimitry Andric   /// Get the final counter updates storage.
getFinals()11130b57cec5SDimitry Andric   MutableArrayRef<Expr *> getFinals() {
1114e8d8bef9SDimitry Andric     auto **Storage = reinterpret_cast<Expr **>(
1115e8d8bef9SDimitry Andric         &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1116fe6060f1SDimitry Andric                              4 * getLoopsNumber()]);
1117bdd1243dSDimitry Andric     return llvm::MutableArrayRef(Storage, getLoopsNumber());
11180b57cec5SDimitry Andric   }
11190b57cec5SDimitry Andric 
1120a7dea167SDimitry Andric   /// Get the dependent counters storage.
getDependentCounters()1121a7dea167SDimitry Andric   MutableArrayRef<Expr *> getDependentCounters() {
1122e8d8bef9SDimitry Andric     auto **Storage = reinterpret_cast<Expr **>(
1123e8d8bef9SDimitry Andric         &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1124fe6060f1SDimitry Andric                              5 * getLoopsNumber()]);
1125bdd1243dSDimitry Andric     return llvm::MutableArrayRef(Storage, getLoopsNumber());
1126a7dea167SDimitry Andric   }
1127a7dea167SDimitry Andric 
1128a7dea167SDimitry Andric   /// Get the dependent inits storage.
getDependentInits()1129a7dea167SDimitry Andric   MutableArrayRef<Expr *> getDependentInits() {
1130e8d8bef9SDimitry Andric     auto **Storage = reinterpret_cast<Expr **>(
1131e8d8bef9SDimitry Andric         &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1132fe6060f1SDimitry Andric                              6 * getLoopsNumber()]);
1133bdd1243dSDimitry Andric     return llvm::MutableArrayRef(Storage, getLoopsNumber());
1134a7dea167SDimitry Andric   }
1135a7dea167SDimitry Andric 
1136a7dea167SDimitry Andric   /// Get the finals conditions storage.
getFinalsConditions()1137a7dea167SDimitry Andric   MutableArrayRef<Expr *> getFinalsConditions() {
1138e8d8bef9SDimitry Andric     auto **Storage = reinterpret_cast<Expr **>(
1139e8d8bef9SDimitry Andric         &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1140fe6060f1SDimitry Andric                              7 * getLoopsNumber()]);
1141bdd1243dSDimitry Andric     return llvm::MutableArrayRef(Storage, getLoopsNumber());
1142a7dea167SDimitry Andric   }
1143a7dea167SDimitry Andric 
11440b57cec5SDimitry Andric protected:
11450b57cec5SDimitry Andric   /// Build instance of loop directive of class \a Kind.
11460b57cec5SDimitry Andric   ///
11470b57cec5SDimitry Andric   /// \param SC Statement class.
11480b57cec5SDimitry Andric   /// \param Kind Kind of OpenMP directive.
11490b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive (directive keyword).
11500b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
11510b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
11520b57cec5SDimitry Andric   ///
OMPLoopDirective(StmtClass SC,OpenMPDirectiveKind Kind,SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)1153e8d8bef9SDimitry Andric   OMPLoopDirective(StmtClass SC, OpenMPDirectiveKind Kind,
11540b57cec5SDimitry Andric                    SourceLocation StartLoc, SourceLocation EndLoc,
1155e8d8bef9SDimitry Andric                    unsigned CollapsedNum)
1156fe6060f1SDimitry Andric       : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, CollapsedNum) {}
11570b57cec5SDimitry Andric 
11580b57cec5SDimitry Andric   /// Offset to the start of children expression arrays.
getArraysOffset(OpenMPDirectiveKind Kind)11590b57cec5SDimitry Andric   static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
11600b57cec5SDimitry Andric     if (isOpenMPLoopBoundSharingDirective(Kind))
11610b57cec5SDimitry Andric       return CombinedDistributeEnd;
11620b57cec5SDimitry Andric     if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) ||
1163349cc55cSDimitry Andric         isOpenMPGenericLoopDirective(Kind) || isOpenMPDistributeDirective(Kind))
11640b57cec5SDimitry Andric       return WorksharingEnd;
11650b57cec5SDimitry Andric     return DefaultEnd;
11660b57cec5SDimitry Andric   }
11670b57cec5SDimitry Andric 
11680b57cec5SDimitry Andric   /// Children number.
numLoopChildren(unsigned CollapsedNum,OpenMPDirectiveKind Kind)11690b57cec5SDimitry Andric   static unsigned numLoopChildren(unsigned CollapsedNum,
11700b57cec5SDimitry Andric                                   OpenMPDirectiveKind Kind) {
1171a7dea167SDimitry Andric     return getArraysOffset(Kind) +
1172a7dea167SDimitry Andric            8 * CollapsedNum; // Counters, PrivateCounters, Inits,
1173a7dea167SDimitry Andric                              // Updates, Finals, DependentCounters,
1174a7dea167SDimitry Andric                              // DependentInits, FinalsConditions.
11750b57cec5SDimitry Andric   }
11760b57cec5SDimitry Andric 
setIterationVariable(Expr * IV)11770b57cec5SDimitry Andric   void setIterationVariable(Expr *IV) {
1178e8d8bef9SDimitry Andric     Data->getChildren()[IterationVariableOffset] = IV;
11790b57cec5SDimitry Andric   }
setLastIteration(Expr * LI)11800b57cec5SDimitry Andric   void setLastIteration(Expr *LI) {
1181e8d8bef9SDimitry Andric     Data->getChildren()[LastIterationOffset] = LI;
11820b57cec5SDimitry Andric   }
setCalcLastIteration(Expr * CLI)11830b57cec5SDimitry Andric   void setCalcLastIteration(Expr *CLI) {
1184e8d8bef9SDimitry Andric     Data->getChildren()[CalcLastIterationOffset] = CLI;
11850b57cec5SDimitry Andric   }
setPreCond(Expr * PC)1186e8d8bef9SDimitry Andric   void setPreCond(Expr *PC) { Data->getChildren()[PreConditionOffset] = PC; }
setCond(Expr * Cond)1187e8d8bef9SDimitry Andric   void setCond(Expr *Cond) { Data->getChildren()[CondOffset] = Cond; }
setInit(Expr * Init)1188e8d8bef9SDimitry Andric   void setInit(Expr *Init) { Data->getChildren()[InitOffset] = Init; }
setInc(Expr * Inc)1189e8d8bef9SDimitry Andric   void setInc(Expr *Inc) { Data->getChildren()[IncOffset] = Inc; }
setPreInits(Stmt * PreInits)11900b57cec5SDimitry Andric   void setPreInits(Stmt *PreInits) {
1191e8d8bef9SDimitry Andric     Data->getChildren()[PreInitsOffset] = PreInits;
11920b57cec5SDimitry Andric   }
setIsLastIterVariable(Expr * IL)11930b57cec5SDimitry Andric   void setIsLastIterVariable(Expr *IL) {
11940b57cec5SDimitry Andric     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1195349cc55cSDimitry Andric             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
11960b57cec5SDimitry Andric             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
11970b57cec5SDimitry Andric             isOpenMPDistributeDirective(getDirectiveKind())) &&
11980b57cec5SDimitry Andric            "expected worksharing loop directive");
1199e8d8bef9SDimitry Andric     Data->getChildren()[IsLastIterVariableOffset] = IL;
12000b57cec5SDimitry Andric   }
setLowerBoundVariable(Expr * LB)12010b57cec5SDimitry Andric   void setLowerBoundVariable(Expr *LB) {
12020b57cec5SDimitry Andric     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1203349cc55cSDimitry Andric             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
12040b57cec5SDimitry Andric             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
12050b57cec5SDimitry Andric             isOpenMPDistributeDirective(getDirectiveKind())) &&
12060b57cec5SDimitry Andric            "expected worksharing loop directive");
1207e8d8bef9SDimitry Andric     Data->getChildren()[LowerBoundVariableOffset] = LB;
12080b57cec5SDimitry Andric   }
setUpperBoundVariable(Expr * UB)12090b57cec5SDimitry Andric   void setUpperBoundVariable(Expr *UB) {
12100b57cec5SDimitry Andric     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1211349cc55cSDimitry Andric             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
12120b57cec5SDimitry Andric             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
12130b57cec5SDimitry Andric             isOpenMPDistributeDirective(getDirectiveKind())) &&
12140b57cec5SDimitry Andric            "expected worksharing loop directive");
1215e8d8bef9SDimitry Andric     Data->getChildren()[UpperBoundVariableOffset] = UB;
12160b57cec5SDimitry Andric   }
setStrideVariable(Expr * ST)12170b57cec5SDimitry Andric   void setStrideVariable(Expr *ST) {
12180b57cec5SDimitry Andric     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1219349cc55cSDimitry Andric             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
12200b57cec5SDimitry Andric             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
12210b57cec5SDimitry Andric             isOpenMPDistributeDirective(getDirectiveKind())) &&
12220b57cec5SDimitry Andric            "expected worksharing loop directive");
1223e8d8bef9SDimitry Andric     Data->getChildren()[StrideVariableOffset] = ST;
12240b57cec5SDimitry Andric   }
setEnsureUpperBound(Expr * EUB)12250b57cec5SDimitry Andric   void setEnsureUpperBound(Expr *EUB) {
12260b57cec5SDimitry Andric     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1227349cc55cSDimitry Andric             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
12280b57cec5SDimitry Andric             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
12290b57cec5SDimitry Andric             isOpenMPDistributeDirective(getDirectiveKind())) &&
12300b57cec5SDimitry Andric            "expected worksharing loop directive");
1231e8d8bef9SDimitry Andric     Data->getChildren()[EnsureUpperBoundOffset] = EUB;
12320b57cec5SDimitry Andric   }
setNextLowerBound(Expr * NLB)12330b57cec5SDimitry Andric   void setNextLowerBound(Expr *NLB) {
12340b57cec5SDimitry Andric     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1235349cc55cSDimitry Andric             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
12360b57cec5SDimitry Andric             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
12370b57cec5SDimitry Andric             isOpenMPDistributeDirective(getDirectiveKind())) &&
12380b57cec5SDimitry Andric            "expected worksharing loop directive");
1239e8d8bef9SDimitry Andric     Data->getChildren()[NextLowerBoundOffset] = NLB;
12400b57cec5SDimitry Andric   }
setNextUpperBound(Expr * NUB)12410b57cec5SDimitry Andric   void setNextUpperBound(Expr *NUB) {
12420b57cec5SDimitry Andric     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1243349cc55cSDimitry Andric             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
12440b57cec5SDimitry Andric             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
12450b57cec5SDimitry Andric             isOpenMPDistributeDirective(getDirectiveKind())) &&
12460b57cec5SDimitry Andric            "expected worksharing loop directive");
1247e8d8bef9SDimitry Andric     Data->getChildren()[NextUpperBoundOffset] = NUB;
12480b57cec5SDimitry Andric   }
setNumIterations(Expr * NI)12490b57cec5SDimitry Andric   void setNumIterations(Expr *NI) {
12500b57cec5SDimitry Andric     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1251349cc55cSDimitry Andric             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
12520b57cec5SDimitry Andric             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
12530b57cec5SDimitry Andric             isOpenMPDistributeDirective(getDirectiveKind())) &&
12540b57cec5SDimitry Andric            "expected worksharing loop directive");
1255e8d8bef9SDimitry Andric     Data->getChildren()[NumIterationsOffset] = NI;
12560b57cec5SDimitry Andric   }
setPrevLowerBoundVariable(Expr * PrevLB)12570b57cec5SDimitry Andric   void setPrevLowerBoundVariable(Expr *PrevLB) {
12580b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
12590b57cec5SDimitry Andric            "expected loop bound sharing directive");
1260e8d8bef9SDimitry Andric     Data->getChildren()[PrevLowerBoundVariableOffset] = PrevLB;
12610b57cec5SDimitry Andric   }
setPrevUpperBoundVariable(Expr * PrevUB)12620b57cec5SDimitry Andric   void setPrevUpperBoundVariable(Expr *PrevUB) {
12630b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
12640b57cec5SDimitry Andric            "expected loop bound sharing directive");
1265e8d8bef9SDimitry Andric     Data->getChildren()[PrevUpperBoundVariableOffset] = PrevUB;
12660b57cec5SDimitry Andric   }
setDistInc(Expr * DistInc)12670b57cec5SDimitry Andric   void setDistInc(Expr *DistInc) {
12680b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
12690b57cec5SDimitry Andric            "expected loop bound sharing directive");
1270e8d8bef9SDimitry Andric     Data->getChildren()[DistIncOffset] = DistInc;
12710b57cec5SDimitry Andric   }
setPrevEnsureUpperBound(Expr * PrevEUB)12720b57cec5SDimitry Andric   void setPrevEnsureUpperBound(Expr *PrevEUB) {
12730b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
12740b57cec5SDimitry Andric            "expected loop bound sharing directive");
1275e8d8bef9SDimitry Andric     Data->getChildren()[PrevEnsureUpperBoundOffset] = PrevEUB;
12760b57cec5SDimitry Andric   }
setCombinedLowerBoundVariable(Expr * CombLB)12770b57cec5SDimitry Andric   void setCombinedLowerBoundVariable(Expr *CombLB) {
12780b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
12790b57cec5SDimitry Andric            "expected loop bound sharing directive");
1280e8d8bef9SDimitry Andric     Data->getChildren()[CombinedLowerBoundVariableOffset] = CombLB;
12810b57cec5SDimitry Andric   }
setCombinedUpperBoundVariable(Expr * CombUB)12820b57cec5SDimitry Andric   void setCombinedUpperBoundVariable(Expr *CombUB) {
12830b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
12840b57cec5SDimitry Andric            "expected loop bound sharing directive");
1285e8d8bef9SDimitry Andric     Data->getChildren()[CombinedUpperBoundVariableOffset] = CombUB;
12860b57cec5SDimitry Andric   }
setCombinedEnsureUpperBound(Expr * CombEUB)12870b57cec5SDimitry Andric   void setCombinedEnsureUpperBound(Expr *CombEUB) {
12880b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
12890b57cec5SDimitry Andric            "expected loop bound sharing directive");
1290e8d8bef9SDimitry Andric     Data->getChildren()[CombinedEnsureUpperBoundOffset] = CombEUB;
12910b57cec5SDimitry Andric   }
setCombinedInit(Expr * CombInit)12920b57cec5SDimitry Andric   void setCombinedInit(Expr *CombInit) {
12930b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
12940b57cec5SDimitry Andric            "expected loop bound sharing directive");
1295e8d8bef9SDimitry Andric     Data->getChildren()[CombinedInitOffset] = CombInit;
12960b57cec5SDimitry Andric   }
setCombinedCond(Expr * CombCond)12970b57cec5SDimitry Andric   void setCombinedCond(Expr *CombCond) {
12980b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
12990b57cec5SDimitry Andric            "expected loop bound sharing directive");
1300e8d8bef9SDimitry Andric     Data->getChildren()[CombinedConditionOffset] = CombCond;
13010b57cec5SDimitry Andric   }
setCombinedNextLowerBound(Expr * CombNLB)13020b57cec5SDimitry Andric   void setCombinedNextLowerBound(Expr *CombNLB) {
13030b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
13040b57cec5SDimitry Andric            "expected loop bound sharing directive");
1305e8d8bef9SDimitry Andric     Data->getChildren()[CombinedNextLowerBoundOffset] = CombNLB;
13060b57cec5SDimitry Andric   }
setCombinedNextUpperBound(Expr * CombNUB)13070b57cec5SDimitry Andric   void setCombinedNextUpperBound(Expr *CombNUB) {
13080b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
13090b57cec5SDimitry Andric            "expected loop bound sharing directive");
1310e8d8bef9SDimitry Andric     Data->getChildren()[CombinedNextUpperBoundOffset] = CombNUB;
13110b57cec5SDimitry Andric   }
setCombinedDistCond(Expr * CombDistCond)13120b57cec5SDimitry Andric   void setCombinedDistCond(Expr *CombDistCond) {
13130b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
13140b57cec5SDimitry Andric            "expected loop bound distribute sharing directive");
1315e8d8bef9SDimitry Andric     Data->getChildren()[CombinedDistConditionOffset] = CombDistCond;
13160b57cec5SDimitry Andric   }
setCombinedParForInDistCond(Expr * CombParForInDistCond)13170b57cec5SDimitry Andric   void setCombinedParForInDistCond(Expr *CombParForInDistCond) {
13180b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
13190b57cec5SDimitry Andric            "expected loop bound distribute sharing directive");
1320e8d8bef9SDimitry Andric     Data->getChildren()[CombinedParForInDistConditionOffset] =
1321e8d8bef9SDimitry Andric         CombParForInDistCond;
13220b57cec5SDimitry Andric   }
13230b57cec5SDimitry Andric   void setCounters(ArrayRef<Expr *> A);
13240b57cec5SDimitry Andric   void setPrivateCounters(ArrayRef<Expr *> A);
13250b57cec5SDimitry Andric   void setInits(ArrayRef<Expr *> A);
13260b57cec5SDimitry Andric   void setUpdates(ArrayRef<Expr *> A);
13270b57cec5SDimitry Andric   void setFinals(ArrayRef<Expr *> A);
1328a7dea167SDimitry Andric   void setDependentCounters(ArrayRef<Expr *> A);
1329a7dea167SDimitry Andric   void setDependentInits(ArrayRef<Expr *> A);
1330a7dea167SDimitry Andric   void setFinalsConditions(ArrayRef<Expr *> A);
13310b57cec5SDimitry Andric 
13320b57cec5SDimitry Andric public:
getIterationVariable()13330b57cec5SDimitry Andric   Expr *getIterationVariable() const {
1334e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[IterationVariableOffset]);
13350b57cec5SDimitry Andric   }
getLastIteration()13360b57cec5SDimitry Andric   Expr *getLastIteration() const {
1337e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[LastIterationOffset]);
13380b57cec5SDimitry Andric   }
getCalcLastIteration()13390b57cec5SDimitry Andric   Expr *getCalcLastIteration() const {
1340e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[CalcLastIterationOffset]);
13410b57cec5SDimitry Andric   }
getPreCond()13420b57cec5SDimitry Andric   Expr *getPreCond() const {
1343e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[PreConditionOffset]);
13440b57cec5SDimitry Andric   }
getCond()1345e8d8bef9SDimitry Andric   Expr *getCond() const { return cast<Expr>(Data->getChildren()[CondOffset]); }
getInit()1346e8d8bef9SDimitry Andric   Expr *getInit() const { return cast<Expr>(Data->getChildren()[InitOffset]); }
getInc()1347e8d8bef9SDimitry Andric   Expr *getInc() const { return cast<Expr>(Data->getChildren()[IncOffset]); }
getPreInits()13480b57cec5SDimitry Andric   const Stmt *getPreInits() const {
1349e8d8bef9SDimitry Andric     return Data->getChildren()[PreInitsOffset];
13500b57cec5SDimitry Andric   }
getPreInits()1351e8d8bef9SDimitry Andric   Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; }
getIsLastIterVariable()13520b57cec5SDimitry Andric   Expr *getIsLastIterVariable() const {
13530b57cec5SDimitry Andric     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1354349cc55cSDimitry Andric             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
13550b57cec5SDimitry Andric             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
13560b57cec5SDimitry Andric             isOpenMPDistributeDirective(getDirectiveKind())) &&
13570b57cec5SDimitry Andric            "expected worksharing loop directive");
1358e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[IsLastIterVariableOffset]);
13590b57cec5SDimitry Andric   }
getLowerBoundVariable()13600b57cec5SDimitry Andric   Expr *getLowerBoundVariable() const {
13610b57cec5SDimitry Andric     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1362349cc55cSDimitry Andric             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
13630b57cec5SDimitry Andric             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
13640b57cec5SDimitry Andric             isOpenMPDistributeDirective(getDirectiveKind())) &&
13650b57cec5SDimitry Andric            "expected worksharing loop directive");
1366e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[LowerBoundVariableOffset]);
13670b57cec5SDimitry Andric   }
getUpperBoundVariable()13680b57cec5SDimitry Andric   Expr *getUpperBoundVariable() const {
13690b57cec5SDimitry Andric     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1370349cc55cSDimitry Andric             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
13710b57cec5SDimitry Andric             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
13720b57cec5SDimitry Andric             isOpenMPDistributeDirective(getDirectiveKind())) &&
13730b57cec5SDimitry Andric            "expected worksharing loop directive");
1374e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[UpperBoundVariableOffset]);
13750b57cec5SDimitry Andric   }
getStrideVariable()13760b57cec5SDimitry Andric   Expr *getStrideVariable() const {
13770b57cec5SDimitry Andric     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1378349cc55cSDimitry Andric             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
13790b57cec5SDimitry Andric             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
13800b57cec5SDimitry Andric             isOpenMPDistributeDirective(getDirectiveKind())) &&
13810b57cec5SDimitry Andric            "expected worksharing loop directive");
1382e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[StrideVariableOffset]);
13830b57cec5SDimitry Andric   }
getEnsureUpperBound()13840b57cec5SDimitry Andric   Expr *getEnsureUpperBound() const {
13850b57cec5SDimitry Andric     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1386349cc55cSDimitry Andric             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
13870b57cec5SDimitry Andric             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
13880b57cec5SDimitry Andric             isOpenMPDistributeDirective(getDirectiveKind())) &&
13890b57cec5SDimitry Andric            "expected worksharing loop directive");
1390e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[EnsureUpperBoundOffset]);
13910b57cec5SDimitry Andric   }
getNextLowerBound()13920b57cec5SDimitry Andric   Expr *getNextLowerBound() const {
13930b57cec5SDimitry Andric     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1394349cc55cSDimitry Andric             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
13950b57cec5SDimitry Andric             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
13960b57cec5SDimitry Andric             isOpenMPDistributeDirective(getDirectiveKind())) &&
13970b57cec5SDimitry Andric            "expected worksharing loop directive");
1398e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[NextLowerBoundOffset]);
13990b57cec5SDimitry Andric   }
getNextUpperBound()14000b57cec5SDimitry Andric   Expr *getNextUpperBound() const {
14010b57cec5SDimitry Andric     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1402349cc55cSDimitry Andric             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
14030b57cec5SDimitry Andric             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
14040b57cec5SDimitry Andric             isOpenMPDistributeDirective(getDirectiveKind())) &&
14050b57cec5SDimitry Andric            "expected worksharing loop directive");
1406e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[NextUpperBoundOffset]);
14070b57cec5SDimitry Andric   }
getNumIterations()14080b57cec5SDimitry Andric   Expr *getNumIterations() const {
14090b57cec5SDimitry Andric     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1410349cc55cSDimitry Andric             isOpenMPGenericLoopDirective(getDirectiveKind()) ||
14110b57cec5SDimitry Andric             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
14120b57cec5SDimitry Andric             isOpenMPDistributeDirective(getDirectiveKind())) &&
14130b57cec5SDimitry Andric            "expected worksharing loop directive");
1414e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[NumIterationsOffset]);
14150b57cec5SDimitry Andric   }
getPrevLowerBoundVariable()14160b57cec5SDimitry Andric   Expr *getPrevLowerBoundVariable() const {
14170b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
14180b57cec5SDimitry Andric            "expected loop bound sharing directive");
1419e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[PrevLowerBoundVariableOffset]);
14200b57cec5SDimitry Andric   }
getPrevUpperBoundVariable()14210b57cec5SDimitry Andric   Expr *getPrevUpperBoundVariable() const {
14220b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
14230b57cec5SDimitry Andric            "expected loop bound sharing directive");
1424e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[PrevUpperBoundVariableOffset]);
14250b57cec5SDimitry Andric   }
getDistInc()14260b57cec5SDimitry Andric   Expr *getDistInc() const {
14270b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
14280b57cec5SDimitry Andric            "expected loop bound sharing directive");
1429e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[DistIncOffset]);
14300b57cec5SDimitry Andric   }
getPrevEnsureUpperBound()14310b57cec5SDimitry Andric   Expr *getPrevEnsureUpperBound() const {
14320b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
14330b57cec5SDimitry Andric            "expected loop bound sharing directive");
1434e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[PrevEnsureUpperBoundOffset]);
14350b57cec5SDimitry Andric   }
getCombinedLowerBoundVariable()14360b57cec5SDimitry Andric   Expr *getCombinedLowerBoundVariable() const {
14370b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
14380b57cec5SDimitry Andric            "expected loop bound sharing directive");
1439e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[CombinedLowerBoundVariableOffset]);
14400b57cec5SDimitry Andric   }
getCombinedUpperBoundVariable()14410b57cec5SDimitry Andric   Expr *getCombinedUpperBoundVariable() const {
14420b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
14430b57cec5SDimitry Andric            "expected loop bound sharing directive");
1444e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[CombinedUpperBoundVariableOffset]);
14450b57cec5SDimitry Andric   }
getCombinedEnsureUpperBound()14460b57cec5SDimitry Andric   Expr *getCombinedEnsureUpperBound() const {
14470b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
14480b57cec5SDimitry Andric            "expected loop bound sharing directive");
1449e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[CombinedEnsureUpperBoundOffset]);
14500b57cec5SDimitry Andric   }
getCombinedInit()14510b57cec5SDimitry Andric   Expr *getCombinedInit() const {
14520b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
14530b57cec5SDimitry Andric            "expected loop bound sharing directive");
1454e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[CombinedInitOffset]);
14550b57cec5SDimitry Andric   }
getCombinedCond()14560b57cec5SDimitry Andric   Expr *getCombinedCond() const {
14570b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
14580b57cec5SDimitry Andric            "expected loop bound sharing directive");
1459e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[CombinedConditionOffset]);
14600b57cec5SDimitry Andric   }
getCombinedNextLowerBound()14610b57cec5SDimitry Andric   Expr *getCombinedNextLowerBound() const {
14620b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
14630b57cec5SDimitry Andric            "expected loop bound sharing directive");
1464e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[CombinedNextLowerBoundOffset]);
14650b57cec5SDimitry Andric   }
getCombinedNextUpperBound()14660b57cec5SDimitry Andric   Expr *getCombinedNextUpperBound() const {
14670b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
14680b57cec5SDimitry Andric            "expected loop bound sharing directive");
1469e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[CombinedNextUpperBoundOffset]);
14700b57cec5SDimitry Andric   }
getCombinedDistCond()14710b57cec5SDimitry Andric   Expr *getCombinedDistCond() const {
14720b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
14730b57cec5SDimitry Andric            "expected loop bound distribute sharing directive");
1474e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[CombinedDistConditionOffset]);
14750b57cec5SDimitry Andric   }
getCombinedParForInDistCond()14760b57cec5SDimitry Andric   Expr *getCombinedParForInDistCond() const {
14770b57cec5SDimitry Andric     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
14780b57cec5SDimitry Andric            "expected loop bound distribute sharing directive");
1479e8d8bef9SDimitry Andric     return cast<Expr>(Data->getChildren()[CombinedParForInDistConditionOffset]);
14800b57cec5SDimitry Andric   }
1481480093f4SDimitry Andric   Stmt *getBody();
getBody()14820b57cec5SDimitry Andric   const Stmt *getBody() const {
1483480093f4SDimitry Andric     return const_cast<OMPLoopDirective *>(this)->getBody();
14840b57cec5SDimitry Andric   }
14850b57cec5SDimitry Andric 
counters()14860b57cec5SDimitry Andric   ArrayRef<Expr *> counters() { return getCounters(); }
14870b57cec5SDimitry Andric 
counters()14880b57cec5SDimitry Andric   ArrayRef<Expr *> counters() const {
14890b57cec5SDimitry Andric     return const_cast<OMPLoopDirective *>(this)->getCounters();
14900b57cec5SDimitry Andric   }
14910b57cec5SDimitry Andric 
private_counters()14920b57cec5SDimitry Andric   ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
14930b57cec5SDimitry Andric 
private_counters()14940b57cec5SDimitry Andric   ArrayRef<Expr *> private_counters() const {
14950b57cec5SDimitry Andric     return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
14960b57cec5SDimitry Andric   }
14970b57cec5SDimitry Andric 
inits()14980b57cec5SDimitry Andric   ArrayRef<Expr *> inits() { return getInits(); }
14990b57cec5SDimitry Andric 
inits()15000b57cec5SDimitry Andric   ArrayRef<Expr *> inits() const {
15010b57cec5SDimitry Andric     return const_cast<OMPLoopDirective *>(this)->getInits();
15020b57cec5SDimitry Andric   }
15030b57cec5SDimitry Andric 
updates()15040b57cec5SDimitry Andric   ArrayRef<Expr *> updates() { return getUpdates(); }
15050b57cec5SDimitry Andric 
updates()15060b57cec5SDimitry Andric   ArrayRef<Expr *> updates() const {
15070b57cec5SDimitry Andric     return const_cast<OMPLoopDirective *>(this)->getUpdates();
15080b57cec5SDimitry Andric   }
15090b57cec5SDimitry Andric 
finals()15100b57cec5SDimitry Andric   ArrayRef<Expr *> finals() { return getFinals(); }
15110b57cec5SDimitry Andric 
finals()15120b57cec5SDimitry Andric   ArrayRef<Expr *> finals() const {
15130b57cec5SDimitry Andric     return const_cast<OMPLoopDirective *>(this)->getFinals();
15140b57cec5SDimitry Andric   }
15150b57cec5SDimitry Andric 
dependent_counters()1516a7dea167SDimitry Andric   ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); }
1517a7dea167SDimitry Andric 
dependent_counters()1518a7dea167SDimitry Andric   ArrayRef<Expr *> dependent_counters() const {
1519a7dea167SDimitry Andric     return const_cast<OMPLoopDirective *>(this)->getDependentCounters();
1520a7dea167SDimitry Andric   }
1521a7dea167SDimitry Andric 
dependent_inits()1522a7dea167SDimitry Andric   ArrayRef<Expr *> dependent_inits() { return getDependentInits(); }
1523a7dea167SDimitry Andric 
dependent_inits()1524a7dea167SDimitry Andric   ArrayRef<Expr *> dependent_inits() const {
1525a7dea167SDimitry Andric     return const_cast<OMPLoopDirective *>(this)->getDependentInits();
1526a7dea167SDimitry Andric   }
1527a7dea167SDimitry Andric 
finals_conditions()1528a7dea167SDimitry Andric   ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); }
1529a7dea167SDimitry Andric 
finals_conditions()1530a7dea167SDimitry Andric   ArrayRef<Expr *> finals_conditions() const {
1531a7dea167SDimitry Andric     return const_cast<OMPLoopDirective *>(this)->getFinalsConditions();
1532a7dea167SDimitry Andric   }
1533a7dea167SDimitry Andric 
classof(const Stmt * T)15340b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
15350b57cec5SDimitry Andric     return T->getStmtClass() == OMPSimdDirectiveClass ||
15360b57cec5SDimitry Andric            T->getStmtClass() == OMPForDirectiveClass ||
15370b57cec5SDimitry Andric            T->getStmtClass() == OMPForSimdDirectiveClass ||
15380b57cec5SDimitry Andric            T->getStmtClass() == OMPParallelForDirectiveClass ||
15390b57cec5SDimitry Andric            T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
15400b57cec5SDimitry Andric            T->getStmtClass() == OMPTaskLoopDirectiveClass ||
15410b57cec5SDimitry Andric            T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
154281ad6265SDimitry Andric            T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass ||
154381ad6265SDimitry Andric            T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass ||
1544a7dea167SDimitry Andric            T->getStmtClass() == OMPMasterTaskLoopDirectiveClass ||
1545a7dea167SDimitry Andric            T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass ||
1546349cc55cSDimitry Andric            T->getStmtClass() == OMPGenericLoopDirectiveClass ||
154781ad6265SDimitry Andric            T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass ||
154881ad6265SDimitry Andric            T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass ||
154981ad6265SDimitry Andric            T->getStmtClass() == OMPParallelGenericLoopDirectiveClass ||
155081ad6265SDimitry Andric            T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass ||
155181ad6265SDimitry Andric            T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass ||
155281ad6265SDimitry Andric            T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass ||
1553a7dea167SDimitry Andric            T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass ||
1554480093f4SDimitry Andric            T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass ||
15550b57cec5SDimitry Andric            T->getStmtClass() == OMPDistributeDirectiveClass ||
15560b57cec5SDimitry Andric            T->getStmtClass() == OMPTargetParallelForDirectiveClass ||
15570b57cec5SDimitry Andric            T->getStmtClass() == OMPDistributeParallelForDirectiveClass ||
15580b57cec5SDimitry Andric            T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass ||
15590b57cec5SDimitry Andric            T->getStmtClass() == OMPDistributeSimdDirectiveClass ||
15600b57cec5SDimitry Andric            T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass ||
15610b57cec5SDimitry Andric            T->getStmtClass() == OMPTargetSimdDirectiveClass ||
15620b57cec5SDimitry Andric            T->getStmtClass() == OMPTeamsDistributeDirectiveClass ||
15630b57cec5SDimitry Andric            T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass ||
15640b57cec5SDimitry Andric            T->getStmtClass() ==
15650b57cec5SDimitry Andric                OMPTeamsDistributeParallelForSimdDirectiveClass ||
15660b57cec5SDimitry Andric            T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass ||
15670b57cec5SDimitry Andric            T->getStmtClass() ==
15680b57cec5SDimitry Andric                OMPTargetTeamsDistributeParallelForDirectiveClass ||
15690b57cec5SDimitry Andric            T->getStmtClass() ==
15700b57cec5SDimitry Andric                OMPTargetTeamsDistributeParallelForSimdDirectiveClass ||
15710b57cec5SDimitry Andric            T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass ||
15720b57cec5SDimitry Andric            T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
15730b57cec5SDimitry Andric   }
15740b57cec5SDimitry Andric };
15750b57cec5SDimitry Andric 
15760b57cec5SDimitry Andric /// This represents '#pragma omp simd' directive.
15770b57cec5SDimitry Andric ///
15780b57cec5SDimitry Andric /// \code
15790b57cec5SDimitry Andric /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
15800b57cec5SDimitry Andric /// \endcode
15810b57cec5SDimitry Andric /// In this example directive '#pragma omp simd' has clauses 'private'
15820b57cec5SDimitry Andric /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
15830b57cec5SDimitry Andric /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
15840b57cec5SDimitry Andric ///
15850b57cec5SDimitry Andric class OMPSimdDirective : public OMPLoopDirective {
15860b57cec5SDimitry Andric   friend class ASTStmtReader;
1587e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
15880b57cec5SDimitry Andric   /// Build directive with the given start and end location.
15890b57cec5SDimitry Andric   ///
15900b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
15910b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
15920b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
15930b57cec5SDimitry Andric   ///
OMPSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)15940b57cec5SDimitry Andric   OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1595e8d8bef9SDimitry Andric                    unsigned CollapsedNum)
1596e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, StartLoc,
1597e8d8bef9SDimitry Andric                          EndLoc, CollapsedNum) {}
15980b57cec5SDimitry Andric 
15990b57cec5SDimitry Andric   /// Build an empty directive.
16000b57cec5SDimitry Andric   ///
16010b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
16020b57cec5SDimitry Andric   ///
OMPSimdDirective(unsigned CollapsedNum)1603e8d8bef9SDimitry Andric   explicit OMPSimdDirective(unsigned CollapsedNum)
1604e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd,
1605e8d8bef9SDimitry Andric                          SourceLocation(), SourceLocation(), CollapsedNum) {}
16060b57cec5SDimitry Andric 
16070b57cec5SDimitry Andric public:
16080b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
16090b57cec5SDimitry Andric   ///
16100b57cec5SDimitry Andric   /// \param C AST context.
16110b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
16120b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
16130b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
16140b57cec5SDimitry Andric   /// \param Clauses List of clauses.
16150b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
16160b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
16170b57cec5SDimitry Andric   ///
16180b57cec5SDimitry Andric   static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
16190b57cec5SDimitry Andric                                   SourceLocation EndLoc, unsigned CollapsedNum,
16200b57cec5SDimitry Andric                                   ArrayRef<OMPClause *> Clauses,
16210b57cec5SDimitry Andric                                   Stmt *AssociatedStmt,
16225f757f3fSDimitry Andric                                   const HelperExprs &Exprs,
16235f757f3fSDimitry Andric                                   OpenMPDirectiveKind ParamPrevMappedDirective);
16240b57cec5SDimitry Andric 
16250b57cec5SDimitry Andric   /// Creates an empty directive with the place
16260b57cec5SDimitry Andric   /// for \a NumClauses clauses.
16270b57cec5SDimitry Andric   ///
16280b57cec5SDimitry Andric   /// \param C AST context.
16290b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
16300b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
16310b57cec5SDimitry Andric   ///
16320b57cec5SDimitry Andric   static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
16330b57cec5SDimitry Andric                                        unsigned CollapsedNum, EmptyShell);
16340b57cec5SDimitry Andric 
classof(const Stmt * T)16350b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
16360b57cec5SDimitry Andric     return T->getStmtClass() == OMPSimdDirectiveClass;
16370b57cec5SDimitry Andric   }
16380b57cec5SDimitry Andric };
16390b57cec5SDimitry Andric 
16400b57cec5SDimitry Andric /// This represents '#pragma omp for' directive.
16410b57cec5SDimitry Andric ///
16420b57cec5SDimitry Andric /// \code
16430b57cec5SDimitry Andric /// #pragma omp for private(a,b) reduction(+:c,d)
16440b57cec5SDimitry Andric /// \endcode
16450b57cec5SDimitry Andric /// In this example directive '#pragma omp for' has clauses 'private' with the
16460b57cec5SDimitry Andric /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
16470b57cec5SDimitry Andric /// and 'd'.
16480b57cec5SDimitry Andric ///
16490b57cec5SDimitry Andric class OMPForDirective : public OMPLoopDirective {
16500b57cec5SDimitry Andric   friend class ASTStmtReader;
1651e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
16520b57cec5SDimitry Andric   /// true if current directive has inner cancel directive.
1653e8d8bef9SDimitry Andric   bool HasCancel = false;
16540b57cec5SDimitry Andric 
16550b57cec5SDimitry Andric   /// Build directive with the given start and end location.
16560b57cec5SDimitry Andric   ///
16570b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
16580b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
16590b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
16600b57cec5SDimitry Andric   ///
OMPForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)16610b57cec5SDimitry Andric   OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1662e8d8bef9SDimitry Andric                   unsigned CollapsedNum)
1663e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, StartLoc,
1664e8d8bef9SDimitry Andric                          EndLoc, CollapsedNum) {}
16650b57cec5SDimitry Andric 
16660b57cec5SDimitry Andric   /// Build an empty directive.
16670b57cec5SDimitry Andric   ///
16680b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
16690b57cec5SDimitry Andric   ///
OMPForDirective(unsigned CollapsedNum)1670e8d8bef9SDimitry Andric   explicit OMPForDirective(unsigned CollapsedNum)
1671e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for,
1672e8d8bef9SDimitry Andric                          SourceLocation(), SourceLocation(), CollapsedNum) {}
16730b57cec5SDimitry Andric 
16745ffd83dbSDimitry Andric   /// Sets special task reduction descriptor.
setTaskReductionRefExpr(Expr * E)1675e8d8bef9SDimitry Andric   void setTaskReductionRefExpr(Expr *E) {
1676fe6060f1SDimitry Andric     Data->getChildren()[numLoopChildren(getLoopsNumber(),
1677e8d8bef9SDimitry Andric                                         llvm::omp::OMPD_for)] = E;
1678e8d8bef9SDimitry Andric   }
16795ffd83dbSDimitry Andric 
16800b57cec5SDimitry Andric   /// Set cancel state.
setHasCancel(bool Has)16810b57cec5SDimitry Andric   void setHasCancel(bool Has) { HasCancel = Has; }
16820b57cec5SDimitry Andric 
16830b57cec5SDimitry Andric public:
16840b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
16850b57cec5SDimitry Andric   ///
16860b57cec5SDimitry Andric   /// \param C AST context.
16870b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
16880b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
16890b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
16900b57cec5SDimitry Andric   /// \param Clauses List of clauses.
16910b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
16920b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
16935ffd83dbSDimitry Andric   /// \param TaskRedRef Task reduction special reference expression to handle
16945ffd83dbSDimitry Andric   /// taskgroup descriptor.
16950b57cec5SDimitry Andric   /// \param HasCancel true if current directive has inner cancel directive.
16960b57cec5SDimitry Andric   ///
16970b57cec5SDimitry Andric   static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
16980b57cec5SDimitry Andric                                  SourceLocation EndLoc, unsigned CollapsedNum,
16990b57cec5SDimitry Andric                                  ArrayRef<OMPClause *> Clauses,
17000b57cec5SDimitry Andric                                  Stmt *AssociatedStmt, const HelperExprs &Exprs,
17015f757f3fSDimitry Andric                                  Expr *TaskRedRef, bool HasCancel,
17025f757f3fSDimitry Andric                                  OpenMPDirectiveKind ParamPrevMappedDirective);
17030b57cec5SDimitry Andric 
17040b57cec5SDimitry Andric   /// Creates an empty directive with the place
17050b57cec5SDimitry Andric   /// for \a NumClauses clauses.
17060b57cec5SDimitry Andric   ///
17070b57cec5SDimitry Andric   /// \param C AST context.
17080b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
17090b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
17100b57cec5SDimitry Andric   ///
17110b57cec5SDimitry Andric   static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
17120b57cec5SDimitry Andric                                       unsigned CollapsedNum, EmptyShell);
17130b57cec5SDimitry Andric 
17145ffd83dbSDimitry Andric   /// Returns special task reduction reference expression.
getTaskReductionRefExpr()1715e8d8bef9SDimitry Andric   Expr *getTaskReductionRefExpr() {
1716e8d8bef9SDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
1717fe6060f1SDimitry Andric         getLoopsNumber(), llvm::omp::OMPD_for)]);
1718e8d8bef9SDimitry Andric   }
getTaskReductionRefExpr()1719e8d8bef9SDimitry Andric   const Expr *getTaskReductionRefExpr() const {
1720e8d8bef9SDimitry Andric     return const_cast<OMPForDirective *>(this)->getTaskReductionRefExpr();
1721e8d8bef9SDimitry Andric   }
17225ffd83dbSDimitry Andric 
17230b57cec5SDimitry Andric   /// Return true if current directive has inner cancel directive.
hasCancel()17240b57cec5SDimitry Andric   bool hasCancel() const { return HasCancel; }
17250b57cec5SDimitry Andric 
classof(const Stmt * T)17260b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
17270b57cec5SDimitry Andric     return T->getStmtClass() == OMPForDirectiveClass;
17280b57cec5SDimitry Andric   }
17290b57cec5SDimitry Andric };
17300b57cec5SDimitry Andric 
17310b57cec5SDimitry Andric /// This represents '#pragma omp for simd' directive.
17320b57cec5SDimitry Andric ///
17330b57cec5SDimitry Andric /// \code
17340b57cec5SDimitry Andric /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
17350b57cec5SDimitry Andric /// \endcode
17360b57cec5SDimitry Andric /// In this example directive '#pragma omp for simd' has clauses 'private'
17370b57cec5SDimitry Andric /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
17380b57cec5SDimitry Andric /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
17390b57cec5SDimitry Andric ///
17400b57cec5SDimitry Andric class OMPForSimdDirective : public OMPLoopDirective {
17410b57cec5SDimitry Andric   friend class ASTStmtReader;
1742e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
17430b57cec5SDimitry Andric   /// Build directive with the given start and end location.
17440b57cec5SDimitry Andric   ///
17450b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
17460b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
17470b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
17480b57cec5SDimitry Andric   ///
OMPForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)17490b57cec5SDimitry Andric   OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1750e8d8bef9SDimitry Andric                       unsigned CollapsedNum)
1751e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
1752e8d8bef9SDimitry Andric                          StartLoc, EndLoc, CollapsedNum) {}
17530b57cec5SDimitry Andric 
17540b57cec5SDimitry Andric   /// Build an empty directive.
17550b57cec5SDimitry Andric   ///
17560b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
17570b57cec5SDimitry Andric   ///
OMPForSimdDirective(unsigned CollapsedNum)1758e8d8bef9SDimitry Andric   explicit OMPForSimdDirective(unsigned CollapsedNum)
1759e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
1760e8d8bef9SDimitry Andric                          SourceLocation(), SourceLocation(), CollapsedNum) {}
17610b57cec5SDimitry Andric 
17620b57cec5SDimitry Andric public:
17630b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
17640b57cec5SDimitry Andric   ///
17650b57cec5SDimitry Andric   /// \param C AST context.
17660b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
17670b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
17680b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
17690b57cec5SDimitry Andric   /// \param Clauses List of clauses.
17700b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
17710b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
17720b57cec5SDimitry Andric   ///
17730b57cec5SDimitry Andric   static OMPForSimdDirective *
17740b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
17750b57cec5SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
17760b57cec5SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
17770b57cec5SDimitry Andric 
17780b57cec5SDimitry Andric   /// Creates an empty directive with the place
17790b57cec5SDimitry Andric   /// for \a NumClauses clauses.
17800b57cec5SDimitry Andric   ///
17810b57cec5SDimitry Andric   /// \param C AST context.
17820b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
17830b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
17840b57cec5SDimitry Andric   ///
17850b57cec5SDimitry Andric   static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
17860b57cec5SDimitry Andric                                           unsigned NumClauses,
17870b57cec5SDimitry Andric                                           unsigned CollapsedNum, EmptyShell);
17880b57cec5SDimitry Andric 
classof(const Stmt * T)17890b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
17900b57cec5SDimitry Andric     return T->getStmtClass() == OMPForSimdDirectiveClass;
17910b57cec5SDimitry Andric   }
17920b57cec5SDimitry Andric };
17930b57cec5SDimitry Andric 
17940b57cec5SDimitry Andric /// This represents '#pragma omp sections' directive.
17950b57cec5SDimitry Andric ///
17960b57cec5SDimitry Andric /// \code
17970b57cec5SDimitry Andric /// #pragma omp sections private(a,b) reduction(+:c,d)
17980b57cec5SDimitry Andric /// \endcode
17990b57cec5SDimitry Andric /// In this example directive '#pragma omp sections' has clauses 'private' with
18000b57cec5SDimitry Andric /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
18010b57cec5SDimitry Andric /// 'c' and 'd'.
18020b57cec5SDimitry Andric ///
18030b57cec5SDimitry Andric class OMPSectionsDirective : public OMPExecutableDirective {
18040b57cec5SDimitry Andric   friend class ASTStmtReader;
1805e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
18060b57cec5SDimitry Andric 
18070b57cec5SDimitry Andric   /// true if current directive has inner cancel directive.
1808e8d8bef9SDimitry Andric   bool HasCancel = false;
18090b57cec5SDimitry Andric 
18100b57cec5SDimitry Andric   /// Build directive with the given start and end location.
18110b57cec5SDimitry Andric   ///
18120b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
18130b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
18140b57cec5SDimitry Andric   ///
OMPSectionsDirective(SourceLocation StartLoc,SourceLocation EndLoc)1815e8d8bef9SDimitry Andric   OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1816e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPSectionsDirectiveClass,
1817e8d8bef9SDimitry Andric                                llvm::omp::OMPD_sections, StartLoc, EndLoc) {}
18180b57cec5SDimitry Andric 
18190b57cec5SDimitry Andric   /// Build an empty directive.
18200b57cec5SDimitry Andric   ///
OMPSectionsDirective()1821e8d8bef9SDimitry Andric   explicit OMPSectionsDirective()
1822e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPSectionsDirectiveClass,
1823480093f4SDimitry Andric                                llvm::omp::OMPD_sections, SourceLocation(),
1824e8d8bef9SDimitry Andric                                SourceLocation()) {}
18250b57cec5SDimitry Andric 
18265ffd83dbSDimitry Andric   /// Sets special task reduction descriptor.
setTaskReductionRefExpr(Expr * E)1827e8d8bef9SDimitry Andric   void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
18285ffd83dbSDimitry Andric 
18290b57cec5SDimitry Andric   /// Set cancel state.
setHasCancel(bool Has)18300b57cec5SDimitry Andric   void setHasCancel(bool Has) { HasCancel = Has; }
18310b57cec5SDimitry Andric 
18320b57cec5SDimitry Andric public:
18330b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
18340b57cec5SDimitry Andric   ///
18350b57cec5SDimitry Andric   /// \param C AST context.
18360b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
18370b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
18380b57cec5SDimitry Andric   /// \param Clauses List of clauses.
18390b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
18405ffd83dbSDimitry Andric   /// \param TaskRedRef Task reduction special reference expression to handle
18415ffd83dbSDimitry Andric   /// taskgroup descriptor.
18420b57cec5SDimitry Andric   /// \param HasCancel true if current directive has inner directive.
18430b57cec5SDimitry Andric   ///
18440b57cec5SDimitry Andric   static OMPSectionsDirective *
18450b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
18465ffd83dbSDimitry Andric          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
18475ffd83dbSDimitry Andric          bool HasCancel);
18480b57cec5SDimitry Andric 
18490b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses
18500b57cec5SDimitry Andric   /// clauses.
18510b57cec5SDimitry Andric   ///
18520b57cec5SDimitry Andric   /// \param C AST context.
18530b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
18540b57cec5SDimitry Andric   ///
18550b57cec5SDimitry Andric   static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
18560b57cec5SDimitry Andric                                            unsigned NumClauses, EmptyShell);
18570b57cec5SDimitry Andric 
18585ffd83dbSDimitry Andric   /// Returns special task reduction reference expression.
getTaskReductionRefExpr()1859e8d8bef9SDimitry Andric   Expr *getTaskReductionRefExpr() {
1860e8d8bef9SDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[0]);
1861e8d8bef9SDimitry Andric   }
getTaskReductionRefExpr()1862e8d8bef9SDimitry Andric   const Expr *getTaskReductionRefExpr() const {
1863e8d8bef9SDimitry Andric     return const_cast<OMPSectionsDirective *>(this)->getTaskReductionRefExpr();
1864e8d8bef9SDimitry Andric   }
18655ffd83dbSDimitry Andric 
18660b57cec5SDimitry Andric   /// Return true if current directive has inner cancel directive.
hasCancel()18670b57cec5SDimitry Andric   bool hasCancel() const { return HasCancel; }
18680b57cec5SDimitry Andric 
classof(const Stmt * T)18690b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
18700b57cec5SDimitry Andric     return T->getStmtClass() == OMPSectionsDirectiveClass;
18710b57cec5SDimitry Andric   }
18720b57cec5SDimitry Andric };
18730b57cec5SDimitry Andric 
18740b57cec5SDimitry Andric /// This represents '#pragma omp section' directive.
18750b57cec5SDimitry Andric ///
18760b57cec5SDimitry Andric /// \code
18770b57cec5SDimitry Andric /// #pragma omp section
18780b57cec5SDimitry Andric /// \endcode
18790b57cec5SDimitry Andric ///
18800b57cec5SDimitry Andric class OMPSectionDirective : public OMPExecutableDirective {
18810b57cec5SDimitry Andric   friend class ASTStmtReader;
1882e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
18830b57cec5SDimitry Andric 
18840b57cec5SDimitry Andric   /// true if current directive has inner cancel directive.
1885e8d8bef9SDimitry Andric   bool HasCancel = false;
18860b57cec5SDimitry Andric 
18870b57cec5SDimitry Andric   /// Build directive with the given start and end location.
18880b57cec5SDimitry Andric   ///
18890b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
18900b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
18910b57cec5SDimitry Andric   ///
OMPSectionDirective(SourceLocation StartLoc,SourceLocation EndLoc)18920b57cec5SDimitry Andric   OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1893e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPSectionDirectiveClass,
1894e8d8bef9SDimitry Andric                                llvm::omp::OMPD_section, StartLoc, EndLoc) {}
18950b57cec5SDimitry Andric 
18960b57cec5SDimitry Andric   /// Build an empty directive.
18970b57cec5SDimitry Andric   ///
OMPSectionDirective()18980b57cec5SDimitry Andric   explicit OMPSectionDirective()
1899e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPSectionDirectiveClass,
1900480093f4SDimitry Andric                                llvm::omp::OMPD_section, SourceLocation(),
1901e8d8bef9SDimitry Andric                                SourceLocation()) {}
19020b57cec5SDimitry Andric 
19030b57cec5SDimitry Andric public:
19040b57cec5SDimitry Andric   /// Creates directive.
19050b57cec5SDimitry Andric   ///
19060b57cec5SDimitry Andric   /// \param C AST context.
19070b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
19080b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
19090b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
19100b57cec5SDimitry Andric   /// \param HasCancel true if current directive has inner directive.
19110b57cec5SDimitry Andric   ///
19120b57cec5SDimitry Andric   static OMPSectionDirective *Create(const ASTContext &C,
19130b57cec5SDimitry Andric                                      SourceLocation StartLoc,
19140b57cec5SDimitry Andric                                      SourceLocation EndLoc,
19150b57cec5SDimitry Andric                                      Stmt *AssociatedStmt, bool HasCancel);
19160b57cec5SDimitry Andric 
19170b57cec5SDimitry Andric   /// Creates an empty directive.
19180b57cec5SDimitry Andric   ///
19190b57cec5SDimitry Andric   /// \param C AST context.
19200b57cec5SDimitry Andric   ///
19210b57cec5SDimitry Andric   static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
19220b57cec5SDimitry Andric 
19230b57cec5SDimitry Andric   /// Set cancel state.
setHasCancel(bool Has)19240b57cec5SDimitry Andric   void setHasCancel(bool Has) { HasCancel = Has; }
19250b57cec5SDimitry Andric 
19260b57cec5SDimitry Andric   /// Return true if current directive has inner cancel directive.
hasCancel()19270b57cec5SDimitry Andric   bool hasCancel() const { return HasCancel; }
19280b57cec5SDimitry Andric 
classof(const Stmt * T)19290b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
19300b57cec5SDimitry Andric     return T->getStmtClass() == OMPSectionDirectiveClass;
19310b57cec5SDimitry Andric   }
19320b57cec5SDimitry Andric };
19330b57cec5SDimitry Andric 
19345f757f3fSDimitry Andric /// This represents '#pragma omp scope' directive.
19355f757f3fSDimitry Andric /// \code
19365f757f3fSDimitry Andric /// #pragma omp scope private(a,b) nowait
19375f757f3fSDimitry Andric /// \endcode
19385f757f3fSDimitry Andric /// In this example directive '#pragma omp scope' has clauses 'private' with
19395f757f3fSDimitry Andric /// the variables 'a' and 'b' and nowait.
19405f757f3fSDimitry Andric ///
19415f757f3fSDimitry Andric class OMPScopeDirective final : public OMPExecutableDirective {
19425f757f3fSDimitry Andric   friend class ASTStmtReader;
19435f757f3fSDimitry Andric   friend class OMPExecutableDirective;
19445f757f3fSDimitry Andric 
19455f757f3fSDimitry Andric   /// Build directive with the given start and end location.
19465f757f3fSDimitry Andric   ///
19475f757f3fSDimitry Andric   /// \param StartLoc Starting location of the directive kind.
19485f757f3fSDimitry Andric   /// \param EndLoc Ending location of the directive.
19495f757f3fSDimitry Andric   ///
OMPScopeDirective(SourceLocation StartLoc,SourceLocation EndLoc)19505f757f3fSDimitry Andric   OMPScopeDirective(SourceLocation StartLoc, SourceLocation EndLoc)
19515f757f3fSDimitry Andric       : OMPExecutableDirective(OMPScopeDirectiveClass, llvm::omp::OMPD_scope,
19525f757f3fSDimitry Andric                                StartLoc, EndLoc) {}
19535f757f3fSDimitry Andric 
19545f757f3fSDimitry Andric   /// Build an empty directive.
19555f757f3fSDimitry Andric   ///
OMPScopeDirective()19565f757f3fSDimitry Andric   explicit OMPScopeDirective()
19575f757f3fSDimitry Andric       : OMPExecutableDirective(OMPScopeDirectiveClass, llvm::omp::OMPD_scope,
19585f757f3fSDimitry Andric                                SourceLocation(), SourceLocation()) {}
19595f757f3fSDimitry Andric 
19605f757f3fSDimitry Andric public:
19615f757f3fSDimitry Andric   /// Creates directive.
19625f757f3fSDimitry Andric   ///
19635f757f3fSDimitry Andric   /// \param C AST context.
19645f757f3fSDimitry Andric   /// \param StartLoc Starting location of the directive kind.
19655f757f3fSDimitry Andric   /// \param EndLoc Ending Location of the directive.
19665f757f3fSDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
19675f757f3fSDimitry Andric   ///
19685f757f3fSDimitry Andric   static OMPScopeDirective *Create(const ASTContext &C, SourceLocation StartLoc,
19695f757f3fSDimitry Andric                                    SourceLocation EndLoc,
19705f757f3fSDimitry Andric                                    ArrayRef<OMPClause *> Clauses,
19715f757f3fSDimitry Andric                                    Stmt *AssociatedStmt);
19725f757f3fSDimitry Andric 
19735f757f3fSDimitry Andric   /// Creates an empty directive.
19745f757f3fSDimitry Andric   ///
19755f757f3fSDimitry Andric   /// \param C AST context.
19765f757f3fSDimitry Andric   ///
19775f757f3fSDimitry Andric   static OMPScopeDirective *CreateEmpty(const ASTContext &C,
19785f757f3fSDimitry Andric                                         unsigned NumClauses, EmptyShell);
19795f757f3fSDimitry Andric 
classof(const Stmt * T)19805f757f3fSDimitry Andric   static bool classof(const Stmt *T) {
19815f757f3fSDimitry Andric     return T->getStmtClass() == OMPScopeDirectiveClass;
19825f757f3fSDimitry Andric   }
19835f757f3fSDimitry Andric };
19845f757f3fSDimitry Andric 
19850b57cec5SDimitry Andric /// This represents '#pragma omp single' directive.
19860b57cec5SDimitry Andric ///
19870b57cec5SDimitry Andric /// \code
19880b57cec5SDimitry Andric /// #pragma omp single private(a,b) copyprivate(c,d)
19890b57cec5SDimitry Andric /// \endcode
19900b57cec5SDimitry Andric /// In this example directive '#pragma omp single' has clauses 'private' with
19910b57cec5SDimitry Andric /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
19920b57cec5SDimitry Andric ///
19930b57cec5SDimitry Andric class OMPSingleDirective : public OMPExecutableDirective {
19940b57cec5SDimitry Andric   friend class ASTStmtReader;
1995e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
19960b57cec5SDimitry Andric   /// Build directive with the given start and end location.
19970b57cec5SDimitry Andric   ///
19980b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
19990b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
20000b57cec5SDimitry Andric   ///
OMPSingleDirective(SourceLocation StartLoc,SourceLocation EndLoc)2001e8d8bef9SDimitry Andric   OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2002e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
2003e8d8bef9SDimitry Andric                                StartLoc, EndLoc) {}
20040b57cec5SDimitry Andric 
20050b57cec5SDimitry Andric   /// Build an empty directive.
20060b57cec5SDimitry Andric   ///
OMPSingleDirective()2007e8d8bef9SDimitry Andric   explicit OMPSingleDirective()
2008e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
2009e8d8bef9SDimitry Andric                                SourceLocation(), SourceLocation()) {}
20100b57cec5SDimitry Andric 
20110b57cec5SDimitry Andric public:
20120b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
20130b57cec5SDimitry Andric   ///
20140b57cec5SDimitry Andric   /// \param C AST context.
20150b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
20160b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
20170b57cec5SDimitry Andric   /// \param Clauses List of clauses.
20180b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
20190b57cec5SDimitry Andric   ///
20200b57cec5SDimitry Andric   static OMPSingleDirective *
20210b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
20220b57cec5SDimitry Andric          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
20230b57cec5SDimitry Andric 
20240b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses
20250b57cec5SDimitry Andric   /// clauses.
20260b57cec5SDimitry Andric   ///
20270b57cec5SDimitry Andric   /// \param C AST context.
20280b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
20290b57cec5SDimitry Andric   ///
20300b57cec5SDimitry Andric   static OMPSingleDirective *CreateEmpty(const ASTContext &C,
20310b57cec5SDimitry Andric                                          unsigned NumClauses, EmptyShell);
20320b57cec5SDimitry Andric 
classof(const Stmt * T)20330b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
20340b57cec5SDimitry Andric     return T->getStmtClass() == OMPSingleDirectiveClass;
20350b57cec5SDimitry Andric   }
20360b57cec5SDimitry Andric };
20370b57cec5SDimitry Andric 
20380b57cec5SDimitry Andric /// This represents '#pragma omp master' directive.
20390b57cec5SDimitry Andric ///
20400b57cec5SDimitry Andric /// \code
20410b57cec5SDimitry Andric /// #pragma omp master
20420b57cec5SDimitry Andric /// \endcode
20430b57cec5SDimitry Andric ///
20440b57cec5SDimitry Andric class OMPMasterDirective : public OMPExecutableDirective {
20450b57cec5SDimitry Andric   friend class ASTStmtReader;
2046e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
20470b57cec5SDimitry Andric   /// Build directive with the given start and end location.
20480b57cec5SDimitry Andric   ///
20490b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
20500b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
20510b57cec5SDimitry Andric   ///
OMPMasterDirective(SourceLocation StartLoc,SourceLocation EndLoc)20520b57cec5SDimitry Andric   OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2053e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
2054e8d8bef9SDimitry Andric                                StartLoc, EndLoc) {}
20550b57cec5SDimitry Andric 
20560b57cec5SDimitry Andric   /// Build an empty directive.
20570b57cec5SDimitry Andric   ///
OMPMasterDirective()20580b57cec5SDimitry Andric   explicit OMPMasterDirective()
2059e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
2060e8d8bef9SDimitry Andric                                SourceLocation(), SourceLocation()) {}
20610b57cec5SDimitry Andric 
20620b57cec5SDimitry Andric public:
20630b57cec5SDimitry Andric   /// Creates directive.
20640b57cec5SDimitry Andric   ///
20650b57cec5SDimitry Andric   /// \param C AST context.
20660b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
20670b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
20680b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
20690b57cec5SDimitry Andric   ///
20700b57cec5SDimitry Andric   static OMPMasterDirective *Create(const ASTContext &C,
20710b57cec5SDimitry Andric                                     SourceLocation StartLoc,
20720b57cec5SDimitry Andric                                     SourceLocation EndLoc,
20730b57cec5SDimitry Andric                                     Stmt *AssociatedStmt);
20740b57cec5SDimitry Andric 
20750b57cec5SDimitry Andric   /// Creates an empty directive.
20760b57cec5SDimitry Andric   ///
20770b57cec5SDimitry Andric   /// \param C AST context.
20780b57cec5SDimitry Andric   ///
20790b57cec5SDimitry Andric   static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
20800b57cec5SDimitry Andric 
classof(const Stmt * T)20810b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
20820b57cec5SDimitry Andric     return T->getStmtClass() == OMPMasterDirectiveClass;
20830b57cec5SDimitry Andric   }
20840b57cec5SDimitry Andric };
20850b57cec5SDimitry Andric 
20860b57cec5SDimitry Andric /// This represents '#pragma omp critical' directive.
20870b57cec5SDimitry Andric ///
20880b57cec5SDimitry Andric /// \code
20890b57cec5SDimitry Andric /// #pragma omp critical
20900b57cec5SDimitry Andric /// \endcode
20910b57cec5SDimitry Andric ///
20920b57cec5SDimitry Andric class OMPCriticalDirective : public OMPExecutableDirective {
20930b57cec5SDimitry Andric   friend class ASTStmtReader;
2094e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
20950b57cec5SDimitry Andric   /// Name of the directive.
20960b57cec5SDimitry Andric   DeclarationNameInfo DirName;
20970b57cec5SDimitry Andric   /// Build directive with the given start and end location.
20980b57cec5SDimitry Andric   ///
20990b57cec5SDimitry Andric   /// \param Name Name of the directive.
21000b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
21010b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
21020b57cec5SDimitry Andric   ///
OMPCriticalDirective(const DeclarationNameInfo & Name,SourceLocation StartLoc,SourceLocation EndLoc)21030b57cec5SDimitry Andric   OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
2104e8d8bef9SDimitry Andric                        SourceLocation EndLoc)
2105e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPCriticalDirectiveClass,
2106e8d8bef9SDimitry Andric                                llvm::omp::OMPD_critical, StartLoc, EndLoc),
21070b57cec5SDimitry Andric         DirName(Name) {}
21080b57cec5SDimitry Andric 
21090b57cec5SDimitry Andric   /// Build an empty directive.
21100b57cec5SDimitry Andric   ///
OMPCriticalDirective()2111e8d8bef9SDimitry Andric   explicit OMPCriticalDirective()
2112e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPCriticalDirectiveClass,
2113480093f4SDimitry Andric                                llvm::omp::OMPD_critical, SourceLocation(),
2114e8d8bef9SDimitry Andric                                SourceLocation()) {}
21150b57cec5SDimitry Andric 
21160b57cec5SDimitry Andric   /// Set name of the directive.
21170b57cec5SDimitry Andric   ///
21180b57cec5SDimitry Andric   /// \param Name Name of the directive.
21190b57cec5SDimitry Andric   ///
setDirectiveName(const DeclarationNameInfo & Name)21200b57cec5SDimitry Andric   void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
21210b57cec5SDimitry Andric 
21220b57cec5SDimitry Andric public:
21230b57cec5SDimitry Andric   /// Creates directive.
21240b57cec5SDimitry Andric   ///
21250b57cec5SDimitry Andric   /// \param C AST context.
21260b57cec5SDimitry Andric   /// \param Name Name of the directive.
21270b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
21280b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
21290b57cec5SDimitry Andric   /// \param Clauses List of clauses.
21300b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
21310b57cec5SDimitry Andric   ///
21320b57cec5SDimitry Andric   static OMPCriticalDirective *
21330b57cec5SDimitry Andric   Create(const ASTContext &C, const DeclarationNameInfo &Name,
21340b57cec5SDimitry Andric          SourceLocation StartLoc, SourceLocation EndLoc,
21350b57cec5SDimitry Andric          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
21360b57cec5SDimitry Andric 
21370b57cec5SDimitry Andric   /// Creates an empty directive.
21380b57cec5SDimitry Andric   ///
21390b57cec5SDimitry Andric   /// \param C AST context.
21400b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
21410b57cec5SDimitry Andric   ///
21420b57cec5SDimitry Andric   static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
21430b57cec5SDimitry Andric                                            unsigned NumClauses, EmptyShell);
21440b57cec5SDimitry Andric 
21450b57cec5SDimitry Andric   /// Return name of the directive.
21460b57cec5SDimitry Andric   ///
getDirectiveName()21470b57cec5SDimitry Andric   DeclarationNameInfo getDirectiveName() const { return DirName; }
21480b57cec5SDimitry Andric 
classof(const Stmt * T)21490b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
21500b57cec5SDimitry Andric     return T->getStmtClass() == OMPCriticalDirectiveClass;
21510b57cec5SDimitry Andric   }
21520b57cec5SDimitry Andric };
21530b57cec5SDimitry Andric 
21540b57cec5SDimitry Andric /// This represents '#pragma omp parallel for' directive.
21550b57cec5SDimitry Andric ///
21560b57cec5SDimitry Andric /// \code
21570b57cec5SDimitry Andric /// #pragma omp parallel for private(a,b) reduction(+:c,d)
21580b57cec5SDimitry Andric /// \endcode
21590b57cec5SDimitry Andric /// In this example directive '#pragma omp parallel for' has clauses 'private'
21600b57cec5SDimitry Andric /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
21610b57cec5SDimitry Andric /// variables 'c' and 'd'.
21620b57cec5SDimitry Andric ///
21630b57cec5SDimitry Andric class OMPParallelForDirective : public OMPLoopDirective {
21640b57cec5SDimitry Andric   friend class ASTStmtReader;
2165e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
21660b57cec5SDimitry Andric 
21670b57cec5SDimitry Andric   /// true if current region has inner cancel directive.
2168e8d8bef9SDimitry Andric   bool HasCancel = false;
21690b57cec5SDimitry Andric 
21700b57cec5SDimitry Andric   /// Build directive with the given start and end location.
21710b57cec5SDimitry Andric   ///
21720b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
21730b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
21740b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
21750b57cec5SDimitry Andric   ///
OMPParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)21760b57cec5SDimitry Andric   OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2177e8d8bef9SDimitry Andric                           unsigned CollapsedNum)
2178e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPParallelForDirectiveClass,
2179480093f4SDimitry Andric                          llvm::omp::OMPD_parallel_for, StartLoc, EndLoc,
2180e8d8bef9SDimitry Andric                          CollapsedNum) {}
21810b57cec5SDimitry Andric 
21820b57cec5SDimitry Andric   /// Build an empty directive.
21830b57cec5SDimitry Andric   ///
21840b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
21850b57cec5SDimitry Andric   ///
OMPParallelForDirective(unsigned CollapsedNum)2186e8d8bef9SDimitry Andric   explicit OMPParallelForDirective(unsigned CollapsedNum)
2187e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPParallelForDirectiveClass,
2188480093f4SDimitry Andric                          llvm::omp::OMPD_parallel_for, SourceLocation(),
2189e8d8bef9SDimitry Andric                          SourceLocation(), CollapsedNum) {}
21900b57cec5SDimitry Andric 
21915ffd83dbSDimitry Andric   /// Sets special task reduction descriptor.
setTaskReductionRefExpr(Expr * E)2192e8d8bef9SDimitry Andric   void setTaskReductionRefExpr(Expr *E) {
2193fe6060f1SDimitry Andric     Data->getChildren()[numLoopChildren(getLoopsNumber(),
2194e8d8bef9SDimitry Andric                                         llvm::omp::OMPD_parallel_for)] = E;
2195e8d8bef9SDimitry Andric   }
21965ffd83dbSDimitry Andric 
21970b57cec5SDimitry Andric   /// Set cancel state.
setHasCancel(bool Has)21980b57cec5SDimitry Andric   void setHasCancel(bool Has) { HasCancel = Has; }
21990b57cec5SDimitry Andric 
22000b57cec5SDimitry Andric public:
22010b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
22020b57cec5SDimitry Andric   ///
22030b57cec5SDimitry Andric   /// \param C AST context.
22040b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
22050b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
22060b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
22070b57cec5SDimitry Andric   /// \param Clauses List of clauses.
22080b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
22090b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
22105ffd83dbSDimitry Andric   /// \param TaskRedRef Task reduction special reference expression to handle
22115ffd83dbSDimitry Andric   /// taskgroup descriptor.
22120b57cec5SDimitry Andric   /// \param HasCancel true if current directive has inner cancel directive.
22130b57cec5SDimitry Andric   ///
22140b57cec5SDimitry Andric   static OMPParallelForDirective *
22150b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
22160b57cec5SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
22175ffd83dbSDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
22185ffd83dbSDimitry Andric          bool HasCancel);
22190b57cec5SDimitry Andric 
22200b57cec5SDimitry Andric   /// Creates an empty directive with the place
22210b57cec5SDimitry Andric   /// for \a NumClauses clauses.
22220b57cec5SDimitry Andric   ///
22230b57cec5SDimitry Andric   /// \param C AST context.
22240b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
22250b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
22260b57cec5SDimitry Andric   ///
22270b57cec5SDimitry Andric   static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
22280b57cec5SDimitry Andric                                               unsigned NumClauses,
22290b57cec5SDimitry Andric                                               unsigned CollapsedNum,
22300b57cec5SDimitry Andric                                               EmptyShell);
22310b57cec5SDimitry Andric 
22325ffd83dbSDimitry Andric   /// Returns special task reduction reference expression.
getTaskReductionRefExpr()2233e8d8bef9SDimitry Andric   Expr *getTaskReductionRefExpr() {
2234e8d8bef9SDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
2235fe6060f1SDimitry Andric         getLoopsNumber(), llvm::omp::OMPD_parallel_for)]);
2236e8d8bef9SDimitry Andric   }
getTaskReductionRefExpr()2237e8d8bef9SDimitry Andric   const Expr *getTaskReductionRefExpr() const {
2238e8d8bef9SDimitry Andric     return const_cast<OMPParallelForDirective *>(this)
2239e8d8bef9SDimitry Andric         ->getTaskReductionRefExpr();
2240e8d8bef9SDimitry Andric   }
22415ffd83dbSDimitry Andric 
22420b57cec5SDimitry Andric   /// Return true if current directive has inner cancel directive.
hasCancel()22430b57cec5SDimitry Andric   bool hasCancel() const { return HasCancel; }
22440b57cec5SDimitry Andric 
classof(const Stmt * T)22450b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
22460b57cec5SDimitry Andric     return T->getStmtClass() == OMPParallelForDirectiveClass;
22470b57cec5SDimitry Andric   }
22480b57cec5SDimitry Andric };
22490b57cec5SDimitry Andric 
22500b57cec5SDimitry Andric /// This represents '#pragma omp parallel for simd' directive.
22510b57cec5SDimitry Andric ///
22520b57cec5SDimitry Andric /// \code
22530b57cec5SDimitry Andric /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
22540b57cec5SDimitry Andric /// \endcode
22550b57cec5SDimitry Andric /// In this example directive '#pragma omp parallel for simd' has clauses
22560b57cec5SDimitry Andric /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
22570b57cec5SDimitry Andric /// and linear step 's', 'reduction' with operator '+' and variables 'c' and
22580b57cec5SDimitry Andric /// 'd'.
22590b57cec5SDimitry Andric ///
22600b57cec5SDimitry Andric class OMPParallelForSimdDirective : public OMPLoopDirective {
22610b57cec5SDimitry Andric   friend class ASTStmtReader;
2262e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
22630b57cec5SDimitry Andric   /// Build directive with the given start and end location.
22640b57cec5SDimitry Andric   ///
22650b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
22660b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
22670b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
22680b57cec5SDimitry Andric   ///
OMPParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)22690b57cec5SDimitry Andric   OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2270e8d8bef9SDimitry Andric                               unsigned CollapsedNum)
2271e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
2272480093f4SDimitry Andric                          llvm::omp::OMPD_parallel_for_simd, StartLoc, EndLoc,
2273e8d8bef9SDimitry Andric                          CollapsedNum) {}
22740b57cec5SDimitry Andric 
22750b57cec5SDimitry Andric   /// Build an empty directive.
22760b57cec5SDimitry Andric   ///
22770b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
22780b57cec5SDimitry Andric   ///
OMPParallelForSimdDirective(unsigned CollapsedNum)2279e8d8bef9SDimitry Andric   explicit OMPParallelForSimdDirective(unsigned CollapsedNum)
2280e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
2281480093f4SDimitry Andric                          llvm::omp::OMPD_parallel_for_simd, SourceLocation(),
2282e8d8bef9SDimitry Andric                          SourceLocation(), CollapsedNum) {}
22830b57cec5SDimitry Andric 
22840b57cec5SDimitry Andric public:
22850b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
22860b57cec5SDimitry Andric   ///
22870b57cec5SDimitry Andric   /// \param C AST context.
22880b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
22890b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
22900b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
22910b57cec5SDimitry Andric   /// \param Clauses List of clauses.
22920b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
22930b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
22940b57cec5SDimitry Andric   ///
22950b57cec5SDimitry Andric   static OMPParallelForSimdDirective *
22960b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
22970b57cec5SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
22980b57cec5SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
22990b57cec5SDimitry Andric 
23000b57cec5SDimitry Andric   /// Creates an empty directive with the place
23010b57cec5SDimitry Andric   /// for \a NumClauses clauses.
23020b57cec5SDimitry Andric   ///
23030b57cec5SDimitry Andric   /// \param C AST context.
23040b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
23050b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
23060b57cec5SDimitry Andric   ///
23070b57cec5SDimitry Andric   static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
23080b57cec5SDimitry Andric                                                   unsigned NumClauses,
23090b57cec5SDimitry Andric                                                   unsigned CollapsedNum,
23100b57cec5SDimitry Andric                                                   EmptyShell);
23110b57cec5SDimitry Andric 
classof(const Stmt * T)23120b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
23130b57cec5SDimitry Andric     return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
23140b57cec5SDimitry Andric   }
23150b57cec5SDimitry Andric };
23160b57cec5SDimitry Andric 
2317480093f4SDimitry Andric /// This represents '#pragma omp parallel master' directive.
2318480093f4SDimitry Andric ///
2319480093f4SDimitry Andric /// \code
2320480093f4SDimitry Andric /// #pragma omp parallel master private(a,b)
2321480093f4SDimitry Andric /// \endcode
2322480093f4SDimitry Andric /// In this example directive '#pragma omp parallel master' has clauses
2323480093f4SDimitry Andric /// 'private' with the variables 'a' and 'b'
2324480093f4SDimitry Andric ///
2325480093f4SDimitry Andric class OMPParallelMasterDirective : public OMPExecutableDirective {
2326480093f4SDimitry Andric   friend class ASTStmtReader;
2327e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
2328480093f4SDimitry Andric 
OMPParallelMasterDirective(SourceLocation StartLoc,SourceLocation EndLoc)2329e8d8bef9SDimitry Andric   OMPParallelMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2330e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
2331480093f4SDimitry Andric                                llvm::omp::OMPD_parallel_master, StartLoc,
2332e8d8bef9SDimitry Andric                                EndLoc) {}
2333480093f4SDimitry Andric 
OMPParallelMasterDirective()2334e8d8bef9SDimitry Andric   explicit OMPParallelMasterDirective()
2335e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
2336480093f4SDimitry Andric                                llvm::omp::OMPD_parallel_master,
2337e8d8bef9SDimitry Andric                                SourceLocation(), SourceLocation()) {}
2338480093f4SDimitry Andric 
23395ffd83dbSDimitry Andric   /// Sets special task reduction descriptor.
setTaskReductionRefExpr(Expr * E)2340e8d8bef9SDimitry Andric   void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
23415ffd83dbSDimitry Andric 
2342480093f4SDimitry Andric public:
2343480093f4SDimitry Andric   /// Creates directive with a list of \a Clauses.
2344480093f4SDimitry Andric   ///
2345480093f4SDimitry Andric   /// \param C AST context.
2346480093f4SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
2347480093f4SDimitry Andric   /// \param EndLoc Ending Location of the directive.
2348480093f4SDimitry Andric   /// \param Clauses List of clauses.
2349480093f4SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
23505ffd83dbSDimitry Andric   /// \param TaskRedRef Task reduction special reference expression to handle
23515ffd83dbSDimitry Andric   /// taskgroup descriptor.
2352480093f4SDimitry Andric   ///
2353480093f4SDimitry Andric   static OMPParallelMasterDirective *
2354480093f4SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
23555ffd83dbSDimitry Andric          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
2356480093f4SDimitry Andric 
2357480093f4SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses
2358480093f4SDimitry Andric   /// clauses.
2359480093f4SDimitry Andric   ///
2360480093f4SDimitry Andric   /// \param C AST context.
2361480093f4SDimitry Andric   /// \param NumClauses Number of clauses.
2362480093f4SDimitry Andric   ///
2363480093f4SDimitry Andric   static OMPParallelMasterDirective *
2364480093f4SDimitry Andric   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2365480093f4SDimitry Andric 
23665ffd83dbSDimitry Andric   /// Returns special task reduction reference expression.
getTaskReductionRefExpr()2367e8d8bef9SDimitry Andric   Expr *getTaskReductionRefExpr() {
2368e8d8bef9SDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[0]);
2369e8d8bef9SDimitry Andric   }
getTaskReductionRefExpr()2370e8d8bef9SDimitry Andric   const Expr *getTaskReductionRefExpr() const {
2371e8d8bef9SDimitry Andric     return const_cast<OMPParallelMasterDirective *>(this)
2372e8d8bef9SDimitry Andric         ->getTaskReductionRefExpr();
2373e8d8bef9SDimitry Andric   }
23745ffd83dbSDimitry Andric 
classof(const Stmt * T)2375480093f4SDimitry Andric   static bool classof(const Stmt *T) {
2376480093f4SDimitry Andric     return T->getStmtClass() == OMPParallelMasterDirectiveClass;
2377480093f4SDimitry Andric   }
2378480093f4SDimitry Andric };
2379480093f4SDimitry Andric 
238081ad6265SDimitry Andric /// This represents '#pragma omp parallel masked' directive.
238181ad6265SDimitry Andric ///
238281ad6265SDimitry Andric /// \code
238381ad6265SDimitry Andric /// #pragma omp parallel masked filter(tid)
238481ad6265SDimitry Andric /// \endcode
238581ad6265SDimitry Andric /// In this example directive '#pragma omp parallel masked' has a clause
238681ad6265SDimitry Andric /// 'filter' with the variable tid
238781ad6265SDimitry Andric ///
238881ad6265SDimitry Andric class OMPParallelMaskedDirective final : public OMPExecutableDirective {
238981ad6265SDimitry Andric   friend class ASTStmtReader;
239081ad6265SDimitry Andric   friend class OMPExecutableDirective;
239181ad6265SDimitry Andric 
OMPParallelMaskedDirective(SourceLocation StartLoc,SourceLocation EndLoc)239281ad6265SDimitry Andric   OMPParallelMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
239381ad6265SDimitry Andric       : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
239481ad6265SDimitry Andric                                llvm::omp::OMPD_parallel_masked, StartLoc,
239581ad6265SDimitry Andric                                EndLoc) {}
239681ad6265SDimitry Andric 
OMPParallelMaskedDirective()239781ad6265SDimitry Andric   explicit OMPParallelMaskedDirective()
239881ad6265SDimitry Andric       : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
239981ad6265SDimitry Andric                                llvm::omp::OMPD_parallel_masked,
240081ad6265SDimitry Andric                                SourceLocation(), SourceLocation()) {}
240181ad6265SDimitry Andric 
240281ad6265SDimitry Andric   /// Sets special task reduction descriptor.
setTaskReductionRefExpr(Expr * E)240381ad6265SDimitry Andric   void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
240481ad6265SDimitry Andric 
240581ad6265SDimitry Andric public:
240681ad6265SDimitry Andric   /// Creates directive with a list of \a Clauses.
240781ad6265SDimitry Andric   ///
240881ad6265SDimitry Andric   /// \param C AST context.
240981ad6265SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
241081ad6265SDimitry Andric   /// \param EndLoc Ending Location of the directive.
241181ad6265SDimitry Andric   /// \param Clauses List of clauses.
241281ad6265SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
241381ad6265SDimitry Andric   /// \param TaskRedRef Task reduction special reference expression to handle
241481ad6265SDimitry Andric   /// taskgroup descriptor.
241581ad6265SDimitry Andric   ///
241681ad6265SDimitry Andric   static OMPParallelMaskedDirective *
241781ad6265SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
241881ad6265SDimitry Andric          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
241981ad6265SDimitry Andric 
242081ad6265SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses
242181ad6265SDimitry Andric   /// clauses.
242281ad6265SDimitry Andric   ///
242381ad6265SDimitry Andric   /// \param C AST context.
242481ad6265SDimitry Andric   /// \param NumClauses Number of clauses.
242581ad6265SDimitry Andric   ///
242681ad6265SDimitry Andric   static OMPParallelMaskedDirective *
242781ad6265SDimitry Andric   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
242881ad6265SDimitry Andric 
242981ad6265SDimitry Andric   /// Returns special task reduction reference expression.
getTaskReductionRefExpr()243081ad6265SDimitry Andric   Expr *getTaskReductionRefExpr() {
243181ad6265SDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[0]);
243281ad6265SDimitry Andric   }
getTaskReductionRefExpr()243381ad6265SDimitry Andric   const Expr *getTaskReductionRefExpr() const {
243481ad6265SDimitry Andric     return const_cast<OMPParallelMaskedDirective *>(this)
243581ad6265SDimitry Andric         ->getTaskReductionRefExpr();
243681ad6265SDimitry Andric   }
243781ad6265SDimitry Andric 
classof(const Stmt * T)243881ad6265SDimitry Andric   static bool classof(const Stmt *T) {
243981ad6265SDimitry Andric     return T->getStmtClass() == OMPParallelMaskedDirectiveClass;
244081ad6265SDimitry Andric   }
244181ad6265SDimitry Andric };
244281ad6265SDimitry Andric 
24430b57cec5SDimitry Andric /// This represents '#pragma omp parallel sections' directive.
24440b57cec5SDimitry Andric ///
24450b57cec5SDimitry Andric /// \code
24460b57cec5SDimitry Andric /// #pragma omp parallel sections private(a,b) reduction(+:c,d)
24470b57cec5SDimitry Andric /// \endcode
24480b57cec5SDimitry Andric /// In this example directive '#pragma omp parallel sections' has clauses
24490b57cec5SDimitry Andric /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
24500b57cec5SDimitry Andric /// and variables 'c' and 'd'.
24510b57cec5SDimitry Andric ///
24520b57cec5SDimitry Andric class OMPParallelSectionsDirective : public OMPExecutableDirective {
24530b57cec5SDimitry Andric   friend class ASTStmtReader;
2454e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
24550b57cec5SDimitry Andric 
24560b57cec5SDimitry Andric   /// true if current directive has inner cancel directive.
2457e8d8bef9SDimitry Andric   bool HasCancel = false;
24580b57cec5SDimitry Andric 
24590b57cec5SDimitry Andric   /// Build directive with the given start and end location.
24600b57cec5SDimitry Andric   ///
24610b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
24620b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
24630b57cec5SDimitry Andric   ///
OMPParallelSectionsDirective(SourceLocation StartLoc,SourceLocation EndLoc)2464e8d8bef9SDimitry Andric   OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2465e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
2466480093f4SDimitry Andric                                llvm::omp::OMPD_parallel_sections, StartLoc,
2467e8d8bef9SDimitry Andric                                EndLoc) {}
24680b57cec5SDimitry Andric 
24690b57cec5SDimitry Andric   /// Build an empty directive.
24700b57cec5SDimitry Andric   ///
OMPParallelSectionsDirective()2471e8d8bef9SDimitry Andric   explicit OMPParallelSectionsDirective()
2472e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
2473480093f4SDimitry Andric                                llvm::omp::OMPD_parallel_sections,
2474e8d8bef9SDimitry Andric                                SourceLocation(), SourceLocation()) {}
24750b57cec5SDimitry Andric 
24765ffd83dbSDimitry Andric   /// Sets special task reduction descriptor.
setTaskReductionRefExpr(Expr * E)2477e8d8bef9SDimitry Andric   void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
24785ffd83dbSDimitry Andric 
24790b57cec5SDimitry Andric   /// Set cancel state.
setHasCancel(bool Has)24800b57cec5SDimitry Andric   void setHasCancel(bool Has) { HasCancel = Has; }
24810b57cec5SDimitry Andric 
24820b57cec5SDimitry Andric public:
24830b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
24840b57cec5SDimitry Andric   ///
24850b57cec5SDimitry Andric   /// \param C AST context.
24860b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
24870b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
24880b57cec5SDimitry Andric   /// \param Clauses List of clauses.
24890b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
24905ffd83dbSDimitry Andric   /// \param TaskRedRef Task reduction special reference expression to handle
24915ffd83dbSDimitry Andric   /// taskgroup descriptor.
24920b57cec5SDimitry Andric   /// \param HasCancel true if current directive has inner cancel directive.
24930b57cec5SDimitry Andric   ///
24940b57cec5SDimitry Andric   static OMPParallelSectionsDirective *
24950b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
24965ffd83dbSDimitry Andric          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
24975ffd83dbSDimitry Andric          bool HasCancel);
24980b57cec5SDimitry Andric 
24990b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses
25000b57cec5SDimitry Andric   /// clauses.
25010b57cec5SDimitry Andric   ///
25020b57cec5SDimitry Andric   /// \param C AST context.
25030b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
25040b57cec5SDimitry Andric   ///
25050b57cec5SDimitry Andric   static OMPParallelSectionsDirective *
25060b57cec5SDimitry Andric   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
25070b57cec5SDimitry Andric 
25085ffd83dbSDimitry Andric   /// Returns special task reduction reference expression.
getTaskReductionRefExpr()2509e8d8bef9SDimitry Andric   Expr *getTaskReductionRefExpr() {
2510e8d8bef9SDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[0]);
2511e8d8bef9SDimitry Andric   }
getTaskReductionRefExpr()2512e8d8bef9SDimitry Andric   const Expr *getTaskReductionRefExpr() const {
2513e8d8bef9SDimitry Andric     return const_cast<OMPParallelSectionsDirective *>(this)
2514e8d8bef9SDimitry Andric         ->getTaskReductionRefExpr();
2515e8d8bef9SDimitry Andric   }
25165ffd83dbSDimitry Andric 
25170b57cec5SDimitry Andric   /// Return true if current directive has inner cancel directive.
hasCancel()25180b57cec5SDimitry Andric   bool hasCancel() const { return HasCancel; }
25190b57cec5SDimitry Andric 
classof(const Stmt * T)25200b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
25210b57cec5SDimitry Andric     return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
25220b57cec5SDimitry Andric   }
25230b57cec5SDimitry Andric };
25240b57cec5SDimitry Andric 
25250b57cec5SDimitry Andric /// This represents '#pragma omp task' directive.
25260b57cec5SDimitry Andric ///
25270b57cec5SDimitry Andric /// \code
25280b57cec5SDimitry Andric /// #pragma omp task private(a,b) final(d)
25290b57cec5SDimitry Andric /// \endcode
25300b57cec5SDimitry Andric /// In this example directive '#pragma omp task' has clauses 'private' with the
25310b57cec5SDimitry Andric /// variables 'a' and 'b' and 'final' with condition 'd'.
25320b57cec5SDimitry Andric ///
25330b57cec5SDimitry Andric class OMPTaskDirective : public OMPExecutableDirective {
25340b57cec5SDimitry Andric   friend class ASTStmtReader;
2535e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
25360b57cec5SDimitry Andric   /// true if this directive has inner cancel directive.
2537e8d8bef9SDimitry Andric   bool HasCancel = false;
25380b57cec5SDimitry Andric 
25390b57cec5SDimitry Andric   /// Build directive with the given start and end location.
25400b57cec5SDimitry Andric   ///
25410b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
25420b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
25430b57cec5SDimitry Andric   ///
OMPTaskDirective(SourceLocation StartLoc,SourceLocation EndLoc)2544e8d8bef9SDimitry Andric   OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2545e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
2546e8d8bef9SDimitry Andric                                StartLoc, EndLoc) {}
25470b57cec5SDimitry Andric 
25480b57cec5SDimitry Andric   /// Build an empty directive.
25490b57cec5SDimitry Andric   ///
OMPTaskDirective()2550e8d8bef9SDimitry Andric   explicit OMPTaskDirective()
2551e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
2552e8d8bef9SDimitry Andric                                SourceLocation(), SourceLocation()) {}
25530b57cec5SDimitry Andric 
25540b57cec5SDimitry Andric   /// Set cancel state.
setHasCancel(bool Has)25550b57cec5SDimitry Andric   void setHasCancel(bool Has) { HasCancel = Has; }
25560b57cec5SDimitry Andric 
25570b57cec5SDimitry Andric public:
25580b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
25590b57cec5SDimitry Andric   ///
25600b57cec5SDimitry Andric   /// \param C AST context.
25610b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
25620b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
25630b57cec5SDimitry Andric   /// \param Clauses List of clauses.
25640b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
25650b57cec5SDimitry Andric   /// \param HasCancel true, if current directive has inner cancel directive.
25660b57cec5SDimitry Andric   ///
25670b57cec5SDimitry Andric   static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
25680b57cec5SDimitry Andric                                   SourceLocation EndLoc,
25690b57cec5SDimitry Andric                                   ArrayRef<OMPClause *> Clauses,
25700b57cec5SDimitry Andric                                   Stmt *AssociatedStmt, bool HasCancel);
25710b57cec5SDimitry Andric 
25720b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses
25730b57cec5SDimitry Andric   /// clauses.
25740b57cec5SDimitry Andric   ///
25750b57cec5SDimitry Andric   /// \param C AST context.
25760b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
25770b57cec5SDimitry Andric   ///
25780b57cec5SDimitry Andric   static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
25790b57cec5SDimitry Andric                                        EmptyShell);
25800b57cec5SDimitry Andric 
25810b57cec5SDimitry Andric   /// Return true if current directive has inner cancel directive.
hasCancel()25820b57cec5SDimitry Andric   bool hasCancel() const { return HasCancel; }
25830b57cec5SDimitry Andric 
classof(const Stmt * T)25840b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
25850b57cec5SDimitry Andric     return T->getStmtClass() == OMPTaskDirectiveClass;
25860b57cec5SDimitry Andric   }
25870b57cec5SDimitry Andric };
25880b57cec5SDimitry Andric 
25890b57cec5SDimitry Andric /// This represents '#pragma omp taskyield' directive.
25900b57cec5SDimitry Andric ///
25910b57cec5SDimitry Andric /// \code
25920b57cec5SDimitry Andric /// #pragma omp taskyield
25930b57cec5SDimitry Andric /// \endcode
25940b57cec5SDimitry Andric ///
25950b57cec5SDimitry Andric class OMPTaskyieldDirective : public OMPExecutableDirective {
25960b57cec5SDimitry Andric   friend class ASTStmtReader;
2597e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
25980b57cec5SDimitry Andric   /// Build directive with the given start and end location.
25990b57cec5SDimitry Andric   ///
26000b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
26010b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
26020b57cec5SDimitry Andric   ///
OMPTaskyieldDirective(SourceLocation StartLoc,SourceLocation EndLoc)26030b57cec5SDimitry Andric   OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2604e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
2605e8d8bef9SDimitry Andric                                llvm::omp::OMPD_taskyield, StartLoc, EndLoc) {}
26060b57cec5SDimitry Andric 
26070b57cec5SDimitry Andric   /// Build an empty directive.
26080b57cec5SDimitry Andric   ///
OMPTaskyieldDirective()26090b57cec5SDimitry Andric   explicit OMPTaskyieldDirective()
2610e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
2611480093f4SDimitry Andric                                llvm::omp::OMPD_taskyield, SourceLocation(),
2612e8d8bef9SDimitry Andric                                SourceLocation()) {}
26130b57cec5SDimitry Andric 
26140b57cec5SDimitry Andric public:
26150b57cec5SDimitry Andric   /// Creates directive.
26160b57cec5SDimitry Andric   ///
26170b57cec5SDimitry Andric   /// \param C AST context.
26180b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
26190b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
26200b57cec5SDimitry Andric   ///
26210b57cec5SDimitry Andric   static OMPTaskyieldDirective *
26220b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
26230b57cec5SDimitry Andric 
26240b57cec5SDimitry Andric   /// Creates an empty directive.
26250b57cec5SDimitry Andric   ///
26260b57cec5SDimitry Andric   /// \param C AST context.
26270b57cec5SDimitry Andric   ///
26280b57cec5SDimitry Andric   static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
26290b57cec5SDimitry Andric 
classof(const Stmt * T)26300b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
26310b57cec5SDimitry Andric     return T->getStmtClass() == OMPTaskyieldDirectiveClass;
26320b57cec5SDimitry Andric   }
26330b57cec5SDimitry Andric };
26340b57cec5SDimitry Andric 
26350b57cec5SDimitry Andric /// This represents '#pragma omp barrier' directive.
26360b57cec5SDimitry Andric ///
26370b57cec5SDimitry Andric /// \code
26380b57cec5SDimitry Andric /// #pragma omp barrier
26390b57cec5SDimitry Andric /// \endcode
26400b57cec5SDimitry Andric ///
26410b57cec5SDimitry Andric class OMPBarrierDirective : public OMPExecutableDirective {
26420b57cec5SDimitry Andric   friend class ASTStmtReader;
2643e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
26440b57cec5SDimitry Andric   /// Build directive with the given start and end location.
26450b57cec5SDimitry Andric   ///
26460b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
26470b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
26480b57cec5SDimitry Andric   ///
OMPBarrierDirective(SourceLocation StartLoc,SourceLocation EndLoc)26490b57cec5SDimitry Andric   OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2650e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPBarrierDirectiveClass,
2651e8d8bef9SDimitry Andric                                llvm::omp::OMPD_barrier, StartLoc, EndLoc) {}
26520b57cec5SDimitry Andric 
26530b57cec5SDimitry Andric   /// Build an empty directive.
26540b57cec5SDimitry Andric   ///
OMPBarrierDirective()26550b57cec5SDimitry Andric   explicit OMPBarrierDirective()
2656e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPBarrierDirectiveClass,
2657480093f4SDimitry Andric                                llvm::omp::OMPD_barrier, SourceLocation(),
2658e8d8bef9SDimitry Andric                                SourceLocation()) {}
26590b57cec5SDimitry Andric 
26600b57cec5SDimitry Andric public:
26610b57cec5SDimitry Andric   /// Creates directive.
26620b57cec5SDimitry Andric   ///
26630b57cec5SDimitry Andric   /// \param C AST context.
26640b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
26650b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
26660b57cec5SDimitry Andric   ///
26670b57cec5SDimitry Andric   static OMPBarrierDirective *
26680b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
26690b57cec5SDimitry Andric 
26700b57cec5SDimitry Andric   /// Creates an empty directive.
26710b57cec5SDimitry Andric   ///
26720b57cec5SDimitry Andric   /// \param C AST context.
26730b57cec5SDimitry Andric   ///
26740b57cec5SDimitry Andric   static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
26750b57cec5SDimitry Andric 
classof(const Stmt * T)26760b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
26770b57cec5SDimitry Andric     return T->getStmtClass() == OMPBarrierDirectiveClass;
26780b57cec5SDimitry Andric   }
26790b57cec5SDimitry Andric };
26800b57cec5SDimitry Andric 
26810b57cec5SDimitry Andric /// This represents '#pragma omp taskwait' directive.
26820b57cec5SDimitry Andric ///
26830b57cec5SDimitry Andric /// \code
26840b57cec5SDimitry Andric /// #pragma omp taskwait
26850b57cec5SDimitry Andric /// \endcode
26860b57cec5SDimitry Andric ///
26870b57cec5SDimitry Andric class OMPTaskwaitDirective : public OMPExecutableDirective {
26880b57cec5SDimitry Andric   friend class ASTStmtReader;
2689e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
26900b57cec5SDimitry Andric   /// Build directive with the given start and end location.
26910b57cec5SDimitry Andric   ///
26920b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
26930b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
26940b57cec5SDimitry Andric   ///
OMPTaskwaitDirective(SourceLocation StartLoc,SourceLocation EndLoc)26950b57cec5SDimitry Andric   OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2696e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
2697e8d8bef9SDimitry Andric                                llvm::omp::OMPD_taskwait, StartLoc, EndLoc) {}
26980b57cec5SDimitry Andric 
26990b57cec5SDimitry Andric   /// Build an empty directive.
27000b57cec5SDimitry Andric   ///
OMPTaskwaitDirective()27010b57cec5SDimitry Andric   explicit OMPTaskwaitDirective()
2702e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
2703480093f4SDimitry Andric                                llvm::omp::OMPD_taskwait, SourceLocation(),
2704e8d8bef9SDimitry Andric                                SourceLocation()) {}
27050b57cec5SDimitry Andric 
27060b57cec5SDimitry Andric public:
27070b57cec5SDimitry Andric   /// Creates directive.
27080b57cec5SDimitry Andric   ///
27090b57cec5SDimitry Andric   /// \param C AST context.
27100b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
27110b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
2712349cc55cSDimitry Andric   /// \param Clauses List of clauses.
27130b57cec5SDimitry Andric   ///
2714349cc55cSDimitry Andric   static OMPTaskwaitDirective *Create(const ASTContext &C,
2715349cc55cSDimitry Andric                                       SourceLocation StartLoc,
2716349cc55cSDimitry Andric                                       SourceLocation EndLoc,
2717349cc55cSDimitry Andric                                       ArrayRef<OMPClause *> Clauses);
27180b57cec5SDimitry Andric 
27190b57cec5SDimitry Andric   /// Creates an empty directive.
27200b57cec5SDimitry Andric   ///
27210b57cec5SDimitry Andric   /// \param C AST context.
2722349cc55cSDimitry Andric   /// \param NumClauses Number of clauses.
27230b57cec5SDimitry Andric   ///
2724349cc55cSDimitry Andric   static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C,
2725349cc55cSDimitry Andric                                            unsigned NumClauses, EmptyShell);
27260b57cec5SDimitry Andric 
classof(const Stmt * T)27270b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
27280b57cec5SDimitry Andric     return T->getStmtClass() == OMPTaskwaitDirectiveClass;
27290b57cec5SDimitry Andric   }
27300b57cec5SDimitry Andric };
27310b57cec5SDimitry Andric 
27320b57cec5SDimitry Andric /// This represents '#pragma omp taskgroup' directive.
27330b57cec5SDimitry Andric ///
27340b57cec5SDimitry Andric /// \code
27350b57cec5SDimitry Andric /// #pragma omp taskgroup
27360b57cec5SDimitry Andric /// \endcode
27370b57cec5SDimitry Andric ///
27380b57cec5SDimitry Andric class OMPTaskgroupDirective : public OMPExecutableDirective {
27390b57cec5SDimitry Andric   friend class ASTStmtReader;
2740e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
27410b57cec5SDimitry Andric   /// Build directive with the given start and end location.
27420b57cec5SDimitry Andric   ///
27430b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
27440b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
27450b57cec5SDimitry Andric   ///
OMPTaskgroupDirective(SourceLocation StartLoc,SourceLocation EndLoc)2746e8d8bef9SDimitry Andric   OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2747e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
2748e8d8bef9SDimitry Andric                                llvm::omp::OMPD_taskgroup, StartLoc, EndLoc) {}
27490b57cec5SDimitry Andric 
27500b57cec5SDimitry Andric   /// Build an empty directive.
27510b57cec5SDimitry Andric   ///
OMPTaskgroupDirective()2752e8d8bef9SDimitry Andric   explicit OMPTaskgroupDirective()
2753e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
2754480093f4SDimitry Andric                                llvm::omp::OMPD_taskgroup, SourceLocation(),
2755e8d8bef9SDimitry Andric                                SourceLocation()) {}
27560b57cec5SDimitry Andric 
27570b57cec5SDimitry Andric   /// Sets the task_reduction return variable.
setReductionRef(Expr * RR)2758e8d8bef9SDimitry Andric   void setReductionRef(Expr *RR) { Data->getChildren()[0] = RR; }
27590b57cec5SDimitry Andric 
27600b57cec5SDimitry Andric public:
27610b57cec5SDimitry Andric   /// Creates directive.
27620b57cec5SDimitry Andric   ///
27630b57cec5SDimitry Andric   /// \param C AST context.
27640b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
27650b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
27660b57cec5SDimitry Andric   /// \param Clauses List of clauses.
27670b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
27680b57cec5SDimitry Andric   /// \param ReductionRef Reference to the task_reduction return variable.
27690b57cec5SDimitry Andric   ///
27700b57cec5SDimitry Andric   static OMPTaskgroupDirective *
27710b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
27720b57cec5SDimitry Andric          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
27730b57cec5SDimitry Andric          Expr *ReductionRef);
27740b57cec5SDimitry Andric 
27750b57cec5SDimitry Andric   /// Creates an empty directive.
27760b57cec5SDimitry Andric   ///
27770b57cec5SDimitry Andric   /// \param C AST context.
27780b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
27790b57cec5SDimitry Andric   ///
27800b57cec5SDimitry Andric   static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C,
27810b57cec5SDimitry Andric                                             unsigned NumClauses, EmptyShell);
27820b57cec5SDimitry Andric 
27830b57cec5SDimitry Andric 
27840b57cec5SDimitry Andric   /// Returns reference to the task_reduction return variable.
getReductionRef()27850b57cec5SDimitry Andric   const Expr *getReductionRef() const {
2786e8d8bef9SDimitry Andric     return const_cast<OMPTaskgroupDirective *>(this)->getReductionRef();
27870b57cec5SDimitry Andric   }
getReductionRef()2788e8d8bef9SDimitry Andric   Expr *getReductionRef() { return cast_or_null<Expr>(Data->getChildren()[0]); }
27890b57cec5SDimitry Andric 
classof(const Stmt * T)27900b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
27910b57cec5SDimitry Andric     return T->getStmtClass() == OMPTaskgroupDirectiveClass;
27920b57cec5SDimitry Andric   }
27930b57cec5SDimitry Andric };
27940b57cec5SDimitry Andric 
27950b57cec5SDimitry Andric /// This represents '#pragma omp flush' directive.
27960b57cec5SDimitry Andric ///
27970b57cec5SDimitry Andric /// \code
27980b57cec5SDimitry Andric /// #pragma omp flush(a,b)
27990b57cec5SDimitry Andric /// \endcode
28000b57cec5SDimitry Andric /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
28010b57cec5SDimitry Andric /// and 'b'.
28020b57cec5SDimitry Andric /// 'omp flush' directive does not have clauses but have an optional list of
28030b57cec5SDimitry Andric /// variables to flush. This list of variables is stored within some fake clause
28040b57cec5SDimitry Andric /// FlushClause.
28050b57cec5SDimitry Andric class OMPFlushDirective : public OMPExecutableDirective {
28060b57cec5SDimitry Andric   friend class ASTStmtReader;
2807e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
28080b57cec5SDimitry Andric   /// Build directive with the given start and end location.
28090b57cec5SDimitry Andric   ///
28100b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
28110b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
28120b57cec5SDimitry Andric   ///
OMPFlushDirective(SourceLocation StartLoc,SourceLocation EndLoc)2813e8d8bef9SDimitry Andric   OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2814e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
2815e8d8bef9SDimitry Andric                                StartLoc, EndLoc) {}
28160b57cec5SDimitry Andric 
28170b57cec5SDimitry Andric   /// Build an empty directive.
28180b57cec5SDimitry Andric   ///
OMPFlushDirective()2819e8d8bef9SDimitry Andric   explicit OMPFlushDirective()
2820e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
2821e8d8bef9SDimitry Andric                                SourceLocation(), SourceLocation()) {}
28220b57cec5SDimitry Andric 
28230b57cec5SDimitry Andric public:
28240b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
28250b57cec5SDimitry Andric   ///
28260b57cec5SDimitry Andric   /// \param C AST context.
28270b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
28280b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
28290b57cec5SDimitry Andric   /// \param Clauses List of clauses (only single OMPFlushClause clause is
28300b57cec5SDimitry Andric   /// allowed).
28310b57cec5SDimitry Andric   ///
28320b57cec5SDimitry Andric   static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
28330b57cec5SDimitry Andric                                    SourceLocation EndLoc,
28340b57cec5SDimitry Andric                                    ArrayRef<OMPClause *> Clauses);
28350b57cec5SDimitry Andric 
28360b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses
28370b57cec5SDimitry Andric   /// clauses.
28380b57cec5SDimitry Andric   ///
28390b57cec5SDimitry Andric   /// \param C AST context.
28400b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
28410b57cec5SDimitry Andric   ///
28420b57cec5SDimitry Andric   static OMPFlushDirective *CreateEmpty(const ASTContext &C,
28430b57cec5SDimitry Andric                                         unsigned NumClauses, EmptyShell);
28440b57cec5SDimitry Andric 
classof(const Stmt * T)28450b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
28460b57cec5SDimitry Andric     return T->getStmtClass() == OMPFlushDirectiveClass;
28470b57cec5SDimitry Andric   }
28480b57cec5SDimitry Andric };
28490b57cec5SDimitry Andric 
28505ffd83dbSDimitry Andric /// This represents '#pragma omp depobj' directive.
28515ffd83dbSDimitry Andric ///
28525ffd83dbSDimitry Andric /// \code
28535ffd83dbSDimitry Andric /// #pragma omp depobj(a) depend(in:x,y)
28545ffd83dbSDimitry Andric /// \endcode
28555ffd83dbSDimitry Andric /// In this example directive '#pragma omp  depobj' initializes a depobj object
28565ffd83dbSDimitry Andric /// 'a' with dependence type 'in' and a list with 'x' and 'y' locators.
28575ffd83dbSDimitry Andric class OMPDepobjDirective final : public OMPExecutableDirective {
28585ffd83dbSDimitry Andric   friend class ASTStmtReader;
2859e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
28605ffd83dbSDimitry Andric 
28615ffd83dbSDimitry Andric   /// Build directive with the given start and end location.
28625ffd83dbSDimitry Andric   ///
28635ffd83dbSDimitry Andric   /// \param StartLoc Starting location of the directive kind.
28645ffd83dbSDimitry Andric   /// \param EndLoc Ending location of the directive.
28655ffd83dbSDimitry Andric   ///
OMPDepobjDirective(SourceLocation StartLoc,SourceLocation EndLoc)2866e8d8bef9SDimitry Andric   OMPDepobjDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2867e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
2868e8d8bef9SDimitry Andric                                StartLoc, EndLoc) {}
28695ffd83dbSDimitry Andric 
28705ffd83dbSDimitry Andric   /// Build an empty directive.
28715ffd83dbSDimitry Andric   ///
OMPDepobjDirective()2872e8d8bef9SDimitry Andric   explicit OMPDepobjDirective()
2873e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
2874e8d8bef9SDimitry Andric                                SourceLocation(), SourceLocation()) {}
28755ffd83dbSDimitry Andric 
28765ffd83dbSDimitry Andric public:
28775ffd83dbSDimitry Andric   /// Creates directive with a list of \a Clauses.
28785ffd83dbSDimitry Andric   ///
28795ffd83dbSDimitry Andric   /// \param C AST context.
28805ffd83dbSDimitry Andric   /// \param StartLoc Starting location of the directive kind.
28815ffd83dbSDimitry Andric   /// \param EndLoc Ending Location of the directive.
28825ffd83dbSDimitry Andric   /// \param Clauses List of clauses.
28835ffd83dbSDimitry Andric   ///
28845ffd83dbSDimitry Andric   static OMPDepobjDirective *Create(const ASTContext &C,
28855ffd83dbSDimitry Andric                                     SourceLocation StartLoc,
28865ffd83dbSDimitry Andric                                     SourceLocation EndLoc,
28875ffd83dbSDimitry Andric                                     ArrayRef<OMPClause *> Clauses);
28885ffd83dbSDimitry Andric 
28895ffd83dbSDimitry Andric   /// Creates an empty directive with the place for \a NumClauses
28905ffd83dbSDimitry Andric   /// clauses.
28915ffd83dbSDimitry Andric   ///
28925ffd83dbSDimitry Andric   /// \param C AST context.
28935ffd83dbSDimitry Andric   /// \param NumClauses Number of clauses.
28945ffd83dbSDimitry Andric   ///
28955ffd83dbSDimitry Andric   static OMPDepobjDirective *CreateEmpty(const ASTContext &C,
28965ffd83dbSDimitry Andric                                          unsigned NumClauses, EmptyShell);
28975ffd83dbSDimitry Andric 
classof(const Stmt * T)28985ffd83dbSDimitry Andric   static bool classof(const Stmt *T) {
28995ffd83dbSDimitry Andric     return T->getStmtClass() == OMPDepobjDirectiveClass;
29005ffd83dbSDimitry Andric   }
29015ffd83dbSDimitry Andric };
29025ffd83dbSDimitry Andric 
29030b57cec5SDimitry Andric /// This represents '#pragma omp ordered' directive.
29040b57cec5SDimitry Andric ///
29050b57cec5SDimitry Andric /// \code
29060b57cec5SDimitry Andric /// #pragma omp ordered
29070b57cec5SDimitry Andric /// \endcode
29080b57cec5SDimitry Andric ///
29090b57cec5SDimitry Andric class OMPOrderedDirective : public OMPExecutableDirective {
29100b57cec5SDimitry Andric   friend class ASTStmtReader;
2911e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
29120b57cec5SDimitry Andric   /// Build directive with the given start and end location.
29130b57cec5SDimitry Andric   ///
29140b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
29150b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
29160b57cec5SDimitry Andric   ///
OMPOrderedDirective(SourceLocation StartLoc,SourceLocation EndLoc)2917e8d8bef9SDimitry Andric   OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2918e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPOrderedDirectiveClass,
2919e8d8bef9SDimitry Andric                                llvm::omp::OMPD_ordered, StartLoc, EndLoc) {}
29200b57cec5SDimitry Andric 
29210b57cec5SDimitry Andric   /// Build an empty directive.
29220b57cec5SDimitry Andric   ///
OMPOrderedDirective()2923e8d8bef9SDimitry Andric   explicit OMPOrderedDirective()
2924e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPOrderedDirectiveClass,
2925480093f4SDimitry Andric                                llvm::omp::OMPD_ordered, SourceLocation(),
2926e8d8bef9SDimitry Andric                                SourceLocation()) {}
29270b57cec5SDimitry Andric 
29280b57cec5SDimitry Andric public:
29290b57cec5SDimitry Andric   /// Creates directive.
29300b57cec5SDimitry Andric   ///
29310b57cec5SDimitry Andric   /// \param C AST context.
29320b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
29330b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
29340b57cec5SDimitry Andric   /// \param Clauses List of clauses.
29350b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
29360b57cec5SDimitry Andric   ///
29370b57cec5SDimitry Andric   static OMPOrderedDirective *
29380b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
29390b57cec5SDimitry Andric          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
29400b57cec5SDimitry Andric 
29410b57cec5SDimitry Andric   /// Creates an empty directive.
29420b57cec5SDimitry Andric   ///
29430b57cec5SDimitry Andric   /// \param C AST context.
29440b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
2945bdd1243dSDimitry Andric   /// \param IsStandalone true, if the standalone directive is created.
29460b57cec5SDimitry Andric   ///
29470b57cec5SDimitry Andric   static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
2948e8d8bef9SDimitry Andric                                           unsigned NumClauses,
2949e8d8bef9SDimitry Andric                                           bool IsStandalone, EmptyShell);
29500b57cec5SDimitry Andric 
classof(const Stmt * T)29510b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
29520b57cec5SDimitry Andric     return T->getStmtClass() == OMPOrderedDirectiveClass;
29530b57cec5SDimitry Andric   }
29540b57cec5SDimitry Andric };
29550b57cec5SDimitry Andric 
29560b57cec5SDimitry Andric /// This represents '#pragma omp atomic' directive.
29570b57cec5SDimitry Andric ///
29580b57cec5SDimitry Andric /// \code
29590b57cec5SDimitry Andric /// #pragma omp atomic capture
29600b57cec5SDimitry Andric /// \endcode
29610b57cec5SDimitry Andric /// In this example directive '#pragma omp atomic' has clause 'capture'.
29620b57cec5SDimitry Andric ///
29630b57cec5SDimitry Andric class OMPAtomicDirective : public OMPExecutableDirective {
29640b57cec5SDimitry Andric   friend class ASTStmtReader;
2965e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
296681ad6265SDimitry Andric 
296781ad6265SDimitry Andric   struct FlagTy {
29680b57cec5SDimitry Andric     /// Used for 'atomic update' or 'atomic capture' constructs. They may
296981ad6265SDimitry Andric     /// have atomic expressions of forms:
29700b57cec5SDimitry Andric     /// \code
29710b57cec5SDimitry Andric     /// x = x binop expr;
29720b57cec5SDimitry Andric     /// x = expr binop x;
29730b57cec5SDimitry Andric     /// \endcode
297481ad6265SDimitry Andric     /// This field is 1 for the first form of the expression and 0 for the
29750b57cec5SDimitry Andric     /// second. Required for correct codegen of non-associative operations (like
29760b57cec5SDimitry Andric     /// << or >>).
297781ad6265SDimitry Andric     uint8_t IsXLHSInRHSPart : 1;
29780b57cec5SDimitry Andric     /// Used for 'atomic update' or 'atomic capture' constructs. They may
297981ad6265SDimitry Andric     /// have atomic expressions of forms:
29800b57cec5SDimitry Andric     /// \code
29810b57cec5SDimitry Andric     /// v = x; <update x>;
29820b57cec5SDimitry Andric     /// <update x>; v = x;
29830b57cec5SDimitry Andric     /// \endcode
298481ad6265SDimitry Andric     /// This field is 1 for the first(postfix) form of the expression and 0
29850b57cec5SDimitry Andric     /// otherwise.
298681ad6265SDimitry Andric     uint8_t IsPostfixUpdate : 1;
298781ad6265SDimitry Andric     /// 1 if 'v' is updated only when the condition is false (compare capture
298881ad6265SDimitry Andric     /// only).
298981ad6265SDimitry Andric     uint8_t IsFailOnly : 1;
299081ad6265SDimitry Andric   } Flags;
29910b57cec5SDimitry Andric 
29920b57cec5SDimitry Andric   /// Build directive with the given start and end location.
29930b57cec5SDimitry Andric   ///
29940b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
29950b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
29960b57cec5SDimitry Andric   ///
OMPAtomicDirective(SourceLocation StartLoc,SourceLocation EndLoc)2997e8d8bef9SDimitry Andric   OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2998e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
2999e8d8bef9SDimitry Andric                                StartLoc, EndLoc) {}
30000b57cec5SDimitry Andric 
30010b57cec5SDimitry Andric   /// Build an empty directive.
30020b57cec5SDimitry Andric   ///
OMPAtomicDirective()3003e8d8bef9SDimitry Andric   explicit OMPAtomicDirective()
3004e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
3005e8d8bef9SDimitry Andric                                SourceLocation(), SourceLocation()) {}
30060b57cec5SDimitry Andric 
3007349cc55cSDimitry Andric   enum DataPositionTy : size_t {
3008349cc55cSDimitry Andric     POS_X = 0,
3009349cc55cSDimitry Andric     POS_V,
3010349cc55cSDimitry Andric     POS_E,
3011349cc55cSDimitry Andric     POS_UpdateExpr,
301281ad6265SDimitry Andric     POS_D,
301381ad6265SDimitry Andric     POS_Cond,
301481ad6265SDimitry Andric     POS_R,
3015349cc55cSDimitry Andric   };
3016349cc55cSDimitry Andric 
30170b57cec5SDimitry Andric   /// Set 'x' part of the associated expression/statement.
setX(Expr * X)3018349cc55cSDimitry Andric   void setX(Expr *X) { Data->getChildren()[DataPositionTy::POS_X] = X; }
30190b57cec5SDimitry Andric   /// Set helper expression of the form
30200b57cec5SDimitry Andric   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
30210b57cec5SDimitry Andric   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
setUpdateExpr(Expr * UE)3022349cc55cSDimitry Andric   void setUpdateExpr(Expr *UE) {
3023349cc55cSDimitry Andric     Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE;
3024349cc55cSDimitry Andric   }
30250b57cec5SDimitry Andric   /// Set 'v' part of the associated expression/statement.
setV(Expr * V)3026349cc55cSDimitry Andric   void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; }
302781ad6265SDimitry Andric   /// Set 'r' part of the associated expression/statement.
setR(Expr * R)302881ad6265SDimitry Andric   void setR(Expr *R) { Data->getChildren()[DataPositionTy::POS_R] = R; }
30290b57cec5SDimitry Andric   /// Set 'expr' part of the associated expression/statement.
setExpr(Expr * E)3030349cc55cSDimitry Andric   void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; }
303181ad6265SDimitry Andric   /// Set 'd' part of the associated expression/statement.
setD(Expr * D)303281ad6265SDimitry Andric   void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; }
303381ad6265SDimitry Andric   /// Set conditional expression in `atomic compare`.
setCond(Expr * C)303481ad6265SDimitry Andric   void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; }
30350b57cec5SDimitry Andric 
30360b57cec5SDimitry Andric public:
303781ad6265SDimitry Andric   struct Expressions {
303881ad6265SDimitry Andric     /// 'x' part of the associated expression/statement.
303981ad6265SDimitry Andric     Expr *X = nullptr;
304081ad6265SDimitry Andric     /// 'v' part of the associated expression/statement.
304181ad6265SDimitry Andric     Expr *V = nullptr;
304281ad6265SDimitry Andric     // 'r' part of the associated expression/statement.
304381ad6265SDimitry Andric     Expr *R = nullptr;
304481ad6265SDimitry Andric     /// 'expr' part of the associated expression/statement.
304581ad6265SDimitry Andric     Expr *E = nullptr;
304681ad6265SDimitry Andric     /// UE Helper expression of the form:
304781ad6265SDimitry Andric     /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
304881ad6265SDimitry Andric     /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
304981ad6265SDimitry Andric     Expr *UE = nullptr;
305081ad6265SDimitry Andric     /// 'd' part of the associated expression/statement.
305181ad6265SDimitry Andric     Expr *D = nullptr;
305281ad6265SDimitry Andric     /// Conditional expression in `atomic compare` construct.
305381ad6265SDimitry Andric     Expr *Cond = nullptr;
305481ad6265SDimitry Andric     /// True if UE has the first form and false if the second.
305581ad6265SDimitry Andric     bool IsXLHSInRHSPart;
305681ad6265SDimitry Andric     /// True if original value of 'x' must be stored in 'v', not an updated one.
305781ad6265SDimitry Andric     bool IsPostfixUpdate;
305881ad6265SDimitry Andric     /// True if 'v' is updated only when the condition is false (compare capture
305981ad6265SDimitry Andric     /// only).
306081ad6265SDimitry Andric     bool IsFailOnly;
306181ad6265SDimitry Andric   };
306281ad6265SDimitry Andric 
30630b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
30640b57cec5SDimitry Andric   /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
30650b57cec5SDimitry Andric   /// detailed description of 'x', 'v' and 'expr').
30660b57cec5SDimitry Andric   ///
30670b57cec5SDimitry Andric   /// \param C AST context.
30680b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
30690b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
30700b57cec5SDimitry Andric   /// \param Clauses List of clauses.
30710b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
307281ad6265SDimitry Andric   /// \param Exprs Associated expressions or statements.
307381ad6265SDimitry Andric   static OMPAtomicDirective *Create(const ASTContext &C,
307481ad6265SDimitry Andric                                     SourceLocation StartLoc,
307581ad6265SDimitry Andric                                     SourceLocation EndLoc,
307681ad6265SDimitry Andric                                     ArrayRef<OMPClause *> Clauses,
307781ad6265SDimitry Andric                                     Stmt *AssociatedStmt, Expressions Exprs);
30780b57cec5SDimitry Andric 
30790b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses
30800b57cec5SDimitry Andric   /// clauses.
30810b57cec5SDimitry Andric   ///
30820b57cec5SDimitry Andric   /// \param C AST context.
30830b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
30840b57cec5SDimitry Andric   ///
30850b57cec5SDimitry Andric   static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
30860b57cec5SDimitry Andric                                          unsigned NumClauses, EmptyShell);
30870b57cec5SDimitry Andric 
30880b57cec5SDimitry Andric   /// Get 'x' part of the associated expression/statement.
getX()3089349cc55cSDimitry Andric   Expr *getX() {
3090349cc55cSDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
3091349cc55cSDimitry Andric   }
getX()30920b57cec5SDimitry Andric   const Expr *getX() const {
3093349cc55cSDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
30940b57cec5SDimitry Andric   }
30950b57cec5SDimitry Andric   /// Get helper expression of the form
30960b57cec5SDimitry Andric   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
30970b57cec5SDimitry Andric   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
getUpdateExpr()3098349cc55cSDimitry Andric   Expr *getUpdateExpr() {
3099349cc55cSDimitry Andric     return cast_or_null<Expr>(
3100349cc55cSDimitry Andric         Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
3101349cc55cSDimitry Andric   }
getUpdateExpr()31020b57cec5SDimitry Andric   const Expr *getUpdateExpr() const {
3103349cc55cSDimitry Andric     return cast_or_null<Expr>(
3104349cc55cSDimitry Andric         Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
31050b57cec5SDimitry Andric   }
31060b57cec5SDimitry Andric   /// Return true if helper update expression has form
31070b57cec5SDimitry Andric   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
31080b57cec5SDimitry Andric   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
isXLHSInRHSPart()310981ad6265SDimitry Andric   bool isXLHSInRHSPart() const { return Flags.IsXLHSInRHSPart; }
31100b57cec5SDimitry Andric   /// Return true if 'v' expression must be updated to original value of
31110b57cec5SDimitry Andric   /// 'x', false if 'v' must be updated to the new value of 'x'.
isPostfixUpdate()311281ad6265SDimitry Andric   bool isPostfixUpdate() const { return Flags.IsPostfixUpdate; }
311381ad6265SDimitry Andric   /// Return true if 'v' is updated only when the condition is evaluated false
311481ad6265SDimitry Andric   /// (compare capture only).
isFailOnly()311581ad6265SDimitry Andric   bool isFailOnly() const { return Flags.IsFailOnly; }
31160b57cec5SDimitry Andric   /// Get 'v' part of the associated expression/statement.
getV()3117349cc55cSDimitry Andric   Expr *getV() {
3118349cc55cSDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
3119349cc55cSDimitry Andric   }
getV()31200b57cec5SDimitry Andric   const Expr *getV() const {
3121349cc55cSDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
31220b57cec5SDimitry Andric   }
312381ad6265SDimitry Andric   /// Get 'r' part of the associated expression/statement.
getR()312481ad6265SDimitry Andric   Expr *getR() {
312581ad6265SDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
312681ad6265SDimitry Andric   }
getR()312781ad6265SDimitry Andric   const Expr *getR() const {
312881ad6265SDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
312981ad6265SDimitry Andric   }
31300b57cec5SDimitry Andric   /// Get 'expr' part of the associated expression/statement.
getExpr()3131349cc55cSDimitry Andric   Expr *getExpr() {
3132349cc55cSDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
3133349cc55cSDimitry Andric   }
getExpr()31340b57cec5SDimitry Andric   const Expr *getExpr() const {
3135349cc55cSDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
31360b57cec5SDimitry Andric   }
313781ad6265SDimitry Andric   /// Get 'd' part of the associated expression/statement.
getD()313881ad6265SDimitry Andric   Expr *getD() {
313981ad6265SDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
314081ad6265SDimitry Andric   }
getD()314181ad6265SDimitry Andric   Expr *getD() const {
314281ad6265SDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
314381ad6265SDimitry Andric   }
314481ad6265SDimitry Andric   /// Get the 'cond' part of the source atomic expression.
getCondExpr()314581ad6265SDimitry Andric   Expr *getCondExpr() {
314681ad6265SDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
314781ad6265SDimitry Andric   }
getCondExpr()314881ad6265SDimitry Andric   Expr *getCondExpr() const {
314981ad6265SDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
315081ad6265SDimitry Andric   }
31510b57cec5SDimitry Andric 
classof(const Stmt * T)31520b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
31530b57cec5SDimitry Andric     return T->getStmtClass() == OMPAtomicDirectiveClass;
31540b57cec5SDimitry Andric   }
31550b57cec5SDimitry Andric };
31560b57cec5SDimitry Andric 
31570b57cec5SDimitry Andric /// This represents '#pragma omp target' directive.
31580b57cec5SDimitry Andric ///
31590b57cec5SDimitry Andric /// \code
31600b57cec5SDimitry Andric /// #pragma omp target if(a)
31610b57cec5SDimitry Andric /// \endcode
31620b57cec5SDimitry Andric /// In this example directive '#pragma omp target' has clause 'if' with
31630b57cec5SDimitry Andric /// condition 'a'.
31640b57cec5SDimitry Andric ///
31650b57cec5SDimitry Andric class OMPTargetDirective : public OMPExecutableDirective {
31660b57cec5SDimitry Andric   friend class ASTStmtReader;
3167e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
31680b57cec5SDimitry Andric   /// Build directive with the given start and end location.
31690b57cec5SDimitry Andric   ///
31700b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
31710b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
31720b57cec5SDimitry Andric   ///
OMPTargetDirective(SourceLocation StartLoc,SourceLocation EndLoc)3173e8d8bef9SDimitry Andric   OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3174e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
3175e8d8bef9SDimitry Andric                                StartLoc, EndLoc) {}
31760b57cec5SDimitry Andric 
31770b57cec5SDimitry Andric   /// Build an empty directive.
31780b57cec5SDimitry Andric   ///
OMPTargetDirective()3179e8d8bef9SDimitry Andric   explicit OMPTargetDirective()
3180e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
3181e8d8bef9SDimitry Andric                                SourceLocation(), SourceLocation()) {}
31820b57cec5SDimitry Andric 
31830b57cec5SDimitry Andric public:
31840b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
31850b57cec5SDimitry Andric   ///
31860b57cec5SDimitry Andric   /// \param C AST context.
31870b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
31880b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
31890b57cec5SDimitry Andric   /// \param Clauses List of clauses.
31900b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
31910b57cec5SDimitry Andric   ///
31920b57cec5SDimitry Andric   static OMPTargetDirective *
31930b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
31940b57cec5SDimitry Andric          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
31950b57cec5SDimitry Andric 
31960b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses
31970b57cec5SDimitry Andric   /// clauses.
31980b57cec5SDimitry Andric   ///
31990b57cec5SDimitry Andric   /// \param C AST context.
32000b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
32010b57cec5SDimitry Andric   ///
32020b57cec5SDimitry Andric   static OMPTargetDirective *CreateEmpty(const ASTContext &C,
32030b57cec5SDimitry Andric                                          unsigned NumClauses, EmptyShell);
32040b57cec5SDimitry Andric 
classof(const Stmt * T)32050b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
32060b57cec5SDimitry Andric     return T->getStmtClass() == OMPTargetDirectiveClass;
32070b57cec5SDimitry Andric   }
32080b57cec5SDimitry Andric };
32090b57cec5SDimitry Andric 
32100b57cec5SDimitry Andric /// This represents '#pragma omp target data' directive.
32110b57cec5SDimitry Andric ///
32120b57cec5SDimitry Andric /// \code
32130b57cec5SDimitry Andric /// #pragma omp target data device(0) if(a) map(b[:])
32140b57cec5SDimitry Andric /// \endcode
32150b57cec5SDimitry Andric /// In this example directive '#pragma omp target data' has clauses 'device'
32160b57cec5SDimitry Andric /// with the value '0', 'if' with condition 'a' and 'map' with array
32170b57cec5SDimitry Andric /// section 'b[:]'.
32180b57cec5SDimitry Andric ///
32190b57cec5SDimitry Andric class OMPTargetDataDirective : public OMPExecutableDirective {
32200b57cec5SDimitry Andric   friend class ASTStmtReader;
3221e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
32220b57cec5SDimitry Andric   /// Build directive with the given start and end location.
32230b57cec5SDimitry Andric   ///
32240b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
32250b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
32260b57cec5SDimitry Andric   ///
OMPTargetDataDirective(SourceLocation StartLoc,SourceLocation EndLoc)3227e8d8bef9SDimitry Andric   OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3228e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTargetDataDirectiveClass,
3229e8d8bef9SDimitry Andric                                llvm::omp::OMPD_target_data, StartLoc, EndLoc) {}
32300b57cec5SDimitry Andric 
32310b57cec5SDimitry Andric   /// Build an empty directive.
32320b57cec5SDimitry Andric   ///
OMPTargetDataDirective()3233e8d8bef9SDimitry Andric   explicit OMPTargetDataDirective()
3234e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTargetDataDirectiveClass,
3235480093f4SDimitry Andric                                llvm::omp::OMPD_target_data, SourceLocation(),
3236e8d8bef9SDimitry Andric                                SourceLocation()) {}
32370b57cec5SDimitry Andric 
32380b57cec5SDimitry Andric public:
32390b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
32400b57cec5SDimitry Andric   ///
32410b57cec5SDimitry Andric   /// \param C AST context.
32420b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
32430b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
32440b57cec5SDimitry Andric   /// \param Clauses List of clauses.
32450b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
32460b57cec5SDimitry Andric   ///
32470b57cec5SDimitry Andric   static OMPTargetDataDirective *
32480b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
32490b57cec5SDimitry Andric          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
32500b57cec5SDimitry Andric 
32510b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a N clauses.
32520b57cec5SDimitry Andric   ///
32530b57cec5SDimitry Andric   /// \param C AST context.
32540b57cec5SDimitry Andric   /// \param N The number of clauses.
32550b57cec5SDimitry Andric   ///
32560b57cec5SDimitry Andric   static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
32570b57cec5SDimitry Andric                                              EmptyShell);
32580b57cec5SDimitry Andric 
classof(const Stmt * T)32590b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
32600b57cec5SDimitry Andric     return T->getStmtClass() == OMPTargetDataDirectiveClass;
32610b57cec5SDimitry Andric   }
32620b57cec5SDimitry Andric };
32630b57cec5SDimitry Andric 
32640b57cec5SDimitry Andric /// This represents '#pragma omp target enter data' directive.
32650b57cec5SDimitry Andric ///
32660b57cec5SDimitry Andric /// \code
32670b57cec5SDimitry Andric /// #pragma omp target enter data device(0) if(a) map(b[:])
32680b57cec5SDimitry Andric /// \endcode
32690b57cec5SDimitry Andric /// In this example directive '#pragma omp target enter data' has clauses
32700b57cec5SDimitry Andric /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
32710b57cec5SDimitry Andric /// section 'b[:]'.
32720b57cec5SDimitry Andric ///
32730b57cec5SDimitry Andric class OMPTargetEnterDataDirective : public OMPExecutableDirective {
32740b57cec5SDimitry Andric   friend class ASTStmtReader;
3275e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
32760b57cec5SDimitry Andric   /// Build directive with the given start and end location.
32770b57cec5SDimitry Andric   ///
32780b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
32790b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
32800b57cec5SDimitry Andric   ///
OMPTargetEnterDataDirective(SourceLocation StartLoc,SourceLocation EndLoc)3281e8d8bef9SDimitry Andric   OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3282e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3283480093f4SDimitry Andric                                llvm::omp::OMPD_target_enter_data, StartLoc,
3284e8d8bef9SDimitry Andric                                EndLoc) {}
32850b57cec5SDimitry Andric 
32860b57cec5SDimitry Andric   /// Build an empty directive.
32870b57cec5SDimitry Andric   ///
OMPTargetEnterDataDirective()3288e8d8bef9SDimitry Andric   explicit OMPTargetEnterDataDirective()
3289e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3290480093f4SDimitry Andric                                llvm::omp::OMPD_target_enter_data,
3291e8d8bef9SDimitry Andric                                SourceLocation(), SourceLocation()) {}
32920b57cec5SDimitry Andric 
32930b57cec5SDimitry Andric public:
32940b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
32950b57cec5SDimitry Andric   ///
32960b57cec5SDimitry Andric   /// \param C AST context.
32970b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
32980b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
32990b57cec5SDimitry Andric   /// \param Clauses List of clauses.
33000b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
33010b57cec5SDimitry Andric   ///
33020b57cec5SDimitry Andric   static OMPTargetEnterDataDirective *
33030b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
33040b57cec5SDimitry Andric          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
33050b57cec5SDimitry Andric 
33060b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a N clauses.
33070b57cec5SDimitry Andric   ///
33080b57cec5SDimitry Andric   /// \param C AST context.
33090b57cec5SDimitry Andric   /// \param N The number of clauses.
33100b57cec5SDimitry Andric   ///
33110b57cec5SDimitry Andric   static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C,
33120b57cec5SDimitry Andric                                                   unsigned N, EmptyShell);
33130b57cec5SDimitry Andric 
classof(const Stmt * T)33140b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
33150b57cec5SDimitry Andric     return T->getStmtClass() == OMPTargetEnterDataDirectiveClass;
33160b57cec5SDimitry Andric   }
33170b57cec5SDimitry Andric };
33180b57cec5SDimitry Andric 
33190b57cec5SDimitry Andric /// This represents '#pragma omp target exit data' directive.
33200b57cec5SDimitry Andric ///
33210b57cec5SDimitry Andric /// \code
33220b57cec5SDimitry Andric /// #pragma omp target exit data device(0) if(a) map(b[:])
33230b57cec5SDimitry Andric /// \endcode
33240b57cec5SDimitry Andric /// In this example directive '#pragma omp target exit data' has clauses
33250b57cec5SDimitry Andric /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
33260b57cec5SDimitry Andric /// section 'b[:]'.
33270b57cec5SDimitry Andric ///
33280b57cec5SDimitry Andric class OMPTargetExitDataDirective : public OMPExecutableDirective {
33290b57cec5SDimitry Andric   friend class ASTStmtReader;
3330e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
33310b57cec5SDimitry Andric   /// Build directive with the given start and end location.
33320b57cec5SDimitry Andric   ///
33330b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
33340b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
33350b57cec5SDimitry Andric   ///
OMPTargetExitDataDirective(SourceLocation StartLoc,SourceLocation EndLoc)3336e8d8bef9SDimitry Andric   OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3337e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3338480093f4SDimitry Andric                                llvm::omp::OMPD_target_exit_data, StartLoc,
3339e8d8bef9SDimitry Andric                                EndLoc) {}
33400b57cec5SDimitry Andric 
33410b57cec5SDimitry Andric   /// Build an empty directive.
33420b57cec5SDimitry Andric   ///
OMPTargetExitDataDirective()3343e8d8bef9SDimitry Andric   explicit OMPTargetExitDataDirective()
3344e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3345480093f4SDimitry Andric                                llvm::omp::OMPD_target_exit_data,
3346e8d8bef9SDimitry Andric                                SourceLocation(), SourceLocation()) {}
33470b57cec5SDimitry Andric 
33480b57cec5SDimitry Andric public:
33490b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
33500b57cec5SDimitry Andric   ///
33510b57cec5SDimitry Andric   /// \param C AST context.
33520b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
33530b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
33540b57cec5SDimitry Andric   /// \param Clauses List of clauses.
33550b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
33560b57cec5SDimitry Andric   ///
33570b57cec5SDimitry Andric   static OMPTargetExitDataDirective *
33580b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
33590b57cec5SDimitry Andric          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
33600b57cec5SDimitry Andric 
33610b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a N clauses.
33620b57cec5SDimitry Andric   ///
33630b57cec5SDimitry Andric   /// \param C AST context.
33640b57cec5SDimitry Andric   /// \param N The number of clauses.
33650b57cec5SDimitry Andric   ///
33660b57cec5SDimitry Andric   static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
33670b57cec5SDimitry Andric                                                  unsigned N, EmptyShell);
33680b57cec5SDimitry Andric 
classof(const Stmt * T)33690b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
33700b57cec5SDimitry Andric     return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
33710b57cec5SDimitry Andric   }
33720b57cec5SDimitry Andric };
33730b57cec5SDimitry Andric 
33740b57cec5SDimitry Andric /// This represents '#pragma omp target parallel' directive.
33750b57cec5SDimitry Andric ///
33760b57cec5SDimitry Andric /// \code
33770b57cec5SDimitry Andric /// #pragma omp target parallel if(a)
33780b57cec5SDimitry Andric /// \endcode
33790b57cec5SDimitry Andric /// In this example directive '#pragma omp target parallel' has clause 'if' with
33800b57cec5SDimitry Andric /// condition 'a'.
33810b57cec5SDimitry Andric ///
33820b57cec5SDimitry Andric class OMPTargetParallelDirective : public OMPExecutableDirective {
33830b57cec5SDimitry Andric   friend class ASTStmtReader;
3384e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
33855ffd83dbSDimitry Andric   /// true if the construct has inner cancel directive.
33865ffd83dbSDimitry Andric   bool HasCancel = false;
33875ffd83dbSDimitry Andric 
33880b57cec5SDimitry Andric   /// Build directive with the given start and end location.
33890b57cec5SDimitry Andric   ///
33900b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
33910b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
33920b57cec5SDimitry Andric   ///
OMPTargetParallelDirective(SourceLocation StartLoc,SourceLocation EndLoc)3393e8d8bef9SDimitry Andric   OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3394e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3395480093f4SDimitry Andric                                llvm::omp::OMPD_target_parallel, StartLoc,
3396e8d8bef9SDimitry Andric                                EndLoc) {}
33970b57cec5SDimitry Andric 
33980b57cec5SDimitry Andric   /// Build an empty directive.
33990b57cec5SDimitry Andric   ///
OMPTargetParallelDirective()3400e8d8bef9SDimitry Andric   explicit OMPTargetParallelDirective()
3401e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3402480093f4SDimitry Andric                                llvm::omp::OMPD_target_parallel,
3403e8d8bef9SDimitry Andric                                SourceLocation(), SourceLocation()) {}
34040b57cec5SDimitry Andric 
34055ffd83dbSDimitry Andric   /// Sets special task reduction descriptor.
setTaskReductionRefExpr(Expr * E)3406e8d8bef9SDimitry Andric   void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
34075ffd83dbSDimitry Andric   /// Set cancel state.
setHasCancel(bool Has)34085ffd83dbSDimitry Andric   void setHasCancel(bool Has) { HasCancel = Has; }
34095ffd83dbSDimitry Andric 
34100b57cec5SDimitry Andric public:
34110b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
34120b57cec5SDimitry Andric   ///
34130b57cec5SDimitry Andric   /// \param C AST context.
34140b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
34150b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
34160b57cec5SDimitry Andric   /// \param Clauses List of clauses.
34170b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
34185ffd83dbSDimitry Andric   /// \param TaskRedRef Task reduction special reference expression to handle
34195ffd83dbSDimitry Andric   /// taskgroup descriptor.
34205ffd83dbSDimitry Andric   /// \param HasCancel true if this directive has inner cancel directive.
34210b57cec5SDimitry Andric   ///
34220b57cec5SDimitry Andric   static OMPTargetParallelDirective *
34230b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
34245ffd83dbSDimitry Andric          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
34255ffd83dbSDimitry Andric          bool HasCancel);
34260b57cec5SDimitry Andric 
34270b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses
34280b57cec5SDimitry Andric   /// clauses.
34290b57cec5SDimitry Andric   ///
34300b57cec5SDimitry Andric   /// \param C AST context.
34310b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
34320b57cec5SDimitry Andric   ///
34330b57cec5SDimitry Andric   static OMPTargetParallelDirective *
34340b57cec5SDimitry Andric   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
34350b57cec5SDimitry Andric 
34365ffd83dbSDimitry Andric   /// Returns special task reduction reference expression.
getTaskReductionRefExpr()3437e8d8bef9SDimitry Andric   Expr *getTaskReductionRefExpr() {
3438e8d8bef9SDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[0]);
3439e8d8bef9SDimitry Andric   }
getTaskReductionRefExpr()3440e8d8bef9SDimitry Andric   const Expr *getTaskReductionRefExpr() const {
3441e8d8bef9SDimitry Andric     return const_cast<OMPTargetParallelDirective *>(this)
3442e8d8bef9SDimitry Andric         ->getTaskReductionRefExpr();
3443e8d8bef9SDimitry Andric   }
34445ffd83dbSDimitry Andric 
34455ffd83dbSDimitry Andric   /// Return true if current directive has inner cancel directive.
hasCancel()34465ffd83dbSDimitry Andric   bool hasCancel() const { return HasCancel; }
34475ffd83dbSDimitry Andric 
classof(const Stmt * T)34480b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
34490b57cec5SDimitry Andric     return T->getStmtClass() == OMPTargetParallelDirectiveClass;
34500b57cec5SDimitry Andric   }
34510b57cec5SDimitry Andric };
34520b57cec5SDimitry Andric 
34530b57cec5SDimitry Andric /// This represents '#pragma omp target parallel for' directive.
34540b57cec5SDimitry Andric ///
34550b57cec5SDimitry Andric /// \code
34560b57cec5SDimitry Andric /// #pragma omp target parallel for private(a,b) reduction(+:c,d)
34570b57cec5SDimitry Andric /// \endcode
34580b57cec5SDimitry Andric /// In this example directive '#pragma omp target parallel for' has clauses
34590b57cec5SDimitry Andric /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
34600b57cec5SDimitry Andric /// and variables 'c' and 'd'.
34610b57cec5SDimitry Andric ///
34620b57cec5SDimitry Andric class OMPTargetParallelForDirective : public OMPLoopDirective {
34630b57cec5SDimitry Andric   friend class ASTStmtReader;
3464e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
34650b57cec5SDimitry Andric 
34660b57cec5SDimitry Andric   /// true if current region has inner cancel directive.
3467e8d8bef9SDimitry Andric   bool HasCancel = false;
34680b57cec5SDimitry Andric 
34690b57cec5SDimitry Andric   /// Build directive with the given start and end location.
34700b57cec5SDimitry Andric   ///
34710b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
34720b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
34730b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
34740b57cec5SDimitry Andric   ///
OMPTargetParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)34750b57cec5SDimitry Andric   OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3476e8d8bef9SDimitry Andric                                 unsigned CollapsedNum)
3477e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3478480093f4SDimitry Andric                          llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc,
3479e8d8bef9SDimitry Andric                          CollapsedNum) {}
34800b57cec5SDimitry Andric 
34810b57cec5SDimitry Andric   /// Build an empty directive.
34820b57cec5SDimitry Andric   ///
34830b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
34840b57cec5SDimitry Andric   ///
OMPTargetParallelForDirective(unsigned CollapsedNum)3485e8d8bef9SDimitry Andric   explicit OMPTargetParallelForDirective(unsigned CollapsedNum)
3486e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3487480093f4SDimitry Andric                          llvm::omp::OMPD_target_parallel_for, SourceLocation(),
3488e8d8bef9SDimitry Andric                          SourceLocation(), CollapsedNum) {}
34890b57cec5SDimitry Andric 
34905ffd83dbSDimitry Andric   /// Sets special task reduction descriptor.
setTaskReductionRefExpr(Expr * E)3491e8d8bef9SDimitry Andric   void setTaskReductionRefExpr(Expr *E) {
3492e8d8bef9SDimitry Andric     Data->getChildren()[numLoopChildren(
3493fe6060f1SDimitry Andric         getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E;
3494e8d8bef9SDimitry Andric   }
34955ffd83dbSDimitry Andric 
34960b57cec5SDimitry Andric   /// Set cancel state.
setHasCancel(bool Has)34970b57cec5SDimitry Andric   void setHasCancel(bool Has) { HasCancel = Has; }
34980b57cec5SDimitry Andric 
34990b57cec5SDimitry Andric public:
35000b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
35010b57cec5SDimitry Andric   ///
35020b57cec5SDimitry Andric   /// \param C AST context.
35030b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
35040b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
35050b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
35060b57cec5SDimitry Andric   /// \param Clauses List of clauses.
35070b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
35080b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
35095ffd83dbSDimitry Andric   /// \param TaskRedRef Task reduction special reference expression to handle
35105ffd83dbSDimitry Andric   /// taskgroup descriptor.
35110b57cec5SDimitry Andric   /// \param HasCancel true if current directive has inner cancel directive.
35120b57cec5SDimitry Andric   ///
35130b57cec5SDimitry Andric   static OMPTargetParallelForDirective *
35140b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
35150b57cec5SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
35165ffd83dbSDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
35175ffd83dbSDimitry Andric          bool HasCancel);
35180b57cec5SDimitry Andric 
35190b57cec5SDimitry Andric   /// Creates an empty directive with the place
35200b57cec5SDimitry Andric   /// for \a NumClauses clauses.
35210b57cec5SDimitry Andric   ///
35220b57cec5SDimitry Andric   /// \param C AST context.
35230b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
35240b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
35250b57cec5SDimitry Andric   ///
35260b57cec5SDimitry Andric   static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C,
35270b57cec5SDimitry Andric                                                     unsigned NumClauses,
35280b57cec5SDimitry Andric                                                     unsigned CollapsedNum,
35290b57cec5SDimitry Andric                                                     EmptyShell);
35300b57cec5SDimitry Andric 
35315ffd83dbSDimitry Andric   /// Returns special task reduction reference expression.
getTaskReductionRefExpr()3532e8d8bef9SDimitry Andric   Expr *getTaskReductionRefExpr() {
3533e8d8bef9SDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
3534fe6060f1SDimitry Andric         getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]);
3535e8d8bef9SDimitry Andric   }
getTaskReductionRefExpr()3536e8d8bef9SDimitry Andric   const Expr *getTaskReductionRefExpr() const {
3537e8d8bef9SDimitry Andric     return const_cast<OMPTargetParallelForDirective *>(this)
3538e8d8bef9SDimitry Andric         ->getTaskReductionRefExpr();
3539e8d8bef9SDimitry Andric   }
35405ffd83dbSDimitry Andric 
35410b57cec5SDimitry Andric   /// Return true if current directive has inner cancel directive.
hasCancel()35420b57cec5SDimitry Andric   bool hasCancel() const { return HasCancel; }
35430b57cec5SDimitry Andric 
classof(const Stmt * T)35440b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
35450b57cec5SDimitry Andric     return T->getStmtClass() == OMPTargetParallelForDirectiveClass;
35460b57cec5SDimitry Andric   }
35470b57cec5SDimitry Andric };
35480b57cec5SDimitry Andric 
35490b57cec5SDimitry Andric /// This represents '#pragma omp teams' directive.
35500b57cec5SDimitry Andric ///
35510b57cec5SDimitry Andric /// \code
35520b57cec5SDimitry Andric /// #pragma omp teams if(a)
35530b57cec5SDimitry Andric /// \endcode
35540b57cec5SDimitry Andric /// In this example directive '#pragma omp teams' has clause 'if' with
35550b57cec5SDimitry Andric /// condition 'a'.
35560b57cec5SDimitry Andric ///
35570b57cec5SDimitry Andric class OMPTeamsDirective : public OMPExecutableDirective {
35580b57cec5SDimitry Andric   friend class ASTStmtReader;
3559e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
35600b57cec5SDimitry Andric   /// Build directive with the given start and end location.
35610b57cec5SDimitry Andric   ///
35620b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
35630b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
35640b57cec5SDimitry Andric   ///
OMPTeamsDirective(SourceLocation StartLoc,SourceLocation EndLoc)3565e8d8bef9SDimitry Andric   OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3566e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3567e8d8bef9SDimitry Andric                                StartLoc, EndLoc) {}
35680b57cec5SDimitry Andric 
35690b57cec5SDimitry Andric   /// Build an empty directive.
35700b57cec5SDimitry Andric   ///
OMPTeamsDirective()3571e8d8bef9SDimitry Andric   explicit OMPTeamsDirective()
3572e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3573e8d8bef9SDimitry Andric                                SourceLocation(), SourceLocation()) {}
35740b57cec5SDimitry Andric 
35750b57cec5SDimitry Andric public:
35760b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
35770b57cec5SDimitry Andric   ///
35780b57cec5SDimitry Andric   /// \param C AST context.
35790b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
35800b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
35810b57cec5SDimitry Andric   /// \param Clauses List of clauses.
35820b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
35830b57cec5SDimitry Andric   ///
35840b57cec5SDimitry Andric   static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
35850b57cec5SDimitry Andric                                    SourceLocation EndLoc,
35860b57cec5SDimitry Andric                                    ArrayRef<OMPClause *> Clauses,
35870b57cec5SDimitry Andric                                    Stmt *AssociatedStmt);
35880b57cec5SDimitry Andric 
35890b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses
35900b57cec5SDimitry Andric   /// clauses.
35910b57cec5SDimitry Andric   ///
35920b57cec5SDimitry Andric   /// \param C AST context.
35930b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
35940b57cec5SDimitry Andric   ///
35950b57cec5SDimitry Andric   static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
35960b57cec5SDimitry Andric                                         unsigned NumClauses, EmptyShell);
35970b57cec5SDimitry Andric 
classof(const Stmt * T)35980b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
35990b57cec5SDimitry Andric     return T->getStmtClass() == OMPTeamsDirectiveClass;
36000b57cec5SDimitry Andric   }
36010b57cec5SDimitry Andric };
36020b57cec5SDimitry Andric 
36030b57cec5SDimitry Andric /// This represents '#pragma omp cancellation point' directive.
36040b57cec5SDimitry Andric ///
36050b57cec5SDimitry Andric /// \code
36060b57cec5SDimitry Andric /// #pragma omp cancellation point for
36070b57cec5SDimitry Andric /// \endcode
36080b57cec5SDimitry Andric ///
36090b57cec5SDimitry Andric /// In this example a cancellation point is created for innermost 'for' region.
36100b57cec5SDimitry Andric class OMPCancellationPointDirective : public OMPExecutableDirective {
36110b57cec5SDimitry Andric   friend class ASTStmtReader;
3612e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
3613e8d8bef9SDimitry Andric   OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
36140b57cec5SDimitry Andric   /// Build directive with the given start and end location.
36150b57cec5SDimitry Andric   ///
36160b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
36170b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
3618e8d8bef9SDimitry Andric   /// statements and child expressions.
36190b57cec5SDimitry Andric   ///
OMPCancellationPointDirective(SourceLocation StartLoc,SourceLocation EndLoc)36200b57cec5SDimitry Andric   OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3621e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3622480093f4SDimitry Andric                                llvm::omp::OMPD_cancellation_point, StartLoc,
3623e8d8bef9SDimitry Andric                                EndLoc) {}
36240b57cec5SDimitry Andric 
36250b57cec5SDimitry Andric   /// Build an empty directive.
OMPCancellationPointDirective()36260b57cec5SDimitry Andric   explicit OMPCancellationPointDirective()
3627e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3628480093f4SDimitry Andric                                llvm::omp::OMPD_cancellation_point,
3629e8d8bef9SDimitry Andric                                SourceLocation(), SourceLocation()) {}
36300b57cec5SDimitry Andric 
36310b57cec5SDimitry Andric   /// Set cancel region for current cancellation point.
36320b57cec5SDimitry Andric   /// \param CR Cancellation region.
setCancelRegion(OpenMPDirectiveKind CR)36330b57cec5SDimitry Andric   void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
36340b57cec5SDimitry Andric 
36350b57cec5SDimitry Andric public:
36360b57cec5SDimitry Andric   /// Creates directive.
36370b57cec5SDimitry Andric   ///
36380b57cec5SDimitry Andric   /// \param C AST context.
36390b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
36400b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
36410b57cec5SDimitry Andric   ///
36420b57cec5SDimitry Andric   static OMPCancellationPointDirective *
36430b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
36440b57cec5SDimitry Andric          OpenMPDirectiveKind CancelRegion);
36450b57cec5SDimitry Andric 
36460b57cec5SDimitry Andric   /// Creates an empty directive.
36470b57cec5SDimitry Andric   ///
36480b57cec5SDimitry Andric   /// \param C AST context.
36490b57cec5SDimitry Andric   ///
36500b57cec5SDimitry Andric   static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
36510b57cec5SDimitry Andric                                                     EmptyShell);
36520b57cec5SDimitry Andric 
36530b57cec5SDimitry Andric   /// Get cancellation region for the current cancellation point.
getCancelRegion()36540b57cec5SDimitry Andric   OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
36550b57cec5SDimitry Andric 
classof(const Stmt * T)36560b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
36570b57cec5SDimitry Andric     return T->getStmtClass() == OMPCancellationPointDirectiveClass;
36580b57cec5SDimitry Andric   }
36590b57cec5SDimitry Andric };
36600b57cec5SDimitry Andric 
36610b57cec5SDimitry Andric /// This represents '#pragma omp cancel' directive.
36620b57cec5SDimitry Andric ///
36630b57cec5SDimitry Andric /// \code
36640b57cec5SDimitry Andric /// #pragma omp cancel for
36650b57cec5SDimitry Andric /// \endcode
36660b57cec5SDimitry Andric ///
36670b57cec5SDimitry Andric /// In this example a cancel is created for innermost 'for' region.
36680b57cec5SDimitry Andric class OMPCancelDirective : public OMPExecutableDirective {
36690b57cec5SDimitry Andric   friend class ASTStmtReader;
3670e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
3671e8d8bef9SDimitry Andric   OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
36720b57cec5SDimitry Andric   /// Build directive with the given start and end location.
36730b57cec5SDimitry Andric   ///
36740b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
36750b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
36760b57cec5SDimitry Andric   ///
OMPCancelDirective(SourceLocation StartLoc,SourceLocation EndLoc)3677e8d8bef9SDimitry Andric   OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3678e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3679e8d8bef9SDimitry Andric                                StartLoc, EndLoc) {}
36800b57cec5SDimitry Andric 
36810b57cec5SDimitry Andric   /// Build an empty directive.
36820b57cec5SDimitry Andric   ///
OMPCancelDirective()3683e8d8bef9SDimitry Andric   explicit OMPCancelDirective()
3684e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3685e8d8bef9SDimitry Andric                                SourceLocation(), SourceLocation()) {}
36860b57cec5SDimitry Andric 
36870b57cec5SDimitry Andric   /// Set cancel region for current cancellation point.
36880b57cec5SDimitry Andric   /// \param CR Cancellation region.
setCancelRegion(OpenMPDirectiveKind CR)36890b57cec5SDimitry Andric   void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
36900b57cec5SDimitry Andric 
36910b57cec5SDimitry Andric public:
36920b57cec5SDimitry Andric   /// Creates directive.
36930b57cec5SDimitry Andric   ///
36940b57cec5SDimitry Andric   /// \param C AST context.
36950b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
36960b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
36970b57cec5SDimitry Andric   /// \param Clauses List of clauses.
36980b57cec5SDimitry Andric   ///
36990b57cec5SDimitry Andric   static OMPCancelDirective *
37000b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
37010b57cec5SDimitry Andric          ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
37020b57cec5SDimitry Andric 
37030b57cec5SDimitry Andric   /// Creates an empty directive.
37040b57cec5SDimitry Andric   ///
37050b57cec5SDimitry Andric   /// \param C AST context.
37060b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
37070b57cec5SDimitry Andric   ///
37080b57cec5SDimitry Andric   static OMPCancelDirective *CreateEmpty(const ASTContext &C,
37090b57cec5SDimitry Andric                                          unsigned NumClauses, EmptyShell);
37100b57cec5SDimitry Andric 
37110b57cec5SDimitry Andric   /// Get cancellation region for the current cancellation point.
getCancelRegion()37120b57cec5SDimitry Andric   OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
37130b57cec5SDimitry Andric 
classof(const Stmt * T)37140b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
37150b57cec5SDimitry Andric     return T->getStmtClass() == OMPCancelDirectiveClass;
37160b57cec5SDimitry Andric   }
37170b57cec5SDimitry Andric };
37180b57cec5SDimitry Andric 
37190b57cec5SDimitry Andric /// This represents '#pragma omp taskloop' directive.
37200b57cec5SDimitry Andric ///
37210b57cec5SDimitry Andric /// \code
37220b57cec5SDimitry Andric /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
37230b57cec5SDimitry Andric /// \endcode
37240b57cec5SDimitry Andric /// In this example directive '#pragma omp taskloop' has clauses 'private'
37250b57cec5SDimitry Andric /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
37260b57cec5SDimitry Andric /// 'num_tasks' with expression 'num'.
37270b57cec5SDimitry Andric ///
37280b57cec5SDimitry Andric class OMPTaskLoopDirective : public OMPLoopDirective {
37290b57cec5SDimitry Andric   friend class ASTStmtReader;
3730e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
37315ffd83dbSDimitry Andric   /// true if the construct has inner cancel directive.
3732e8d8bef9SDimitry Andric   bool HasCancel = false;
37335ffd83dbSDimitry Andric 
37340b57cec5SDimitry Andric   /// Build directive with the given start and end location.
37350b57cec5SDimitry Andric   ///
37360b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
37370b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
37380b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
37390b57cec5SDimitry Andric   ///
OMPTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)37400b57cec5SDimitry Andric   OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3741e8d8bef9SDimitry Andric                        unsigned CollapsedNum)
3742e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3743e8d8bef9SDimitry Andric                          StartLoc, EndLoc, CollapsedNum) {}
37440b57cec5SDimitry Andric 
37450b57cec5SDimitry Andric   /// Build an empty directive.
37460b57cec5SDimitry Andric   ///
37470b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
37480b57cec5SDimitry Andric   ///
OMPTaskLoopDirective(unsigned CollapsedNum)3749e8d8bef9SDimitry Andric   explicit OMPTaskLoopDirective(unsigned CollapsedNum)
3750e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3751e8d8bef9SDimitry Andric                          SourceLocation(), SourceLocation(), CollapsedNum) {}
37525ffd83dbSDimitry Andric 
37535ffd83dbSDimitry Andric   /// Set cancel state.
setHasCancel(bool Has)37545ffd83dbSDimitry Andric   void setHasCancel(bool Has) { HasCancel = Has; }
37550b57cec5SDimitry Andric 
37560b57cec5SDimitry Andric public:
37570b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
37580b57cec5SDimitry Andric   ///
37590b57cec5SDimitry Andric   /// \param C AST context.
37600b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
37610b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
37620b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
37630b57cec5SDimitry Andric   /// \param Clauses List of clauses.
37640b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
37650b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
37665ffd83dbSDimitry Andric   /// \param HasCancel true if this directive has inner cancel directive.
37670b57cec5SDimitry Andric   ///
37680b57cec5SDimitry Andric   static OMPTaskLoopDirective *
37690b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
37700b57cec5SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
37715ffd83dbSDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
37720b57cec5SDimitry Andric 
37730b57cec5SDimitry Andric   /// Creates an empty directive with the place
37740b57cec5SDimitry Andric   /// for \a NumClauses clauses.
37750b57cec5SDimitry Andric   ///
37760b57cec5SDimitry Andric   /// \param C AST context.
37770b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
37780b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
37790b57cec5SDimitry Andric   ///
37800b57cec5SDimitry Andric   static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
37810b57cec5SDimitry Andric                                            unsigned NumClauses,
37820b57cec5SDimitry Andric                                            unsigned CollapsedNum, EmptyShell);
37830b57cec5SDimitry Andric 
37845ffd83dbSDimitry Andric   /// Return true if current directive has inner cancel directive.
hasCancel()37855ffd83dbSDimitry Andric   bool hasCancel() const { return HasCancel; }
37865ffd83dbSDimitry Andric 
classof(const Stmt * T)37870b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
37880b57cec5SDimitry Andric     return T->getStmtClass() == OMPTaskLoopDirectiveClass;
37890b57cec5SDimitry Andric   }
37900b57cec5SDimitry Andric };
37910b57cec5SDimitry Andric 
37920b57cec5SDimitry Andric /// This represents '#pragma omp taskloop simd' directive.
37930b57cec5SDimitry Andric ///
37940b57cec5SDimitry Andric /// \code
37950b57cec5SDimitry Andric /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
37960b57cec5SDimitry Andric /// \endcode
37970b57cec5SDimitry Andric /// In this example directive '#pragma omp taskloop simd' has clauses 'private'
37980b57cec5SDimitry Andric /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
37990b57cec5SDimitry Andric /// 'num_tasks' with expression 'num'.
38000b57cec5SDimitry Andric ///
38010b57cec5SDimitry Andric class OMPTaskLoopSimdDirective : public OMPLoopDirective {
38020b57cec5SDimitry Andric   friend class ASTStmtReader;
3803e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
38040b57cec5SDimitry Andric   /// Build directive with the given start and end location.
38050b57cec5SDimitry Andric   ///
38060b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
38070b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
38080b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
38090b57cec5SDimitry Andric   ///
OMPTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)38100b57cec5SDimitry Andric   OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3811e8d8bef9SDimitry Andric                            unsigned CollapsedNum)
3812e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3813480093f4SDimitry Andric                          llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc,
3814e8d8bef9SDimitry Andric                          CollapsedNum) {}
38150b57cec5SDimitry Andric 
38160b57cec5SDimitry Andric   /// Build an empty directive.
38170b57cec5SDimitry Andric   ///
38180b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
38190b57cec5SDimitry Andric   ///
OMPTaskLoopSimdDirective(unsigned CollapsedNum)3820e8d8bef9SDimitry Andric   explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum)
3821e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3822480093f4SDimitry Andric                          llvm::omp::OMPD_taskloop_simd, SourceLocation(),
3823e8d8bef9SDimitry Andric                          SourceLocation(), CollapsedNum) {}
38240b57cec5SDimitry Andric 
38250b57cec5SDimitry Andric public:
38260b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
38270b57cec5SDimitry Andric   ///
38280b57cec5SDimitry Andric   /// \param C AST context.
38290b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
38300b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
38310b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
38320b57cec5SDimitry Andric   /// \param Clauses List of clauses.
38330b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
38340b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
38350b57cec5SDimitry Andric   ///
38360b57cec5SDimitry Andric   static OMPTaskLoopSimdDirective *
38370b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
38380b57cec5SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
38390b57cec5SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
38400b57cec5SDimitry Andric 
38410b57cec5SDimitry Andric   /// Creates an empty directive with the place
38420b57cec5SDimitry Andric   /// for \a NumClauses clauses.
38430b57cec5SDimitry Andric   ///
38440b57cec5SDimitry Andric   /// \param C AST context.
38450b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
38460b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
38470b57cec5SDimitry Andric   ///
38480b57cec5SDimitry Andric   static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
38490b57cec5SDimitry Andric                                                unsigned NumClauses,
38500b57cec5SDimitry Andric                                                unsigned CollapsedNum,
38510b57cec5SDimitry Andric                                                EmptyShell);
38520b57cec5SDimitry Andric 
classof(const Stmt * T)38530b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
38540b57cec5SDimitry Andric     return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
38550b57cec5SDimitry Andric   }
38560b57cec5SDimitry Andric };
38570b57cec5SDimitry Andric 
3858a7dea167SDimitry Andric /// This represents '#pragma omp master taskloop' directive.
3859a7dea167SDimitry Andric ///
3860a7dea167SDimitry Andric /// \code
3861a7dea167SDimitry Andric /// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num)
3862a7dea167SDimitry Andric /// \endcode
3863a7dea167SDimitry Andric /// In this example directive '#pragma omp master taskloop' has clauses
3864a7dea167SDimitry Andric /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3865a7dea167SDimitry Andric /// and 'num_tasks' with expression 'num'.
3866a7dea167SDimitry Andric ///
3867a7dea167SDimitry Andric class OMPMasterTaskLoopDirective : public OMPLoopDirective {
3868a7dea167SDimitry Andric   friend class ASTStmtReader;
3869e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
38705ffd83dbSDimitry Andric   /// true if the construct has inner cancel directive.
3871e8d8bef9SDimitry Andric   bool HasCancel = false;
38725ffd83dbSDimitry Andric 
3873a7dea167SDimitry Andric   /// Build directive with the given start and end location.
3874a7dea167SDimitry Andric   ///
3875a7dea167SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
3876a7dea167SDimitry Andric   /// \param EndLoc Ending location of the directive.
3877a7dea167SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
3878a7dea167SDimitry Andric   ///
OMPMasterTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)3879a7dea167SDimitry Andric   OMPMasterTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3880e8d8bef9SDimitry Andric                              unsigned CollapsedNum)
3881e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3882480093f4SDimitry Andric                          llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc,
3883e8d8bef9SDimitry Andric                          CollapsedNum) {}
3884a7dea167SDimitry Andric 
3885a7dea167SDimitry Andric   /// Build an empty directive.
3886a7dea167SDimitry Andric   ///
3887a7dea167SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
3888a7dea167SDimitry Andric   ///
OMPMasterTaskLoopDirective(unsigned CollapsedNum)3889e8d8bef9SDimitry Andric   explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum)
3890e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3891480093f4SDimitry Andric                          llvm::omp::OMPD_master_taskloop, SourceLocation(),
3892e8d8bef9SDimitry Andric                          SourceLocation(), CollapsedNum) {}
38935ffd83dbSDimitry Andric 
38945ffd83dbSDimitry Andric   /// Set cancel state.
setHasCancel(bool Has)38955ffd83dbSDimitry Andric   void setHasCancel(bool Has) { HasCancel = Has; }
3896a7dea167SDimitry Andric 
3897a7dea167SDimitry Andric public:
3898a7dea167SDimitry Andric   /// Creates directive with a list of \a Clauses.
3899a7dea167SDimitry Andric   ///
3900a7dea167SDimitry Andric   /// \param C AST context.
3901a7dea167SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
3902a7dea167SDimitry Andric   /// \param EndLoc Ending Location of the directive.
3903a7dea167SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
3904a7dea167SDimitry Andric   /// \param Clauses List of clauses.
3905a7dea167SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
3906a7dea167SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
39075ffd83dbSDimitry Andric   /// \param HasCancel true if this directive has inner cancel directive.
3908a7dea167SDimitry Andric   ///
3909a7dea167SDimitry Andric   static OMPMasterTaskLoopDirective *
3910a7dea167SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3911a7dea167SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
39125ffd83dbSDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3913a7dea167SDimitry Andric 
3914a7dea167SDimitry Andric   /// Creates an empty directive with the place
3915a7dea167SDimitry Andric   /// for \a NumClauses clauses.
3916a7dea167SDimitry Andric   ///
3917a7dea167SDimitry Andric   /// \param C AST context.
3918a7dea167SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
3919a7dea167SDimitry Andric   /// \param NumClauses Number of clauses.
3920a7dea167SDimitry Andric   ///
3921a7dea167SDimitry Andric   static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
3922a7dea167SDimitry Andric                                                  unsigned NumClauses,
3923a7dea167SDimitry Andric                                                  unsigned CollapsedNum,
3924a7dea167SDimitry Andric                                                  EmptyShell);
3925a7dea167SDimitry Andric 
39265ffd83dbSDimitry Andric   /// Return true if current directive has inner cancel directive.
hasCancel()39275ffd83dbSDimitry Andric   bool hasCancel() const { return HasCancel; }
39285ffd83dbSDimitry Andric 
classof(const Stmt * T)3929a7dea167SDimitry Andric   static bool classof(const Stmt *T) {
3930a7dea167SDimitry Andric     return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass;
3931a7dea167SDimitry Andric   }
3932a7dea167SDimitry Andric };
3933a7dea167SDimitry Andric 
393481ad6265SDimitry Andric /// This represents '#pragma omp masked taskloop' directive.
393581ad6265SDimitry Andric ///
393681ad6265SDimitry Andric /// \code
393781ad6265SDimitry Andric /// #pragma omp masked taskloop private(a,b) grainsize(val) num_tasks(num)
393881ad6265SDimitry Andric /// \endcode
393981ad6265SDimitry Andric /// In this example directive '#pragma omp masked taskloop' has clauses
394081ad6265SDimitry Andric /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
394181ad6265SDimitry Andric /// and 'num_tasks' with expression 'num'.
394281ad6265SDimitry Andric ///
394381ad6265SDimitry Andric class OMPMaskedTaskLoopDirective final : public OMPLoopDirective {
394481ad6265SDimitry Andric   friend class ASTStmtReader;
394581ad6265SDimitry Andric   friend class OMPExecutableDirective;
394681ad6265SDimitry Andric   /// true if the construct has inner cancel directive.
394781ad6265SDimitry Andric   bool HasCancel = false;
394881ad6265SDimitry Andric 
394981ad6265SDimitry Andric   /// Build directive with the given start and end location.
395081ad6265SDimitry Andric   ///
395181ad6265SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
395281ad6265SDimitry Andric   /// \param EndLoc Ending location of the directive.
395381ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
395481ad6265SDimitry Andric   ///
OMPMaskedTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)395581ad6265SDimitry Andric   OMPMaskedTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
395681ad6265SDimitry Andric                              unsigned CollapsedNum)
395781ad6265SDimitry Andric       : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
395881ad6265SDimitry Andric                          llvm::omp::OMPD_masked_taskloop, StartLoc, EndLoc,
395981ad6265SDimitry Andric                          CollapsedNum) {}
396081ad6265SDimitry Andric 
396181ad6265SDimitry Andric   /// Build an empty directive.
396281ad6265SDimitry Andric   ///
396381ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
396481ad6265SDimitry Andric   ///
OMPMaskedTaskLoopDirective(unsigned CollapsedNum)396581ad6265SDimitry Andric   explicit OMPMaskedTaskLoopDirective(unsigned CollapsedNum)
396681ad6265SDimitry Andric       : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
396781ad6265SDimitry Andric                          llvm::omp::OMPD_masked_taskloop, SourceLocation(),
396881ad6265SDimitry Andric                          SourceLocation(), CollapsedNum) {}
396981ad6265SDimitry Andric 
397081ad6265SDimitry Andric   /// Set cancel state.
setHasCancel(bool Has)397181ad6265SDimitry Andric   void setHasCancel(bool Has) { HasCancel = Has; }
397281ad6265SDimitry Andric 
397381ad6265SDimitry Andric public:
397481ad6265SDimitry Andric   /// Creates directive with a list of \a Clauses.
397581ad6265SDimitry Andric   ///
397681ad6265SDimitry Andric   /// \param C AST context.
397781ad6265SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
397881ad6265SDimitry Andric   /// \param EndLoc Ending Location of the directive.
397981ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
398081ad6265SDimitry Andric   /// \param Clauses List of clauses.
398181ad6265SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
398281ad6265SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
398381ad6265SDimitry Andric   /// \param HasCancel true if this directive has inner cancel directive.
398481ad6265SDimitry Andric   ///
398581ad6265SDimitry Andric   static OMPMaskedTaskLoopDirective *
398681ad6265SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
398781ad6265SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
398881ad6265SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
398981ad6265SDimitry Andric 
399081ad6265SDimitry Andric   /// Creates an empty directive with the place
399181ad6265SDimitry Andric   /// for \a NumClauses clauses.
399281ad6265SDimitry Andric   ///
399381ad6265SDimitry Andric   /// \param C AST context.
399481ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
399581ad6265SDimitry Andric   /// \param NumClauses Number of clauses.
399681ad6265SDimitry Andric   ///
399781ad6265SDimitry Andric   static OMPMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
399881ad6265SDimitry Andric                                                  unsigned NumClauses,
399981ad6265SDimitry Andric                                                  unsigned CollapsedNum,
400081ad6265SDimitry Andric                                                  EmptyShell);
400181ad6265SDimitry Andric 
400281ad6265SDimitry Andric   /// Return true if current directive has inner cancel directive.
hasCancel()400381ad6265SDimitry Andric   bool hasCancel() const { return HasCancel; }
400481ad6265SDimitry Andric 
classof(const Stmt * T)400581ad6265SDimitry Andric   static bool classof(const Stmt *T) {
400681ad6265SDimitry Andric     return T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass;
400781ad6265SDimitry Andric   }
400881ad6265SDimitry Andric };
400981ad6265SDimitry Andric 
4010a7dea167SDimitry Andric /// This represents '#pragma omp master taskloop simd' directive.
4011a7dea167SDimitry Andric ///
4012a7dea167SDimitry Andric /// \code
4013a7dea167SDimitry Andric /// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num)
4014a7dea167SDimitry Andric /// \endcode
4015a7dea167SDimitry Andric /// In this example directive '#pragma omp master taskloop simd' has clauses
4016a7dea167SDimitry Andric /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4017a7dea167SDimitry Andric /// and 'num_tasks' with expression 'num'.
4018a7dea167SDimitry Andric ///
4019a7dea167SDimitry Andric class OMPMasterTaskLoopSimdDirective : public OMPLoopDirective {
4020a7dea167SDimitry Andric   friend class ASTStmtReader;
4021e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
4022a7dea167SDimitry Andric   /// Build directive with the given start and end location.
4023a7dea167SDimitry Andric   ///
4024a7dea167SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
4025a7dea167SDimitry Andric   /// \param EndLoc Ending location of the directive.
4026a7dea167SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
4027a7dea167SDimitry Andric   ///
OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4028a7dea167SDimitry Andric   OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4029e8d8bef9SDimitry Andric                                  unsigned CollapsedNum)
4030e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
4031480093f4SDimitry Andric                          llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc,
4032e8d8bef9SDimitry Andric                          CollapsedNum) {}
4033a7dea167SDimitry Andric 
4034a7dea167SDimitry Andric   /// Build an empty directive.
4035a7dea167SDimitry Andric   ///
4036a7dea167SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
4037a7dea167SDimitry Andric   ///
OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum)4038e8d8bef9SDimitry Andric   explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum)
4039e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
4040480093f4SDimitry Andric                          llvm::omp::OMPD_master_taskloop_simd, SourceLocation(),
4041e8d8bef9SDimitry Andric                          SourceLocation(), CollapsedNum) {}
4042a7dea167SDimitry Andric 
4043a7dea167SDimitry Andric public:
4044a7dea167SDimitry Andric   /// Creates directive with a list of \p Clauses.
4045a7dea167SDimitry Andric   ///
4046a7dea167SDimitry Andric   /// \param C AST context.
4047a7dea167SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
4048a7dea167SDimitry Andric   /// \param EndLoc Ending Location of the directive.
4049a7dea167SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
4050a7dea167SDimitry Andric   /// \param Clauses List of clauses.
4051a7dea167SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
4052a7dea167SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
4053a7dea167SDimitry Andric   ///
4054a7dea167SDimitry Andric   static OMPMasterTaskLoopSimdDirective *
4055a7dea167SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4056a7dea167SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4057a7dea167SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
4058a7dea167SDimitry Andric 
4059a7dea167SDimitry Andric   /// Creates an empty directive with the place for \p NumClauses clauses.
4060a7dea167SDimitry Andric   ///
4061a7dea167SDimitry Andric   /// \param C AST context.
4062a7dea167SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
4063a7dea167SDimitry Andric   /// \param NumClauses Number of clauses.
4064a7dea167SDimitry Andric   ///
4065a7dea167SDimitry Andric   static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
4066a7dea167SDimitry Andric                                                      unsigned NumClauses,
4067a7dea167SDimitry Andric                                                      unsigned CollapsedNum,
4068a7dea167SDimitry Andric                                                      EmptyShell);
4069a7dea167SDimitry Andric 
classof(const Stmt * T)4070a7dea167SDimitry Andric   static bool classof(const Stmt *T) {
4071a7dea167SDimitry Andric     return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass;
4072a7dea167SDimitry Andric   }
4073a7dea167SDimitry Andric };
4074a7dea167SDimitry Andric 
407581ad6265SDimitry Andric /// This represents '#pragma omp masked taskloop simd' directive.
407681ad6265SDimitry Andric ///
407781ad6265SDimitry Andric /// \code
407881ad6265SDimitry Andric /// #pragma omp masked taskloop simd private(a,b) grainsize(val) num_tasks(num)
407981ad6265SDimitry Andric /// \endcode
408081ad6265SDimitry Andric /// In this example directive '#pragma omp masked taskloop simd' has clauses
408181ad6265SDimitry Andric /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
408281ad6265SDimitry Andric /// and 'num_tasks' with expression 'num'.
408381ad6265SDimitry Andric ///
408481ad6265SDimitry Andric class OMPMaskedTaskLoopSimdDirective final : public OMPLoopDirective {
408581ad6265SDimitry Andric   friend class ASTStmtReader;
408681ad6265SDimitry Andric   friend class OMPExecutableDirective;
408781ad6265SDimitry Andric   /// Build directive with the given start and end location.
408881ad6265SDimitry Andric   ///
408981ad6265SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
409081ad6265SDimitry Andric   /// \param EndLoc Ending location of the directive.
409181ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
409281ad6265SDimitry Andric   ///
OMPMaskedTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)409381ad6265SDimitry Andric   OMPMaskedTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
409481ad6265SDimitry Andric                                  unsigned CollapsedNum)
409581ad6265SDimitry Andric       : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
409681ad6265SDimitry Andric                          llvm::omp::OMPD_masked_taskloop_simd, StartLoc, EndLoc,
409781ad6265SDimitry Andric                          CollapsedNum) {}
409881ad6265SDimitry Andric 
409981ad6265SDimitry Andric   /// Build an empty directive.
410081ad6265SDimitry Andric   ///
410181ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
410281ad6265SDimitry Andric   ///
OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum)410381ad6265SDimitry Andric   explicit OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
410481ad6265SDimitry Andric       : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
410581ad6265SDimitry Andric                          llvm::omp::OMPD_masked_taskloop_simd, SourceLocation(),
410681ad6265SDimitry Andric                          SourceLocation(), CollapsedNum) {}
410781ad6265SDimitry Andric 
410881ad6265SDimitry Andric public:
410981ad6265SDimitry Andric   /// Creates directive with a list of \p Clauses.
411081ad6265SDimitry Andric   ///
411181ad6265SDimitry Andric   /// \param C AST context.
411281ad6265SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
411381ad6265SDimitry Andric   /// \param EndLoc Ending Location of the directive.
411481ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
411581ad6265SDimitry Andric   /// \param Clauses List of clauses.
411681ad6265SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
411781ad6265SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
411881ad6265SDimitry Andric   ///
411981ad6265SDimitry Andric   static OMPMaskedTaskLoopSimdDirective *
412081ad6265SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
412181ad6265SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
412281ad6265SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
412381ad6265SDimitry Andric 
412481ad6265SDimitry Andric   /// Creates an empty directive with the place for \p NumClauses clauses.
412581ad6265SDimitry Andric   ///
412681ad6265SDimitry Andric   /// \param C AST context.
412781ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
412881ad6265SDimitry Andric   /// \param NumClauses Number of clauses.
412981ad6265SDimitry Andric   ///
413081ad6265SDimitry Andric   static OMPMaskedTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
413181ad6265SDimitry Andric                                                      unsigned NumClauses,
413281ad6265SDimitry Andric                                                      unsigned CollapsedNum,
413381ad6265SDimitry Andric                                                      EmptyShell);
413481ad6265SDimitry Andric 
classof(const Stmt * T)413581ad6265SDimitry Andric   static bool classof(const Stmt *T) {
413681ad6265SDimitry Andric     return T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass;
413781ad6265SDimitry Andric   }
413881ad6265SDimitry Andric };
413981ad6265SDimitry Andric 
4140a7dea167SDimitry Andric /// This represents '#pragma omp parallel master taskloop' directive.
4141a7dea167SDimitry Andric ///
4142a7dea167SDimitry Andric /// \code
4143a7dea167SDimitry Andric /// #pragma omp parallel master taskloop private(a,b) grainsize(val)
4144a7dea167SDimitry Andric /// num_tasks(num)
4145a7dea167SDimitry Andric /// \endcode
4146a7dea167SDimitry Andric /// In this example directive '#pragma omp parallel master taskloop' has clauses
4147a7dea167SDimitry Andric /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4148a7dea167SDimitry Andric /// and 'num_tasks' with expression 'num'.
4149a7dea167SDimitry Andric ///
4150a7dea167SDimitry Andric class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective {
4151a7dea167SDimitry Andric   friend class ASTStmtReader;
4152e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
41535ffd83dbSDimitry Andric   /// true if the construct has inner cancel directive.
4154e8d8bef9SDimitry Andric   bool HasCancel = false;
41555ffd83dbSDimitry Andric 
4156a7dea167SDimitry Andric   /// Build directive with the given start and end location.
4157a7dea167SDimitry Andric   ///
4158a7dea167SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
4159a7dea167SDimitry Andric   /// \param EndLoc Ending location of the directive.
4160a7dea167SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
4161a7dea167SDimitry Andric   ///
OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4162a7dea167SDimitry Andric   OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc,
4163a7dea167SDimitry Andric                                      SourceLocation EndLoc,
4164e8d8bef9SDimitry Andric                                      unsigned CollapsedNum)
4165e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
4166480093f4SDimitry Andric                          llvm::omp::OMPD_parallel_master_taskloop, StartLoc,
4167e8d8bef9SDimitry Andric                          EndLoc, CollapsedNum) {}
4168a7dea167SDimitry Andric 
4169a7dea167SDimitry Andric   /// Build an empty directive.
4170a7dea167SDimitry Andric   ///
4171a7dea167SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
4172a7dea167SDimitry Andric   ///
OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum)4173e8d8bef9SDimitry Andric   explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum)
4174e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
4175480093f4SDimitry Andric                          llvm::omp::OMPD_parallel_master_taskloop,
4176e8d8bef9SDimitry Andric                          SourceLocation(), SourceLocation(), CollapsedNum) {}
41775ffd83dbSDimitry Andric 
41785ffd83dbSDimitry Andric   /// Set cancel state.
setHasCancel(bool Has)41795ffd83dbSDimitry Andric   void setHasCancel(bool Has) { HasCancel = Has; }
4180a7dea167SDimitry Andric 
4181a7dea167SDimitry Andric public:
4182a7dea167SDimitry Andric   /// Creates directive with a list of \a Clauses.
4183a7dea167SDimitry Andric   ///
4184a7dea167SDimitry Andric   /// \param C AST context.
4185a7dea167SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
4186a7dea167SDimitry Andric   /// \param EndLoc Ending Location of the directive.
4187a7dea167SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
4188a7dea167SDimitry Andric   /// \param Clauses List of clauses.
4189a7dea167SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
4190a7dea167SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
41915ffd83dbSDimitry Andric   /// \param HasCancel true if this directive has inner cancel directive.
4192a7dea167SDimitry Andric   ///
4193a7dea167SDimitry Andric   static OMPParallelMasterTaskLoopDirective *
4194a7dea167SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4195a7dea167SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
41965ffd83dbSDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
4197a7dea167SDimitry Andric 
4198a7dea167SDimitry Andric   /// Creates an empty directive with the place
4199a7dea167SDimitry Andric   /// for \a NumClauses clauses.
4200a7dea167SDimitry Andric   ///
4201a7dea167SDimitry Andric   /// \param C AST context.
4202a7dea167SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
4203a7dea167SDimitry Andric   /// \param NumClauses Number of clauses.
4204a7dea167SDimitry Andric   ///
4205a7dea167SDimitry Andric   static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
4206a7dea167SDimitry Andric                                                          unsigned NumClauses,
4207a7dea167SDimitry Andric                                                          unsigned CollapsedNum,
4208a7dea167SDimitry Andric                                                          EmptyShell);
4209a7dea167SDimitry Andric 
42105ffd83dbSDimitry Andric   /// Return true if current directive has inner cancel directive.
hasCancel()42115ffd83dbSDimitry Andric   bool hasCancel() const { return HasCancel; }
42125ffd83dbSDimitry Andric 
classof(const Stmt * T)4213a7dea167SDimitry Andric   static bool classof(const Stmt *T) {
4214a7dea167SDimitry Andric     return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass;
4215a7dea167SDimitry Andric   }
4216a7dea167SDimitry Andric };
4217a7dea167SDimitry Andric 
421881ad6265SDimitry Andric /// This represents '#pragma omp parallel masked taskloop' directive.
421981ad6265SDimitry Andric ///
422081ad6265SDimitry Andric /// \code
422181ad6265SDimitry Andric /// #pragma omp parallel masked taskloop private(a,b) grainsize(val)
422281ad6265SDimitry Andric /// num_tasks(num)
422381ad6265SDimitry Andric /// \endcode
422481ad6265SDimitry Andric /// In this example directive '#pragma omp parallel masked taskloop' has clauses
422581ad6265SDimitry Andric /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
422681ad6265SDimitry Andric /// and 'num_tasks' with expression 'num'.
422781ad6265SDimitry Andric ///
422881ad6265SDimitry Andric class OMPParallelMaskedTaskLoopDirective final : public OMPLoopDirective {
422981ad6265SDimitry Andric   friend class ASTStmtReader;
423081ad6265SDimitry Andric   friend class OMPExecutableDirective;
423181ad6265SDimitry Andric   /// true if the construct has inner cancel directive.
423281ad6265SDimitry Andric   bool HasCancel = false;
423381ad6265SDimitry Andric 
423481ad6265SDimitry Andric   /// Build directive with the given start and end location.
423581ad6265SDimitry Andric   ///
423681ad6265SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
423781ad6265SDimitry Andric   /// \param EndLoc Ending location of the directive.
423881ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
423981ad6265SDimitry Andric   ///
OMPParallelMaskedTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)424081ad6265SDimitry Andric   OMPParallelMaskedTaskLoopDirective(SourceLocation StartLoc,
424181ad6265SDimitry Andric                                      SourceLocation EndLoc,
424281ad6265SDimitry Andric                                      unsigned CollapsedNum)
424381ad6265SDimitry Andric       : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
424481ad6265SDimitry Andric                          llvm::omp::OMPD_parallel_masked_taskloop, StartLoc,
424581ad6265SDimitry Andric                          EndLoc, CollapsedNum) {}
424681ad6265SDimitry Andric 
424781ad6265SDimitry Andric   /// Build an empty directive.
424881ad6265SDimitry Andric   ///
424981ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
425081ad6265SDimitry Andric   ///
OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum)425181ad6265SDimitry Andric   explicit OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum)
425281ad6265SDimitry Andric       : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
425381ad6265SDimitry Andric                          llvm::omp::OMPD_parallel_masked_taskloop,
425481ad6265SDimitry Andric                          SourceLocation(), SourceLocation(), CollapsedNum) {}
425581ad6265SDimitry Andric 
425681ad6265SDimitry Andric   /// Set cancel state.
setHasCancel(bool Has)425781ad6265SDimitry Andric   void setHasCancel(bool Has) { HasCancel = Has; }
425881ad6265SDimitry Andric 
425981ad6265SDimitry Andric public:
426081ad6265SDimitry Andric   /// Creates directive with a list of \a Clauses.
426181ad6265SDimitry Andric   ///
426281ad6265SDimitry Andric   /// \param C AST context.
426381ad6265SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
426481ad6265SDimitry Andric   /// \param EndLoc Ending Location of the directive.
426581ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
426681ad6265SDimitry Andric   /// \param Clauses List of clauses.
426781ad6265SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
426881ad6265SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
426981ad6265SDimitry Andric   /// \param HasCancel true if this directive has inner cancel directive.
427081ad6265SDimitry Andric   ///
427181ad6265SDimitry Andric   static OMPParallelMaskedTaskLoopDirective *
427281ad6265SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
427381ad6265SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
427481ad6265SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
427581ad6265SDimitry Andric 
427681ad6265SDimitry Andric   /// Creates an empty directive with the place
427781ad6265SDimitry Andric   /// for \a NumClauses clauses.
427881ad6265SDimitry Andric   ///
427981ad6265SDimitry Andric   /// \param C AST context.
428081ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
428181ad6265SDimitry Andric   /// \param NumClauses Number of clauses.
428281ad6265SDimitry Andric   ///
428381ad6265SDimitry Andric   static OMPParallelMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
428481ad6265SDimitry Andric                                                          unsigned NumClauses,
428581ad6265SDimitry Andric                                                          unsigned CollapsedNum,
428681ad6265SDimitry Andric                                                          EmptyShell);
428781ad6265SDimitry Andric 
428881ad6265SDimitry Andric   /// Return true if current directive has inner cancel directive.
hasCancel()428981ad6265SDimitry Andric   bool hasCancel() const { return HasCancel; }
429081ad6265SDimitry Andric 
classof(const Stmt * T)429181ad6265SDimitry Andric   static bool classof(const Stmt *T) {
429281ad6265SDimitry Andric     return T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass;
429381ad6265SDimitry Andric   }
429481ad6265SDimitry Andric };
429581ad6265SDimitry Andric 
4296480093f4SDimitry Andric /// This represents '#pragma omp parallel master taskloop simd' directive.
4297480093f4SDimitry Andric ///
4298480093f4SDimitry Andric /// \code
4299480093f4SDimitry Andric /// #pragma omp parallel master taskloop simd private(a,b) grainsize(val)
4300480093f4SDimitry Andric /// num_tasks(num)
4301480093f4SDimitry Andric /// \endcode
4302480093f4SDimitry Andric /// In this example directive '#pragma omp parallel master taskloop simd' has
4303480093f4SDimitry Andric /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
4304480093f4SDimitry Andric /// expression 'val' and 'num_tasks' with expression 'num'.
4305480093f4SDimitry Andric ///
4306480093f4SDimitry Andric class OMPParallelMasterTaskLoopSimdDirective : public OMPLoopDirective {
4307480093f4SDimitry Andric   friend class ASTStmtReader;
4308e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
4309480093f4SDimitry Andric   /// Build directive with the given start and end location.
4310480093f4SDimitry Andric   ///
4311480093f4SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
4312480093f4SDimitry Andric   /// \param EndLoc Ending location of the directive.
4313480093f4SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
4314480093f4SDimitry Andric   ///
OMPParallelMasterTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4315480093f4SDimitry Andric   OMPParallelMasterTaskLoopSimdDirective(SourceLocation StartLoc,
4316480093f4SDimitry Andric                                          SourceLocation EndLoc,
4317e8d8bef9SDimitry Andric                                          unsigned CollapsedNum)
4318e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
4319480093f4SDimitry Andric                          llvm::omp::OMPD_parallel_master_taskloop_simd,
4320e8d8bef9SDimitry Andric                          StartLoc, EndLoc, CollapsedNum) {}
4321480093f4SDimitry Andric 
4322480093f4SDimitry Andric   /// Build an empty directive.
4323480093f4SDimitry Andric   ///
4324480093f4SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
4325480093f4SDimitry Andric   ///
OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum)4326e8d8bef9SDimitry Andric   explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum)
4327e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
4328480093f4SDimitry Andric                          llvm::omp::OMPD_parallel_master_taskloop_simd,
4329e8d8bef9SDimitry Andric                          SourceLocation(), SourceLocation(), CollapsedNum) {}
4330480093f4SDimitry Andric 
4331480093f4SDimitry Andric public:
4332480093f4SDimitry Andric   /// Creates directive with a list of \p Clauses.
4333480093f4SDimitry Andric   ///
4334480093f4SDimitry Andric   /// \param C AST context.
4335480093f4SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
4336480093f4SDimitry Andric   /// \param EndLoc Ending Location of the directive.
4337480093f4SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
4338480093f4SDimitry Andric   /// \param Clauses List of clauses.
4339480093f4SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
4340480093f4SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
4341480093f4SDimitry Andric   ///
4342480093f4SDimitry Andric   static OMPParallelMasterTaskLoopSimdDirective *
4343480093f4SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4344480093f4SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4345480093f4SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
4346480093f4SDimitry Andric 
4347480093f4SDimitry Andric   /// Creates an empty directive with the place
4348480093f4SDimitry Andric   /// for \a NumClauses clauses.
4349480093f4SDimitry Andric   ///
4350480093f4SDimitry Andric   /// \param C AST context.
4351480093f4SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
4352480093f4SDimitry Andric   /// \param NumClauses Number of clauses.
4353480093f4SDimitry Andric   ///
4354480093f4SDimitry Andric   static OMPParallelMasterTaskLoopSimdDirective *
4355480093f4SDimitry Andric   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4356480093f4SDimitry Andric               EmptyShell);
4357480093f4SDimitry Andric 
classof(const Stmt * T)4358480093f4SDimitry Andric   static bool classof(const Stmt *T) {
4359480093f4SDimitry Andric     return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass;
4360480093f4SDimitry Andric   }
4361480093f4SDimitry Andric };
4362480093f4SDimitry Andric 
436381ad6265SDimitry Andric /// This represents '#pragma omp parallel masked taskloop simd' directive.
436481ad6265SDimitry Andric ///
436581ad6265SDimitry Andric /// \code
436681ad6265SDimitry Andric /// #pragma omp parallel masked taskloop simd private(a,b) grainsize(val)
436781ad6265SDimitry Andric /// num_tasks(num)
436881ad6265SDimitry Andric /// \endcode
436981ad6265SDimitry Andric /// In this example directive '#pragma omp parallel masked taskloop simd' has
437081ad6265SDimitry Andric /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
437181ad6265SDimitry Andric /// expression 'val' and 'num_tasks' with expression 'num'.
437281ad6265SDimitry Andric ///
437381ad6265SDimitry Andric class OMPParallelMaskedTaskLoopSimdDirective final : public OMPLoopDirective {
437481ad6265SDimitry Andric   friend class ASTStmtReader;
437581ad6265SDimitry Andric   friend class OMPExecutableDirective;
437681ad6265SDimitry Andric   /// Build directive with the given start and end location.
437781ad6265SDimitry Andric   ///
437881ad6265SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
437981ad6265SDimitry Andric   /// \param EndLoc Ending location of the directive.
438081ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
438181ad6265SDimitry Andric   ///
OMPParallelMaskedTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)438281ad6265SDimitry Andric   OMPParallelMaskedTaskLoopSimdDirective(SourceLocation StartLoc,
438381ad6265SDimitry Andric                                          SourceLocation EndLoc,
438481ad6265SDimitry Andric                                          unsigned CollapsedNum)
438581ad6265SDimitry Andric       : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
438681ad6265SDimitry Andric                          llvm::omp::OMPD_parallel_masked_taskloop_simd,
438781ad6265SDimitry Andric                          StartLoc, EndLoc, CollapsedNum) {}
438881ad6265SDimitry Andric 
438981ad6265SDimitry Andric   /// Build an empty directive.
439081ad6265SDimitry Andric   ///
439181ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
439281ad6265SDimitry Andric   ///
OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum)439381ad6265SDimitry Andric   explicit OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
439481ad6265SDimitry Andric       : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
439581ad6265SDimitry Andric                          llvm::omp::OMPD_parallel_masked_taskloop_simd,
439681ad6265SDimitry Andric                          SourceLocation(), SourceLocation(), CollapsedNum) {}
439781ad6265SDimitry Andric 
439881ad6265SDimitry Andric public:
439981ad6265SDimitry Andric   /// Creates directive with a list of \p Clauses.
440081ad6265SDimitry Andric   ///
440181ad6265SDimitry Andric   /// \param C AST context.
440281ad6265SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
440381ad6265SDimitry Andric   /// \param EndLoc Ending Location of the directive.
440481ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
440581ad6265SDimitry Andric   /// \param Clauses List of clauses.
440681ad6265SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
440781ad6265SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
440881ad6265SDimitry Andric   ///
440981ad6265SDimitry Andric   static OMPParallelMaskedTaskLoopSimdDirective *
441081ad6265SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
441181ad6265SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
441281ad6265SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
441381ad6265SDimitry Andric 
441481ad6265SDimitry Andric   /// Creates an empty directive with the place
441581ad6265SDimitry Andric   /// for \a NumClauses clauses.
441681ad6265SDimitry Andric   ///
441781ad6265SDimitry Andric   /// \param C AST context.
441881ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
441981ad6265SDimitry Andric   /// \param NumClauses Number of clauses.
442081ad6265SDimitry Andric   ///
442181ad6265SDimitry Andric   static OMPParallelMaskedTaskLoopSimdDirective *
442281ad6265SDimitry Andric   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
442381ad6265SDimitry Andric               EmptyShell);
442481ad6265SDimitry Andric 
classof(const Stmt * T)442581ad6265SDimitry Andric   static bool classof(const Stmt *T) {
442681ad6265SDimitry Andric     return T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass;
442781ad6265SDimitry Andric   }
442881ad6265SDimitry Andric };
442981ad6265SDimitry Andric 
44300b57cec5SDimitry Andric /// This represents '#pragma omp distribute' directive.
44310b57cec5SDimitry Andric ///
44320b57cec5SDimitry Andric /// \code
44330b57cec5SDimitry Andric /// #pragma omp distribute private(a,b)
44340b57cec5SDimitry Andric /// \endcode
44350b57cec5SDimitry Andric /// In this example directive '#pragma omp distribute' has clauses 'private'
44360b57cec5SDimitry Andric /// with the variables 'a' and 'b'
44370b57cec5SDimitry Andric ///
44380b57cec5SDimitry Andric class OMPDistributeDirective : public OMPLoopDirective {
44390b57cec5SDimitry Andric   friend class ASTStmtReader;
4440e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
44410b57cec5SDimitry Andric 
44420b57cec5SDimitry Andric   /// Build directive with the given start and end location.
44430b57cec5SDimitry Andric   ///
44440b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
44450b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
44460b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
44470b57cec5SDimitry Andric   ///
OMPDistributeDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)44480b57cec5SDimitry Andric   OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4449e8d8bef9SDimitry Andric                          unsigned CollapsedNum)
4450e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPDistributeDirectiveClass,
4451480093f4SDimitry Andric                          llvm::omp::OMPD_distribute, StartLoc, EndLoc,
4452e8d8bef9SDimitry Andric                          CollapsedNum) {}
44530b57cec5SDimitry Andric 
44540b57cec5SDimitry Andric   /// Build an empty directive.
44550b57cec5SDimitry Andric   ///
44560b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
44570b57cec5SDimitry Andric   ///
OMPDistributeDirective(unsigned CollapsedNum)4458e8d8bef9SDimitry Andric   explicit OMPDistributeDirective(unsigned CollapsedNum)
4459e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPDistributeDirectiveClass,
4460480093f4SDimitry Andric                          llvm::omp::OMPD_distribute, SourceLocation(),
4461e8d8bef9SDimitry Andric                          SourceLocation(), CollapsedNum) {}
44620b57cec5SDimitry Andric 
44630b57cec5SDimitry Andric public:
44640b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
44650b57cec5SDimitry Andric   ///
44660b57cec5SDimitry Andric   /// \param C AST context.
44670b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
44680b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
44690b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
44700b57cec5SDimitry Andric   /// \param Clauses List of clauses.
44710b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
44720b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
44730b57cec5SDimitry Andric   ///
44740b57cec5SDimitry Andric   static OMPDistributeDirective *
44750b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
44760b57cec5SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
44775f757f3fSDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs,
44785f757f3fSDimitry Andric          OpenMPDirectiveKind ParamPrevMappedDirective);
44790b57cec5SDimitry Andric 
44800b57cec5SDimitry Andric   /// Creates an empty directive with the place
44810b57cec5SDimitry Andric   /// for \a NumClauses clauses.
44820b57cec5SDimitry Andric   ///
44830b57cec5SDimitry Andric   /// \param C AST context.
44840b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
44850b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
44860b57cec5SDimitry Andric   ///
44870b57cec5SDimitry Andric   static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
44880b57cec5SDimitry Andric                                              unsigned NumClauses,
44890b57cec5SDimitry Andric                                              unsigned CollapsedNum, EmptyShell);
44900b57cec5SDimitry Andric 
classof(const Stmt * T)44910b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
44920b57cec5SDimitry Andric     return T->getStmtClass() == OMPDistributeDirectiveClass;
44930b57cec5SDimitry Andric   }
44940b57cec5SDimitry Andric };
44950b57cec5SDimitry Andric 
44960b57cec5SDimitry Andric /// This represents '#pragma omp target update' directive.
44970b57cec5SDimitry Andric ///
44980b57cec5SDimitry Andric /// \code
44990b57cec5SDimitry Andric /// #pragma omp target update to(a) from(b) device(1)
45000b57cec5SDimitry Andric /// \endcode
45010b57cec5SDimitry Andric /// In this example directive '#pragma omp target update' has clause 'to' with
45020b57cec5SDimitry Andric /// argument 'a', clause 'from' with argument 'b' and clause 'device' with
45030b57cec5SDimitry Andric /// argument '1'.
45040b57cec5SDimitry Andric ///
45050b57cec5SDimitry Andric class OMPTargetUpdateDirective : public OMPExecutableDirective {
45060b57cec5SDimitry Andric   friend class ASTStmtReader;
4507e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
45080b57cec5SDimitry Andric   /// Build directive with the given start and end location.
45090b57cec5SDimitry Andric   ///
45100b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
45110b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
45120b57cec5SDimitry Andric   ///
OMPTargetUpdateDirective(SourceLocation StartLoc,SourceLocation EndLoc)4513e8d8bef9SDimitry Andric   OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc)
4514e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
4515e8d8bef9SDimitry Andric                                llvm::omp::OMPD_target_update, StartLoc,
4516e8d8bef9SDimitry Andric                                EndLoc) {}
45170b57cec5SDimitry Andric 
45180b57cec5SDimitry Andric   /// Build an empty directive.
45190b57cec5SDimitry Andric   ///
OMPTargetUpdateDirective()4520e8d8bef9SDimitry Andric   explicit OMPTargetUpdateDirective()
4521e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
4522480093f4SDimitry Andric                                llvm::omp::OMPD_target_update, SourceLocation(),
4523e8d8bef9SDimitry Andric                                SourceLocation()) {}
45240b57cec5SDimitry Andric 
45250b57cec5SDimitry Andric public:
45260b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
45270b57cec5SDimitry Andric   ///
45280b57cec5SDimitry Andric   /// \param C AST context.
45290b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
45300b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
45310b57cec5SDimitry Andric   /// \param Clauses List of clauses.
45320b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
45330b57cec5SDimitry Andric   ///
45340b57cec5SDimitry Andric   static OMPTargetUpdateDirective *
45350b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
45360b57cec5SDimitry Andric          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
45370b57cec5SDimitry Andric 
45380b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses
45390b57cec5SDimitry Andric   /// clauses.
45400b57cec5SDimitry Andric   ///
45410b57cec5SDimitry Andric   /// \param C AST context.
45420b57cec5SDimitry Andric   /// \param NumClauses The number of clauses.
45430b57cec5SDimitry Andric   ///
45440b57cec5SDimitry Andric   static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C,
45450b57cec5SDimitry Andric                                                unsigned NumClauses, EmptyShell);
45460b57cec5SDimitry Andric 
classof(const Stmt * T)45470b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
45480b57cec5SDimitry Andric     return T->getStmtClass() == OMPTargetUpdateDirectiveClass;
45490b57cec5SDimitry Andric   }
45500b57cec5SDimitry Andric };
45510b57cec5SDimitry Andric 
45520b57cec5SDimitry Andric /// This represents '#pragma omp distribute parallel for' composite
45530b57cec5SDimitry Andric ///  directive.
45540b57cec5SDimitry Andric ///
45550b57cec5SDimitry Andric /// \code
45560b57cec5SDimitry Andric /// #pragma omp distribute parallel for private(a,b)
45570b57cec5SDimitry Andric /// \endcode
45580b57cec5SDimitry Andric /// In this example directive '#pragma omp distribute parallel for' has clause
45590b57cec5SDimitry Andric /// 'private' with the variables 'a' and 'b'
45600b57cec5SDimitry Andric ///
45610b57cec5SDimitry Andric class OMPDistributeParallelForDirective : public OMPLoopDirective {
45620b57cec5SDimitry Andric   friend class ASTStmtReader;
4563e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
45640b57cec5SDimitry Andric   /// true if the construct has inner cancel directive.
45650b57cec5SDimitry Andric   bool HasCancel = false;
45660b57cec5SDimitry Andric 
45670b57cec5SDimitry Andric   /// Build directive with the given start and end location.
45680b57cec5SDimitry Andric   ///
45690b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
45700b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
45710b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
45720b57cec5SDimitry Andric   ///
OMPDistributeParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)45730b57cec5SDimitry Andric   OMPDistributeParallelForDirective(SourceLocation StartLoc,
45740b57cec5SDimitry Andric                                     SourceLocation EndLoc,
4575e8d8bef9SDimitry Andric                                     unsigned CollapsedNum)
4576e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4577480093f4SDimitry Andric                          llvm::omp::OMPD_distribute_parallel_for, StartLoc,
4578e8d8bef9SDimitry Andric                          EndLoc, CollapsedNum) {}
45790b57cec5SDimitry Andric 
45800b57cec5SDimitry Andric   /// Build an empty directive.
45810b57cec5SDimitry Andric   ///
45820b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
45830b57cec5SDimitry Andric   ///
OMPDistributeParallelForDirective(unsigned CollapsedNum)4584e8d8bef9SDimitry Andric   explicit OMPDistributeParallelForDirective(unsigned CollapsedNum)
4585e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4586480093f4SDimitry Andric                          llvm::omp::OMPD_distribute_parallel_for,
4587e8d8bef9SDimitry Andric                          SourceLocation(), SourceLocation(), CollapsedNum) {}
45880b57cec5SDimitry Andric 
45895ffd83dbSDimitry Andric   /// Sets special task reduction descriptor.
setTaskReductionRefExpr(Expr * E)4590e8d8bef9SDimitry Andric   void setTaskReductionRefExpr(Expr *E) {
4591e8d8bef9SDimitry Andric     Data->getChildren()[numLoopChildren(
4592fe6060f1SDimitry Andric         getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E;
4593e8d8bef9SDimitry Andric   }
45945ffd83dbSDimitry Andric 
45950b57cec5SDimitry Andric   /// Set cancel state.
setHasCancel(bool Has)45960b57cec5SDimitry Andric   void setHasCancel(bool Has) { HasCancel = Has; }
45970b57cec5SDimitry Andric 
45980b57cec5SDimitry Andric public:
45990b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
46000b57cec5SDimitry Andric   ///
46010b57cec5SDimitry Andric   /// \param C AST context.
46020b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
46030b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
46040b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
46050b57cec5SDimitry Andric   /// \param Clauses List of clauses.
46060b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
46070b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
46085ffd83dbSDimitry Andric   /// \param TaskRedRef Task reduction special reference expression to handle
46095ffd83dbSDimitry Andric   /// taskgroup descriptor.
46100b57cec5SDimitry Andric   /// \param HasCancel true if this directive has inner cancel directive.
46110b57cec5SDimitry Andric   ///
46120b57cec5SDimitry Andric   static OMPDistributeParallelForDirective *
46130b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
46140b57cec5SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
46155ffd83dbSDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
46165ffd83dbSDimitry Andric          bool HasCancel);
46170b57cec5SDimitry Andric 
46180b57cec5SDimitry Andric   /// Creates an empty directive with the place
46190b57cec5SDimitry Andric   /// for \a NumClauses clauses.
46200b57cec5SDimitry Andric   ///
46210b57cec5SDimitry Andric   /// \param C AST context.
46220b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
46230b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
46240b57cec5SDimitry Andric   ///
46250b57cec5SDimitry Andric   static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C,
46260b57cec5SDimitry Andric                                                         unsigned NumClauses,
46270b57cec5SDimitry Andric                                                         unsigned CollapsedNum,
46280b57cec5SDimitry Andric                                                         EmptyShell);
46290b57cec5SDimitry Andric 
46305ffd83dbSDimitry Andric   /// Returns special task reduction reference expression.
getTaskReductionRefExpr()4631e8d8bef9SDimitry Andric   Expr *getTaskReductionRefExpr() {
4632e8d8bef9SDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
4633fe6060f1SDimitry Andric         getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]);
4634e8d8bef9SDimitry Andric   }
getTaskReductionRefExpr()4635e8d8bef9SDimitry Andric   const Expr *getTaskReductionRefExpr() const {
4636e8d8bef9SDimitry Andric     return const_cast<OMPDistributeParallelForDirective *>(this)
4637e8d8bef9SDimitry Andric         ->getTaskReductionRefExpr();
4638e8d8bef9SDimitry Andric   }
46395ffd83dbSDimitry Andric 
46400b57cec5SDimitry Andric   /// Return true if current directive has inner cancel directive.
hasCancel()46410b57cec5SDimitry Andric   bool hasCancel() const { return HasCancel; }
46420b57cec5SDimitry Andric 
classof(const Stmt * T)46430b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
46440b57cec5SDimitry Andric     return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
46450b57cec5SDimitry Andric   }
46460b57cec5SDimitry Andric };
46470b57cec5SDimitry Andric 
46480b57cec5SDimitry Andric /// This represents '#pragma omp distribute parallel for simd' composite
46490b57cec5SDimitry Andric /// directive.
46500b57cec5SDimitry Andric ///
46510b57cec5SDimitry Andric /// \code
46520b57cec5SDimitry Andric /// #pragma omp distribute parallel for simd private(x)
46530b57cec5SDimitry Andric /// \endcode
46540b57cec5SDimitry Andric /// In this example directive '#pragma omp distribute parallel for simd' has
46550b57cec5SDimitry Andric /// clause 'private' with the variables 'x'
46560b57cec5SDimitry Andric ///
46570b57cec5SDimitry Andric class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective {
46580b57cec5SDimitry Andric   friend class ASTStmtReader;
4659e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
46600b57cec5SDimitry Andric 
46610b57cec5SDimitry Andric   /// Build directive with the given start and end location.
46620b57cec5SDimitry Andric   ///
46630b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
46640b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
46650b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
46660b57cec5SDimitry Andric   ///
OMPDistributeParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)46670b57cec5SDimitry Andric   OMPDistributeParallelForSimdDirective(SourceLocation StartLoc,
46680b57cec5SDimitry Andric                                         SourceLocation EndLoc,
4669e8d8bef9SDimitry Andric                                         unsigned CollapsedNum)
4670e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4671480093f4SDimitry Andric                          llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc,
4672e8d8bef9SDimitry Andric                          EndLoc, CollapsedNum) {}
46730b57cec5SDimitry Andric 
46740b57cec5SDimitry Andric   /// Build an empty directive.
46750b57cec5SDimitry Andric   ///
46760b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
46770b57cec5SDimitry Andric   ///
OMPDistributeParallelForSimdDirective(unsigned CollapsedNum)4678e8d8bef9SDimitry Andric   explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum)
4679e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4680480093f4SDimitry Andric                          llvm::omp::OMPD_distribute_parallel_for_simd,
4681e8d8bef9SDimitry Andric                          SourceLocation(), SourceLocation(), CollapsedNum) {}
46820b57cec5SDimitry Andric 
46830b57cec5SDimitry Andric public:
46840b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
46850b57cec5SDimitry Andric   ///
46860b57cec5SDimitry Andric   /// \param C AST context.
46870b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
46880b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
46890b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
46900b57cec5SDimitry Andric   /// \param Clauses List of clauses.
46910b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
46920b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
46930b57cec5SDimitry Andric   ///
46940b57cec5SDimitry Andric   static OMPDistributeParallelForSimdDirective *Create(
46950b57cec5SDimitry Andric       const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
46960b57cec5SDimitry Andric       unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
46970b57cec5SDimitry Andric       Stmt *AssociatedStmt, const HelperExprs &Exprs);
46980b57cec5SDimitry Andric 
46990b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses clauses.
47000b57cec5SDimitry Andric   ///
47010b57cec5SDimitry Andric   /// \param C AST context.
47020b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
47030b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
47040b57cec5SDimitry Andric   ///
47050b57cec5SDimitry Andric   static OMPDistributeParallelForSimdDirective *CreateEmpty(
47060b57cec5SDimitry Andric       const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
47070b57cec5SDimitry Andric       EmptyShell);
47080b57cec5SDimitry Andric 
classof(const Stmt * T)47090b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
47100b57cec5SDimitry Andric     return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass;
47110b57cec5SDimitry Andric   }
47120b57cec5SDimitry Andric };
47130b57cec5SDimitry Andric 
47140b57cec5SDimitry Andric /// This represents '#pragma omp distribute simd' composite directive.
47150b57cec5SDimitry Andric ///
47160b57cec5SDimitry Andric /// \code
47170b57cec5SDimitry Andric /// #pragma omp distribute simd private(x)
47180b57cec5SDimitry Andric /// \endcode
47190b57cec5SDimitry Andric /// In this example directive '#pragma omp distribute simd' has clause
47200b57cec5SDimitry Andric /// 'private' with the variables 'x'
47210b57cec5SDimitry Andric ///
47220b57cec5SDimitry Andric class OMPDistributeSimdDirective final : public OMPLoopDirective {
47230b57cec5SDimitry Andric   friend class ASTStmtReader;
4724e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
47250b57cec5SDimitry Andric 
47260b57cec5SDimitry Andric   /// Build directive with the given start and end location.
47270b57cec5SDimitry Andric   ///
47280b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
47290b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
47300b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
47310b57cec5SDimitry Andric   ///
OMPDistributeSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)47320b57cec5SDimitry Andric   OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4733e8d8bef9SDimitry Andric                              unsigned CollapsedNum)
4734e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4735480093f4SDimitry Andric                          llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc,
4736e8d8bef9SDimitry Andric                          CollapsedNum) {}
47370b57cec5SDimitry Andric 
47380b57cec5SDimitry Andric   /// Build an empty directive.
47390b57cec5SDimitry Andric   ///
47400b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
47410b57cec5SDimitry Andric   ///
OMPDistributeSimdDirective(unsigned CollapsedNum)4742e8d8bef9SDimitry Andric   explicit OMPDistributeSimdDirective(unsigned CollapsedNum)
4743e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4744480093f4SDimitry Andric                          llvm::omp::OMPD_distribute_simd, SourceLocation(),
4745e8d8bef9SDimitry Andric                          SourceLocation(), CollapsedNum) {}
47460b57cec5SDimitry Andric 
47470b57cec5SDimitry Andric public:
47480b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
47490b57cec5SDimitry Andric   ///
47500b57cec5SDimitry Andric   /// \param C AST context.
47510b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
47520b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
47530b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
47540b57cec5SDimitry Andric   /// \param Clauses List of clauses.
47550b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
47560b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
47570b57cec5SDimitry Andric   ///
47580b57cec5SDimitry Andric   static OMPDistributeSimdDirective *
47590b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
47600b57cec5SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
47610b57cec5SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
47620b57cec5SDimitry Andric 
47630b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses clauses.
47640b57cec5SDimitry Andric   ///
47650b57cec5SDimitry Andric   /// \param C AST context.
47660b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
47670b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
47680b57cec5SDimitry Andric   ///
47690b57cec5SDimitry Andric   static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C,
47700b57cec5SDimitry Andric                                                  unsigned NumClauses,
47710b57cec5SDimitry Andric                                                  unsigned CollapsedNum,
47720b57cec5SDimitry Andric                                                  EmptyShell);
47730b57cec5SDimitry Andric 
classof(const Stmt * T)47740b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
47750b57cec5SDimitry Andric     return T->getStmtClass() == OMPDistributeSimdDirectiveClass;
47760b57cec5SDimitry Andric   }
47770b57cec5SDimitry Andric };
47780b57cec5SDimitry Andric 
47790b57cec5SDimitry Andric /// This represents '#pragma omp target parallel for simd' directive.
47800b57cec5SDimitry Andric ///
47810b57cec5SDimitry Andric /// \code
47820b57cec5SDimitry Andric /// #pragma omp target parallel for simd private(a) map(b) safelen(c)
47830b57cec5SDimitry Andric /// \endcode
47840b57cec5SDimitry Andric /// In this example directive '#pragma omp target parallel for simd' has clauses
47850b57cec5SDimitry Andric /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen'
47860b57cec5SDimitry Andric /// with the variable 'c'.
47870b57cec5SDimitry Andric ///
47880b57cec5SDimitry Andric class OMPTargetParallelForSimdDirective final : public OMPLoopDirective {
47890b57cec5SDimitry Andric   friend class ASTStmtReader;
4790e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
47910b57cec5SDimitry Andric 
47920b57cec5SDimitry Andric   /// Build directive with the given start and end location.
47930b57cec5SDimitry Andric   ///
47940b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
47950b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
47960b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
47970b57cec5SDimitry Andric   ///
OMPTargetParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)4798480093f4SDimitry Andric   OMPTargetParallelForSimdDirective(SourceLocation StartLoc,
4799480093f4SDimitry Andric                                     SourceLocation EndLoc,
4800e8d8bef9SDimitry Andric                                     unsigned CollapsedNum)
4801e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4802480093f4SDimitry Andric                          llvm::omp::OMPD_target_parallel_for_simd, StartLoc,
4803e8d8bef9SDimitry Andric                          EndLoc, CollapsedNum) {}
48040b57cec5SDimitry Andric 
48050b57cec5SDimitry Andric   /// Build an empty directive.
48060b57cec5SDimitry Andric   ///
48070b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
48080b57cec5SDimitry Andric   ///
OMPTargetParallelForSimdDirective(unsigned CollapsedNum)4809e8d8bef9SDimitry Andric   explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum)
4810e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4811480093f4SDimitry Andric                          llvm::omp::OMPD_target_parallel_for_simd,
4812e8d8bef9SDimitry Andric                          SourceLocation(), SourceLocation(), CollapsedNum) {}
48130b57cec5SDimitry Andric 
48140b57cec5SDimitry Andric public:
48150b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
48160b57cec5SDimitry Andric   ///
48170b57cec5SDimitry Andric   /// \param C AST context.
48180b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
48190b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
48200b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
48210b57cec5SDimitry Andric   /// \param Clauses List of clauses.
48220b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
48230b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
48240b57cec5SDimitry Andric   ///
48250b57cec5SDimitry Andric   static OMPTargetParallelForSimdDirective *
48260b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
48270b57cec5SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
48280b57cec5SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
48290b57cec5SDimitry Andric 
48300b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses clauses.
48310b57cec5SDimitry Andric   ///
48320b57cec5SDimitry Andric   /// \param C AST context.
48330b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
48340b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
48350b57cec5SDimitry Andric   ///
48360b57cec5SDimitry Andric   static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C,
48370b57cec5SDimitry Andric                                                         unsigned NumClauses,
48380b57cec5SDimitry Andric                                                         unsigned CollapsedNum,
48390b57cec5SDimitry Andric                                                         EmptyShell);
48400b57cec5SDimitry Andric 
classof(const Stmt * T)48410b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
48420b57cec5SDimitry Andric     return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
48430b57cec5SDimitry Andric   }
48440b57cec5SDimitry Andric };
48450b57cec5SDimitry Andric 
48460b57cec5SDimitry Andric /// This represents '#pragma omp target simd' directive.
48470b57cec5SDimitry Andric ///
48480b57cec5SDimitry Andric /// \code
48490b57cec5SDimitry Andric /// #pragma omp target simd private(a) map(b) safelen(c)
48500b57cec5SDimitry Andric /// \endcode
48510b57cec5SDimitry Andric /// In this example directive '#pragma omp target simd' has clauses 'private'
48520b57cec5SDimitry Andric /// with the variable 'a', 'map' with the variable 'b' and 'safelen' with
48530b57cec5SDimitry Andric /// the variable 'c'.
48540b57cec5SDimitry Andric ///
48550b57cec5SDimitry Andric class OMPTargetSimdDirective final : public OMPLoopDirective {
48560b57cec5SDimitry Andric   friend class ASTStmtReader;
4857e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
48580b57cec5SDimitry Andric 
48590b57cec5SDimitry Andric   /// Build directive with the given start and end location.
48600b57cec5SDimitry Andric   ///
48610b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
48620b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
48630b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
48640b57cec5SDimitry Andric   ///
OMPTargetSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)48650b57cec5SDimitry Andric   OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4866e8d8bef9SDimitry Andric                          unsigned CollapsedNum)
4867e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTargetSimdDirectiveClass,
4868480093f4SDimitry Andric                          llvm::omp::OMPD_target_simd, StartLoc, EndLoc,
4869e8d8bef9SDimitry Andric                          CollapsedNum) {}
48700b57cec5SDimitry Andric 
48710b57cec5SDimitry Andric   /// Build an empty directive.
48720b57cec5SDimitry Andric   ///
48730b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
48740b57cec5SDimitry Andric   ///
OMPTargetSimdDirective(unsigned CollapsedNum)4875e8d8bef9SDimitry Andric   explicit OMPTargetSimdDirective(unsigned CollapsedNum)
4876e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTargetSimdDirectiveClass,
4877480093f4SDimitry Andric                          llvm::omp::OMPD_target_simd, SourceLocation(),
4878e8d8bef9SDimitry Andric                          SourceLocation(), CollapsedNum) {}
48790b57cec5SDimitry Andric 
48800b57cec5SDimitry Andric public:
48810b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
48820b57cec5SDimitry Andric   ///
48830b57cec5SDimitry Andric   /// \param C AST context.
48840b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
48850b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
48860b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
48870b57cec5SDimitry Andric   /// \param Clauses List of clauses.
48880b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
48890b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
48900b57cec5SDimitry Andric   ///
48910b57cec5SDimitry Andric   static OMPTargetSimdDirective *
48920b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
48930b57cec5SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
48940b57cec5SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
48950b57cec5SDimitry Andric 
48960b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses clauses.
48970b57cec5SDimitry Andric   ///
48980b57cec5SDimitry Andric   /// \param C AST context.
48990b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
49000b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
49010b57cec5SDimitry Andric   ///
49020b57cec5SDimitry Andric   static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C,
49030b57cec5SDimitry Andric                                              unsigned NumClauses,
49040b57cec5SDimitry Andric                                              unsigned CollapsedNum,
49050b57cec5SDimitry Andric                                              EmptyShell);
49060b57cec5SDimitry Andric 
classof(const Stmt * T)49070b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
49080b57cec5SDimitry Andric     return T->getStmtClass() == OMPTargetSimdDirectiveClass;
49090b57cec5SDimitry Andric   }
49100b57cec5SDimitry Andric };
49110b57cec5SDimitry Andric 
49120b57cec5SDimitry Andric /// This represents '#pragma omp teams distribute' directive.
49130b57cec5SDimitry Andric ///
49140b57cec5SDimitry Andric /// \code
49150b57cec5SDimitry Andric /// #pragma omp teams distribute private(a,b)
49160b57cec5SDimitry Andric /// \endcode
49170b57cec5SDimitry Andric /// In this example directive '#pragma omp teams distribute' has clauses
49180b57cec5SDimitry Andric /// 'private' with the variables 'a' and 'b'
49190b57cec5SDimitry Andric ///
49200b57cec5SDimitry Andric class OMPTeamsDistributeDirective final : public OMPLoopDirective {
49210b57cec5SDimitry Andric   friend class ASTStmtReader;
4922e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
49230b57cec5SDimitry Andric 
49240b57cec5SDimitry Andric   /// Build directive with the given start and end location.
49250b57cec5SDimitry Andric   ///
49260b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
49270b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
49280b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
49290b57cec5SDimitry Andric   ///
OMPTeamsDistributeDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)49300b57cec5SDimitry Andric   OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4931e8d8bef9SDimitry Andric                               unsigned CollapsedNum)
4932e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTeamsDistributeDirectiveClass,
4933480093f4SDimitry Andric                          llvm::omp::OMPD_teams_distribute, StartLoc, EndLoc,
4934e8d8bef9SDimitry Andric                          CollapsedNum) {}
49350b57cec5SDimitry Andric 
49360b57cec5SDimitry Andric   /// Build an empty directive.
49370b57cec5SDimitry Andric   ///
49380b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
49390b57cec5SDimitry Andric   ///
OMPTeamsDistributeDirective(unsigned CollapsedNum)4940e8d8bef9SDimitry Andric   explicit OMPTeamsDistributeDirective(unsigned CollapsedNum)
4941e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTeamsDistributeDirectiveClass,
4942480093f4SDimitry Andric                          llvm::omp::OMPD_teams_distribute, SourceLocation(),
4943e8d8bef9SDimitry Andric                          SourceLocation(), CollapsedNum) {}
49440b57cec5SDimitry Andric 
49450b57cec5SDimitry Andric public:
49460b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
49470b57cec5SDimitry Andric   ///
49480b57cec5SDimitry Andric   /// \param C AST context.
49490b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
49500b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
49510b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
49520b57cec5SDimitry Andric   /// \param Clauses List of clauses.
49530b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
49540b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
49550b57cec5SDimitry Andric   ///
49560b57cec5SDimitry Andric   static OMPTeamsDistributeDirective *
49570b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
49580b57cec5SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
49590b57cec5SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
49600b57cec5SDimitry Andric 
49610b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses clauses.
49620b57cec5SDimitry Andric   ///
49630b57cec5SDimitry Andric   /// \param C AST context.
49640b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
49650b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
49660b57cec5SDimitry Andric   ///
49670b57cec5SDimitry Andric   static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C,
49680b57cec5SDimitry Andric                                                   unsigned NumClauses,
49690b57cec5SDimitry Andric                                                   unsigned CollapsedNum,
49700b57cec5SDimitry Andric                                                   EmptyShell);
49710b57cec5SDimitry Andric 
classof(const Stmt * T)49720b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
49730b57cec5SDimitry Andric     return T->getStmtClass() == OMPTeamsDistributeDirectiveClass;
49740b57cec5SDimitry Andric   }
49750b57cec5SDimitry Andric };
49760b57cec5SDimitry Andric 
49770b57cec5SDimitry Andric /// This represents '#pragma omp teams distribute simd'
49780b57cec5SDimitry Andric /// combined directive.
49790b57cec5SDimitry Andric ///
49800b57cec5SDimitry Andric /// \code
49810b57cec5SDimitry Andric /// #pragma omp teams distribute simd private(a,b)
49820b57cec5SDimitry Andric /// \endcode
49830b57cec5SDimitry Andric /// In this example directive '#pragma omp teams distribute simd'
49840b57cec5SDimitry Andric /// has clause 'private' with the variables 'a' and 'b'
49850b57cec5SDimitry Andric ///
49860b57cec5SDimitry Andric class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective {
49870b57cec5SDimitry Andric   friend class ASTStmtReader;
4988e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
49890b57cec5SDimitry Andric 
49900b57cec5SDimitry Andric   /// Build directive with the given start and end location.
49910b57cec5SDimitry Andric   ///
49920b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
49930b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
49940b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
49950b57cec5SDimitry Andric   ///
OMPTeamsDistributeSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)49960b57cec5SDimitry Andric   OMPTeamsDistributeSimdDirective(SourceLocation StartLoc,
4997e8d8bef9SDimitry Andric                                   SourceLocation EndLoc, unsigned CollapsedNum)
4998e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass,
4999480093f4SDimitry Andric                          llvm::omp::OMPD_teams_distribute_simd, StartLoc,
5000e8d8bef9SDimitry Andric                          EndLoc, CollapsedNum) {}
50010b57cec5SDimitry Andric 
50020b57cec5SDimitry Andric   /// Build an empty directive.
50030b57cec5SDimitry Andric   ///
50040b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
50050b57cec5SDimitry Andric   ///
OMPTeamsDistributeSimdDirective(unsigned CollapsedNum)5006e8d8bef9SDimitry Andric   explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum)
5007e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass,
5008480093f4SDimitry Andric                          llvm::omp::OMPD_teams_distribute_simd,
5009e8d8bef9SDimitry Andric                          SourceLocation(), SourceLocation(), CollapsedNum) {}
50100b57cec5SDimitry Andric 
50110b57cec5SDimitry Andric public:
50120b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
50130b57cec5SDimitry Andric   ///
50140b57cec5SDimitry Andric   /// \param C AST context.
50150b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
50160b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
50170b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
50180b57cec5SDimitry Andric   /// \param Clauses List of clauses.
50190b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
50200b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
50210b57cec5SDimitry Andric   ///
50220b57cec5SDimitry Andric   static OMPTeamsDistributeSimdDirective *
50230b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
50240b57cec5SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
50250b57cec5SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
50260b57cec5SDimitry Andric 
50270b57cec5SDimitry Andric   /// Creates an empty directive with the place
50280b57cec5SDimitry Andric   /// for \a NumClauses clauses.
50290b57cec5SDimitry Andric   ///
50300b57cec5SDimitry Andric   /// \param C AST context.
50310b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
50320b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
50330b57cec5SDimitry Andric   ///
50340b57cec5SDimitry Andric   static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C,
50350b57cec5SDimitry Andric                                                       unsigned NumClauses,
50360b57cec5SDimitry Andric                                                       unsigned CollapsedNum,
50370b57cec5SDimitry Andric                                                       EmptyShell);
50380b57cec5SDimitry Andric 
classof(const Stmt * T)50390b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
50400b57cec5SDimitry Andric     return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass;
50410b57cec5SDimitry Andric   }
50420b57cec5SDimitry Andric };
50430b57cec5SDimitry Andric 
50440b57cec5SDimitry Andric /// This represents '#pragma omp teams distribute parallel for simd' composite
50450b57cec5SDimitry Andric /// directive.
50460b57cec5SDimitry Andric ///
50470b57cec5SDimitry Andric /// \code
50480b57cec5SDimitry Andric /// #pragma omp teams distribute parallel for simd private(x)
50490b57cec5SDimitry Andric /// \endcode
50500b57cec5SDimitry Andric /// In this example directive '#pragma omp teams distribute parallel for simd'
50510b57cec5SDimitry Andric /// has clause 'private' with the variables 'x'
50520b57cec5SDimitry Andric ///
50530b57cec5SDimitry Andric class OMPTeamsDistributeParallelForSimdDirective final
50540b57cec5SDimitry Andric     : public OMPLoopDirective {
50550b57cec5SDimitry Andric   friend class ASTStmtReader;
5056e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
50570b57cec5SDimitry Andric 
50580b57cec5SDimitry Andric   /// Build directive with the given start and end location.
50590b57cec5SDimitry Andric   ///
50600b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
50610b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
50620b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
50630b57cec5SDimitry Andric   ///
OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)50640b57cec5SDimitry Andric   OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
50650b57cec5SDimitry Andric                                              SourceLocation EndLoc,
5066e8d8bef9SDimitry Andric                                              unsigned CollapsedNum)
5067e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass,
5068480093f4SDimitry Andric                          llvm::omp::OMPD_teams_distribute_parallel_for_simd,
5069e8d8bef9SDimitry Andric                          StartLoc, EndLoc, CollapsedNum) {}
50700b57cec5SDimitry Andric 
50710b57cec5SDimitry Andric   /// Build an empty directive.
50720b57cec5SDimitry Andric   ///
50730b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
50740b57cec5SDimitry Andric   ///
OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum)5075e8d8bef9SDimitry Andric   explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum)
5076e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass,
5077480093f4SDimitry Andric                          llvm::omp::OMPD_teams_distribute_parallel_for_simd,
5078e8d8bef9SDimitry Andric                          SourceLocation(), SourceLocation(), CollapsedNum) {}
50790b57cec5SDimitry Andric 
50800b57cec5SDimitry Andric public:
50810b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
50820b57cec5SDimitry Andric   ///
50830b57cec5SDimitry Andric   /// \param C AST context.
50840b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
50850b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
50860b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
50870b57cec5SDimitry Andric   /// \param Clauses List of clauses.
50880b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
50890b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
50900b57cec5SDimitry Andric   ///
50910b57cec5SDimitry Andric   static OMPTeamsDistributeParallelForSimdDirective *
50920b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
50930b57cec5SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
50940b57cec5SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
50950b57cec5SDimitry Andric 
50960b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses clauses.
50970b57cec5SDimitry Andric   ///
50980b57cec5SDimitry Andric   /// \param C AST context.
50990b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
51000b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
51010b57cec5SDimitry Andric   ///
51020b57cec5SDimitry Andric   static OMPTeamsDistributeParallelForSimdDirective *
51030b57cec5SDimitry Andric   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
51040b57cec5SDimitry Andric               EmptyShell);
51050b57cec5SDimitry Andric 
classof(const Stmt * T)51060b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
51070b57cec5SDimitry Andric     return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass;
51080b57cec5SDimitry Andric   }
51090b57cec5SDimitry Andric };
51100b57cec5SDimitry Andric 
51110b57cec5SDimitry Andric /// This represents '#pragma omp teams distribute parallel for' composite
51120b57cec5SDimitry Andric /// directive.
51130b57cec5SDimitry Andric ///
51140b57cec5SDimitry Andric /// \code
51150b57cec5SDimitry Andric /// #pragma omp teams distribute parallel for private(x)
51160b57cec5SDimitry Andric /// \endcode
51170b57cec5SDimitry Andric /// In this example directive '#pragma omp teams distribute parallel for'
51180b57cec5SDimitry Andric /// has clause 'private' with the variables 'x'
51190b57cec5SDimitry Andric ///
51200b57cec5SDimitry Andric class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
51210b57cec5SDimitry Andric   friend class ASTStmtReader;
5122e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
51230b57cec5SDimitry Andric   /// true if the construct has inner cancel directive.
51240b57cec5SDimitry Andric   bool HasCancel = false;
51250b57cec5SDimitry Andric 
51260b57cec5SDimitry Andric   /// Build directive with the given start and end location.
51270b57cec5SDimitry Andric   ///
51280b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
51290b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
51300b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
51310b57cec5SDimitry Andric   ///
OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)51320b57cec5SDimitry Andric   OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc,
51330b57cec5SDimitry Andric                                          SourceLocation EndLoc,
5134e8d8bef9SDimitry Andric                                          unsigned CollapsedNum)
5135e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass,
5136480093f4SDimitry Andric                          llvm::omp::OMPD_teams_distribute_parallel_for,
5137e8d8bef9SDimitry Andric                          StartLoc, EndLoc, CollapsedNum) {}
51380b57cec5SDimitry Andric 
51390b57cec5SDimitry Andric   /// Build an empty directive.
51400b57cec5SDimitry Andric   ///
51410b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
51420b57cec5SDimitry Andric   ///
OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum)5143e8d8bef9SDimitry Andric   explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum)
5144e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass,
5145480093f4SDimitry Andric                          llvm::omp::OMPD_teams_distribute_parallel_for,
5146e8d8bef9SDimitry Andric                          SourceLocation(), SourceLocation(), CollapsedNum) {}
51470b57cec5SDimitry Andric 
51485ffd83dbSDimitry Andric   /// Sets special task reduction descriptor.
setTaskReductionRefExpr(Expr * E)5149e8d8bef9SDimitry Andric   void setTaskReductionRefExpr(Expr *E) {
5150e8d8bef9SDimitry Andric     Data->getChildren()[numLoopChildren(
5151fe6060f1SDimitry Andric         getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)] = E;
5152e8d8bef9SDimitry Andric   }
51535ffd83dbSDimitry Andric 
51540b57cec5SDimitry Andric   /// Set cancel state.
setHasCancel(bool Has)51550b57cec5SDimitry Andric   void setHasCancel(bool Has) { HasCancel = Has; }
51560b57cec5SDimitry Andric 
51570b57cec5SDimitry Andric public:
51580b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
51590b57cec5SDimitry Andric   ///
51600b57cec5SDimitry Andric   /// \param C AST context.
51610b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
51620b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
51630b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
51640b57cec5SDimitry Andric   /// \param Clauses List of clauses.
51650b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
51660b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
51675ffd83dbSDimitry Andric   /// \param TaskRedRef Task reduction special reference expression to handle
51685ffd83dbSDimitry Andric   /// taskgroup descriptor.
51690b57cec5SDimitry Andric   /// \param HasCancel true if this directive has inner cancel directive.
51700b57cec5SDimitry Andric   ///
51710b57cec5SDimitry Andric   static OMPTeamsDistributeParallelForDirective *
51720b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
51730b57cec5SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
51745ffd83dbSDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
51755ffd83dbSDimitry Andric          bool HasCancel);
51760b57cec5SDimitry Andric 
51770b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses clauses.
51780b57cec5SDimitry Andric   ///
51790b57cec5SDimitry Andric   /// \param C AST context.
51800b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
51810b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
51820b57cec5SDimitry Andric   ///
51830b57cec5SDimitry Andric   static OMPTeamsDistributeParallelForDirective *
51840b57cec5SDimitry Andric   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
51850b57cec5SDimitry Andric               EmptyShell);
51860b57cec5SDimitry Andric 
51875ffd83dbSDimitry Andric   /// Returns special task reduction reference expression.
getTaskReductionRefExpr()5188e8d8bef9SDimitry Andric   Expr *getTaskReductionRefExpr() {
5189e8d8bef9SDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
5190fe6060f1SDimitry Andric         getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)]);
5191e8d8bef9SDimitry Andric   }
getTaskReductionRefExpr()5192e8d8bef9SDimitry Andric   const Expr *getTaskReductionRefExpr() const {
5193e8d8bef9SDimitry Andric     return const_cast<OMPTeamsDistributeParallelForDirective *>(this)
5194e8d8bef9SDimitry Andric         ->getTaskReductionRefExpr();
5195e8d8bef9SDimitry Andric   }
51965ffd83dbSDimitry Andric 
51970b57cec5SDimitry Andric   /// Return true if current directive has inner cancel directive.
hasCancel()51980b57cec5SDimitry Andric   bool hasCancel() const { return HasCancel; }
51990b57cec5SDimitry Andric 
classof(const Stmt * T)52000b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
52010b57cec5SDimitry Andric     return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass;
52020b57cec5SDimitry Andric   }
52030b57cec5SDimitry Andric };
52040b57cec5SDimitry Andric 
52050b57cec5SDimitry Andric /// This represents '#pragma omp target teams' directive.
52060b57cec5SDimitry Andric ///
52070b57cec5SDimitry Andric /// \code
52080b57cec5SDimitry Andric /// #pragma omp target teams if(a>0)
52090b57cec5SDimitry Andric /// \endcode
52100b57cec5SDimitry Andric /// In this example directive '#pragma omp target teams' has clause 'if' with
52110b57cec5SDimitry Andric /// condition 'a>0'.
52120b57cec5SDimitry Andric ///
52130b57cec5SDimitry Andric class OMPTargetTeamsDirective final : public OMPExecutableDirective {
52140b57cec5SDimitry Andric   friend class ASTStmtReader;
5215e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
52160b57cec5SDimitry Andric   /// Build directive with the given start and end location.
52170b57cec5SDimitry Andric   ///
52180b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
52190b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
52200b57cec5SDimitry Andric   ///
OMPTargetTeamsDirective(SourceLocation StartLoc,SourceLocation EndLoc)5221e8d8bef9SDimitry Andric   OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5222e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTargetTeamsDirectiveClass,
5223e8d8bef9SDimitry Andric                                llvm::omp::OMPD_target_teams, StartLoc, EndLoc) {
5224e8d8bef9SDimitry Andric   }
52250b57cec5SDimitry Andric 
52260b57cec5SDimitry Andric   /// Build an empty directive.
52270b57cec5SDimitry Andric   ///
OMPTargetTeamsDirective()5228e8d8bef9SDimitry Andric   explicit OMPTargetTeamsDirective()
5229e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPTargetTeamsDirectiveClass,
5230480093f4SDimitry Andric                                llvm::omp::OMPD_target_teams, SourceLocation(),
5231e8d8bef9SDimitry Andric                                SourceLocation()) {}
52320b57cec5SDimitry Andric 
52330b57cec5SDimitry Andric public:
52340b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
52350b57cec5SDimitry Andric   ///
52360b57cec5SDimitry Andric   /// \param C AST context.
52370b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
52380b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
52390b57cec5SDimitry Andric   /// \param Clauses List of clauses.
52400b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
52410b57cec5SDimitry Andric   ///
52420b57cec5SDimitry Andric   static OMPTargetTeamsDirective *Create(const ASTContext &C,
52430b57cec5SDimitry Andric                                          SourceLocation StartLoc,
52440b57cec5SDimitry Andric                                          SourceLocation EndLoc,
52450b57cec5SDimitry Andric                                          ArrayRef<OMPClause *> Clauses,
52460b57cec5SDimitry Andric                                          Stmt *AssociatedStmt);
52470b57cec5SDimitry Andric 
52480b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses clauses.
52490b57cec5SDimitry Andric   ///
52500b57cec5SDimitry Andric   /// \param C AST context.
52510b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
52520b57cec5SDimitry Andric   ///
52530b57cec5SDimitry Andric   static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C,
52540b57cec5SDimitry Andric                                               unsigned NumClauses, EmptyShell);
52550b57cec5SDimitry Andric 
classof(const Stmt * T)52560b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
52570b57cec5SDimitry Andric     return T->getStmtClass() == OMPTargetTeamsDirectiveClass;
52580b57cec5SDimitry Andric   }
52590b57cec5SDimitry Andric };
52600b57cec5SDimitry Andric 
52610b57cec5SDimitry Andric /// This represents '#pragma omp target teams distribute' combined directive.
52620b57cec5SDimitry Andric ///
52630b57cec5SDimitry Andric /// \code
52640b57cec5SDimitry Andric /// #pragma omp target teams distribute private(x)
52650b57cec5SDimitry Andric /// \endcode
52660b57cec5SDimitry Andric /// In this example directive '#pragma omp target teams distribute' has clause
52670b57cec5SDimitry Andric /// 'private' with the variables 'x'
52680b57cec5SDimitry Andric ///
52690b57cec5SDimitry Andric class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective {
52700b57cec5SDimitry Andric   friend class ASTStmtReader;
5271e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
52720b57cec5SDimitry Andric 
52730b57cec5SDimitry Andric   /// Build directive with the given start and end location.
52740b57cec5SDimitry Andric   ///
52750b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
52760b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
52770b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
52780b57cec5SDimitry Andric   ///
OMPTargetTeamsDistributeDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)52790b57cec5SDimitry Andric   OMPTargetTeamsDistributeDirective(SourceLocation StartLoc,
52800b57cec5SDimitry Andric                                     SourceLocation EndLoc,
5281e8d8bef9SDimitry Andric                                     unsigned CollapsedNum)
5282e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass,
5283480093f4SDimitry Andric                          llvm::omp::OMPD_target_teams_distribute, StartLoc,
5284e8d8bef9SDimitry Andric                          EndLoc, CollapsedNum) {}
52850b57cec5SDimitry Andric 
52860b57cec5SDimitry Andric   /// Build an empty directive.
52870b57cec5SDimitry Andric   ///
52880b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
52890b57cec5SDimitry Andric   ///
OMPTargetTeamsDistributeDirective(unsigned CollapsedNum)5290e8d8bef9SDimitry Andric   explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum)
5291e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass,
5292480093f4SDimitry Andric                          llvm::omp::OMPD_target_teams_distribute,
5293e8d8bef9SDimitry Andric                          SourceLocation(), SourceLocation(), CollapsedNum) {}
52940b57cec5SDimitry Andric 
52950b57cec5SDimitry Andric public:
52960b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
52970b57cec5SDimitry Andric   ///
52980b57cec5SDimitry Andric   /// \param C AST context.
52990b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
53000b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
53010b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
53020b57cec5SDimitry Andric   /// \param Clauses List of clauses.
53030b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
53040b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
53050b57cec5SDimitry Andric   ///
53060b57cec5SDimitry Andric   static OMPTargetTeamsDistributeDirective *
53070b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
53080b57cec5SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
53090b57cec5SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
53100b57cec5SDimitry Andric 
53110b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses clauses.
53120b57cec5SDimitry Andric   ///
53130b57cec5SDimitry Andric   /// \param C AST context.
53140b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
53150b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
53160b57cec5SDimitry Andric   ///
53170b57cec5SDimitry Andric   static OMPTargetTeamsDistributeDirective *
53180b57cec5SDimitry Andric   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
53190b57cec5SDimitry Andric               EmptyShell);
53200b57cec5SDimitry Andric 
classof(const Stmt * T)53210b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
53220b57cec5SDimitry Andric     return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass;
53230b57cec5SDimitry Andric   }
53240b57cec5SDimitry Andric };
53250b57cec5SDimitry Andric 
53260b57cec5SDimitry Andric /// This represents '#pragma omp target teams distribute parallel for' combined
53270b57cec5SDimitry Andric /// directive.
53280b57cec5SDimitry Andric ///
53290b57cec5SDimitry Andric /// \code
53300b57cec5SDimitry Andric /// #pragma omp target teams distribute parallel for private(x)
53310b57cec5SDimitry Andric /// \endcode
53320b57cec5SDimitry Andric /// In this example directive '#pragma omp target teams distribute parallel
53330b57cec5SDimitry Andric /// for' has clause 'private' with the variables 'x'
53340b57cec5SDimitry Andric ///
53350b57cec5SDimitry Andric class OMPTargetTeamsDistributeParallelForDirective final
53360b57cec5SDimitry Andric     : public OMPLoopDirective {
53370b57cec5SDimitry Andric   friend class ASTStmtReader;
5338e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
53390b57cec5SDimitry Andric   /// true if the construct has inner cancel directive.
53400b57cec5SDimitry Andric   bool HasCancel = false;
53410b57cec5SDimitry Andric 
53420b57cec5SDimitry Andric   /// Build directive with the given start and end location.
53430b57cec5SDimitry Andric   ///
53440b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
53450b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
53460b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
53470b57cec5SDimitry Andric   ///
OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)53480b57cec5SDimitry Andric   OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc,
53490b57cec5SDimitry Andric                                                SourceLocation EndLoc,
5350e8d8bef9SDimitry Andric                                                unsigned CollapsedNum)
5351e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass,
5352480093f4SDimitry Andric                          llvm::omp::OMPD_target_teams_distribute_parallel_for,
5353e8d8bef9SDimitry Andric                          StartLoc, EndLoc, CollapsedNum) {}
53540b57cec5SDimitry Andric 
53550b57cec5SDimitry Andric   /// Build an empty directive.
53560b57cec5SDimitry Andric   ///
53570b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
53580b57cec5SDimitry Andric   ///
OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum)5359e8d8bef9SDimitry Andric   explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum)
5360e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass,
5361480093f4SDimitry Andric                          llvm::omp::OMPD_target_teams_distribute_parallel_for,
5362e8d8bef9SDimitry Andric                          SourceLocation(), SourceLocation(), CollapsedNum) {}
53630b57cec5SDimitry Andric 
53645ffd83dbSDimitry Andric   /// Sets special task reduction descriptor.
setTaskReductionRefExpr(Expr * E)5365e8d8bef9SDimitry Andric   void setTaskReductionRefExpr(Expr *E) {
5366e8d8bef9SDimitry Andric     Data->getChildren()[numLoopChildren(
5367fe6060f1SDimitry Andric         getLoopsNumber(),
5368e8d8bef9SDimitry Andric         llvm::omp::OMPD_target_teams_distribute_parallel_for)] = E;
5369e8d8bef9SDimitry Andric   }
53705ffd83dbSDimitry Andric 
53710b57cec5SDimitry Andric   /// Set cancel state.
setHasCancel(bool Has)53720b57cec5SDimitry Andric   void setHasCancel(bool Has) { HasCancel = Has; }
53730b57cec5SDimitry Andric 
53740b57cec5SDimitry Andric public:
53750b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
53760b57cec5SDimitry Andric   ///
53770b57cec5SDimitry Andric   /// \param C AST context.
53780b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
53790b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
53800b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
53810b57cec5SDimitry Andric   /// \param Clauses List of clauses.
53820b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
53830b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
53845ffd83dbSDimitry Andric   /// \param TaskRedRef Task reduction special reference expression to handle
53855ffd83dbSDimitry Andric   /// taskgroup descriptor.
53860b57cec5SDimitry Andric   /// \param HasCancel true if this directive has inner cancel directive.
53870b57cec5SDimitry Andric   ///
53880b57cec5SDimitry Andric   static OMPTargetTeamsDistributeParallelForDirective *
53890b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
53900b57cec5SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
53915ffd83dbSDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
53925ffd83dbSDimitry Andric          bool HasCancel);
53930b57cec5SDimitry Andric 
53940b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses clauses.
53950b57cec5SDimitry Andric   ///
53960b57cec5SDimitry Andric   /// \param C AST context.
53970b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
53980b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
53990b57cec5SDimitry Andric   ///
54000b57cec5SDimitry Andric   static OMPTargetTeamsDistributeParallelForDirective *
54010b57cec5SDimitry Andric   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
54020b57cec5SDimitry Andric               EmptyShell);
54030b57cec5SDimitry Andric 
54045ffd83dbSDimitry Andric   /// Returns special task reduction reference expression.
getTaskReductionRefExpr()5405e8d8bef9SDimitry Andric   Expr *getTaskReductionRefExpr() {
5406e8d8bef9SDimitry Andric     return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
5407fe6060f1SDimitry Andric         getLoopsNumber(),
5408e8d8bef9SDimitry Andric         llvm::omp::OMPD_target_teams_distribute_parallel_for)]);
5409e8d8bef9SDimitry Andric   }
getTaskReductionRefExpr()5410e8d8bef9SDimitry Andric   const Expr *getTaskReductionRefExpr() const {
5411e8d8bef9SDimitry Andric     return const_cast<OMPTargetTeamsDistributeParallelForDirective *>(this)
5412e8d8bef9SDimitry Andric         ->getTaskReductionRefExpr();
5413e8d8bef9SDimitry Andric   }
54145ffd83dbSDimitry Andric 
54150b57cec5SDimitry Andric   /// Return true if current directive has inner cancel directive.
hasCancel()54160b57cec5SDimitry Andric   bool hasCancel() const { return HasCancel; }
54170b57cec5SDimitry Andric 
classof(const Stmt * T)54180b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
54190b57cec5SDimitry Andric     return T->getStmtClass() ==
54200b57cec5SDimitry Andric            OMPTargetTeamsDistributeParallelForDirectiveClass;
54210b57cec5SDimitry Andric   }
54220b57cec5SDimitry Andric };
54230b57cec5SDimitry Andric 
54240b57cec5SDimitry Andric /// This represents '#pragma omp target teams distribute parallel for simd'
54250b57cec5SDimitry Andric /// combined directive.
54260b57cec5SDimitry Andric ///
54270b57cec5SDimitry Andric /// \code
54280b57cec5SDimitry Andric /// #pragma omp target teams distribute parallel for simd private(x)
54290b57cec5SDimitry Andric /// \endcode
54300b57cec5SDimitry Andric /// In this example directive '#pragma omp target teams distribute parallel
54310b57cec5SDimitry Andric /// for simd' has clause 'private' with the variables 'x'
54320b57cec5SDimitry Andric ///
54330b57cec5SDimitry Andric class OMPTargetTeamsDistributeParallelForSimdDirective final
54340b57cec5SDimitry Andric     : public OMPLoopDirective {
54350b57cec5SDimitry Andric   friend class ASTStmtReader;
5436e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
54370b57cec5SDimitry Andric 
54380b57cec5SDimitry Andric   /// Build directive with the given start and end location.
54390b57cec5SDimitry Andric   ///
54400b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
54410b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
54420b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
54430b57cec5SDimitry Andric   ///
OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)54440b57cec5SDimitry Andric   OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
54450b57cec5SDimitry Andric                                                    SourceLocation EndLoc,
5446e8d8bef9SDimitry Andric                                                    unsigned CollapsedNum)
5447480093f4SDimitry Andric       : OMPLoopDirective(
5448e8d8bef9SDimitry Andric             OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
5449480093f4SDimitry Andric             llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, StartLoc,
5450e8d8bef9SDimitry Andric             EndLoc, CollapsedNum) {}
54510b57cec5SDimitry Andric 
54520b57cec5SDimitry Andric   /// Build an empty directive.
54530b57cec5SDimitry Andric   ///
54540b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
54550b57cec5SDimitry Andric   ///
OMPTargetTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum)54560b57cec5SDimitry Andric   explicit OMPTargetTeamsDistributeParallelForSimdDirective(
5457e8d8bef9SDimitry Andric       unsigned CollapsedNum)
54580b57cec5SDimitry Andric       : OMPLoopDirective(
5459e8d8bef9SDimitry Andric             OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
5460480093f4SDimitry Andric             llvm::omp::OMPD_target_teams_distribute_parallel_for_simd,
5461e8d8bef9SDimitry Andric             SourceLocation(), SourceLocation(), CollapsedNum) {}
54620b57cec5SDimitry Andric 
54630b57cec5SDimitry Andric public:
54640b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
54650b57cec5SDimitry Andric   ///
54660b57cec5SDimitry Andric   /// \param C AST context.
54670b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
54680b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
54690b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
54700b57cec5SDimitry Andric   /// \param Clauses List of clauses.
54710b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
54720b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
54730b57cec5SDimitry Andric   ///
54740b57cec5SDimitry Andric   static OMPTargetTeamsDistributeParallelForSimdDirective *
54750b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
54760b57cec5SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
54770b57cec5SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
54780b57cec5SDimitry Andric 
54790b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses clauses.
54800b57cec5SDimitry Andric   ///
54810b57cec5SDimitry Andric   /// \param C AST context.
54820b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
54830b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
54840b57cec5SDimitry Andric   ///
54850b57cec5SDimitry Andric   static OMPTargetTeamsDistributeParallelForSimdDirective *
54860b57cec5SDimitry Andric   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
54870b57cec5SDimitry Andric               EmptyShell);
54880b57cec5SDimitry Andric 
classof(const Stmt * T)54890b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
54900b57cec5SDimitry Andric     return T->getStmtClass() ==
54910b57cec5SDimitry Andric            OMPTargetTeamsDistributeParallelForSimdDirectiveClass;
54920b57cec5SDimitry Andric   }
54930b57cec5SDimitry Andric };
54940b57cec5SDimitry Andric 
54950b57cec5SDimitry Andric /// This represents '#pragma omp target teams distribute simd' combined
54960b57cec5SDimitry Andric /// directive.
54970b57cec5SDimitry Andric ///
54980b57cec5SDimitry Andric /// \code
54990b57cec5SDimitry Andric /// #pragma omp target teams distribute simd private(x)
55000b57cec5SDimitry Andric /// \endcode
55010b57cec5SDimitry Andric /// In this example directive '#pragma omp target teams distribute simd'
55020b57cec5SDimitry Andric /// has clause 'private' with the variables 'x'
55030b57cec5SDimitry Andric ///
55040b57cec5SDimitry Andric class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective {
55050b57cec5SDimitry Andric   friend class ASTStmtReader;
5506e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
55070b57cec5SDimitry Andric 
55080b57cec5SDimitry Andric   /// Build directive with the given start and end location.
55090b57cec5SDimitry Andric   ///
55100b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
55110b57cec5SDimitry Andric   /// \param EndLoc Ending location of the directive.
55120b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
55130b57cec5SDimitry Andric   ///
OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)55140b57cec5SDimitry Andric   OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc,
55150b57cec5SDimitry Andric                                         SourceLocation EndLoc,
5516e8d8bef9SDimitry Andric                                         unsigned CollapsedNum)
5517e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass,
5518480093f4SDimitry Andric                          llvm::omp::OMPD_target_teams_distribute_simd, StartLoc,
5519e8d8bef9SDimitry Andric                          EndLoc, CollapsedNum) {}
55200b57cec5SDimitry Andric 
55210b57cec5SDimitry Andric   /// Build an empty directive.
55220b57cec5SDimitry Andric   ///
55230b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
55240b57cec5SDimitry Andric   ///
OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum)5525e8d8bef9SDimitry Andric   explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum)
5526e8d8bef9SDimitry Andric       : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass,
5527480093f4SDimitry Andric                          llvm::omp::OMPD_target_teams_distribute_simd,
5528e8d8bef9SDimitry Andric                          SourceLocation(), SourceLocation(), CollapsedNum) {}
55290b57cec5SDimitry Andric 
55300b57cec5SDimitry Andric public:
55310b57cec5SDimitry Andric   /// Creates directive with a list of \a Clauses.
55320b57cec5SDimitry Andric   ///
55330b57cec5SDimitry Andric   /// \param C AST context.
55340b57cec5SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
55350b57cec5SDimitry Andric   /// \param EndLoc Ending Location of the directive.
55360b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
55370b57cec5SDimitry Andric   /// \param Clauses List of clauses.
55380b57cec5SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
55390b57cec5SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
55400b57cec5SDimitry Andric   ///
55410b57cec5SDimitry Andric   static OMPTargetTeamsDistributeSimdDirective *
55420b57cec5SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
55430b57cec5SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
55440b57cec5SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
55450b57cec5SDimitry Andric 
55460b57cec5SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses clauses.
55470b57cec5SDimitry Andric   ///
55480b57cec5SDimitry Andric   /// \param C AST context.
55490b57cec5SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
55500b57cec5SDimitry Andric   /// \param NumClauses Number of clauses.
55510b57cec5SDimitry Andric   ///
55520b57cec5SDimitry Andric   static OMPTargetTeamsDistributeSimdDirective *
55530b57cec5SDimitry Andric   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
55540b57cec5SDimitry Andric               EmptyShell);
55550b57cec5SDimitry Andric 
classof(const Stmt * T)55560b57cec5SDimitry Andric   static bool classof(const Stmt *T) {
55570b57cec5SDimitry Andric     return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
55580b57cec5SDimitry Andric   }
55590b57cec5SDimitry Andric };
55600b57cec5SDimitry Andric 
5561fe6060f1SDimitry Andric /// This represents the '#pragma omp tile' loop transformation directive.
5562349cc55cSDimitry Andric class OMPTileDirective final : public OMPLoopTransformationDirective {
5563fe6060f1SDimitry Andric   friend class ASTStmtReader;
5564fe6060f1SDimitry Andric   friend class OMPExecutableDirective;
5565fe6060f1SDimitry Andric 
5566fe6060f1SDimitry Andric   /// Default list of offsets.
5567fe6060f1SDimitry Andric   enum {
5568fe6060f1SDimitry Andric     PreInitsOffset = 0,
5569fe6060f1SDimitry Andric     TransformedStmtOffset,
5570fe6060f1SDimitry Andric   };
5571fe6060f1SDimitry Andric 
OMPTileDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumLoops)5572fe6060f1SDimitry Andric   explicit OMPTileDirective(SourceLocation StartLoc, SourceLocation EndLoc,
5573fe6060f1SDimitry Andric                             unsigned NumLoops)
5574349cc55cSDimitry Andric       : OMPLoopTransformationDirective(OMPTileDirectiveClass,
5575349cc55cSDimitry Andric                                        llvm::omp::OMPD_tile, StartLoc, EndLoc,
5576349cc55cSDimitry Andric                                        NumLoops) {
5577349cc55cSDimitry Andric     setNumGeneratedLoops(3 * NumLoops);
5578349cc55cSDimitry Andric   }
5579fe6060f1SDimitry Andric 
setPreInits(Stmt * PreInits)5580fe6060f1SDimitry Andric   void setPreInits(Stmt *PreInits) {
5581fe6060f1SDimitry Andric     Data->getChildren()[PreInitsOffset] = PreInits;
5582fe6060f1SDimitry Andric   }
5583fe6060f1SDimitry Andric 
setTransformedStmt(Stmt * S)5584fe6060f1SDimitry Andric   void setTransformedStmt(Stmt *S) {
5585fe6060f1SDimitry Andric     Data->getChildren()[TransformedStmtOffset] = S;
5586fe6060f1SDimitry Andric   }
5587fe6060f1SDimitry Andric 
5588fe6060f1SDimitry Andric public:
5589fe6060f1SDimitry Andric   /// Create a new AST node representation for '#pragma omp tile'.
5590fe6060f1SDimitry Andric   ///
5591fe6060f1SDimitry Andric   /// \param C         Context of the AST.
5592fe6060f1SDimitry Andric   /// \param StartLoc  Location of the introducer (e.g. the 'omp' token).
5593fe6060f1SDimitry Andric   /// \param EndLoc    Location of the directive's end (e.g. the tok::eod).
5594fe6060f1SDimitry Andric   /// \param Clauses   The directive's clauses.
5595fe6060f1SDimitry Andric   /// \param NumLoops  Number of associated loops (number of items in the
5596fe6060f1SDimitry Andric   ///                  'sizes' clause).
5597fe6060f1SDimitry Andric   /// \param AssociatedStmt The outermost associated loop.
5598fe6060f1SDimitry Andric   /// \param TransformedStmt The loop nest after tiling, or nullptr in
5599fe6060f1SDimitry Andric   ///                        dependent contexts.
5600fe6060f1SDimitry Andric   /// \param PreInits Helper preinits statements for the loop nest.
5601fe6060f1SDimitry Andric   static OMPTileDirective *Create(const ASTContext &C, SourceLocation StartLoc,
5602fe6060f1SDimitry Andric                                   SourceLocation EndLoc,
5603fe6060f1SDimitry Andric                                   ArrayRef<OMPClause *> Clauses,
5604fe6060f1SDimitry Andric                                   unsigned NumLoops, Stmt *AssociatedStmt,
5605fe6060f1SDimitry Andric                                   Stmt *TransformedStmt, Stmt *PreInits);
5606fe6060f1SDimitry Andric 
5607fe6060f1SDimitry Andric   /// Build an empty '#pragma omp tile' AST node for deserialization.
5608fe6060f1SDimitry Andric   ///
5609fe6060f1SDimitry Andric   /// \param C          Context of the AST.
5610fe6060f1SDimitry Andric   /// \param NumClauses Number of clauses to allocate.
5611fe6060f1SDimitry Andric   /// \param NumLoops   Number of associated loops to allocate.
5612fe6060f1SDimitry Andric   static OMPTileDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
5613fe6060f1SDimitry Andric                                        unsigned NumLoops);
5614fe6060f1SDimitry Andric 
5615fe6060f1SDimitry Andric   /// Gets/sets the associated loops after tiling.
5616fe6060f1SDimitry Andric   ///
5617fe6060f1SDimitry Andric   /// This is in de-sugared format stored as a CompoundStmt.
5618fe6060f1SDimitry Andric   ///
5619fe6060f1SDimitry Andric   /// \code
5620fe6060f1SDimitry Andric   ///   for (...)
5621fe6060f1SDimitry Andric   ///     ...
5622fe6060f1SDimitry Andric   /// \endcode
5623fe6060f1SDimitry Andric   ///
5624fe6060f1SDimitry Andric   /// Note that if the generated loops a become associated loops of another
5625fe6060f1SDimitry Andric   /// directive, they may need to be hoisted before them.
getTransformedStmt()5626fe6060f1SDimitry Andric   Stmt *getTransformedStmt() const {
5627fe6060f1SDimitry Andric     return Data->getChildren()[TransformedStmtOffset];
5628fe6060f1SDimitry Andric   }
5629fe6060f1SDimitry Andric 
5630fe6060f1SDimitry Andric   /// Return preinits statement.
getPreInits()5631fe6060f1SDimitry Andric   Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
5632fe6060f1SDimitry Andric 
classof(const Stmt * T)5633fe6060f1SDimitry Andric   static bool classof(const Stmt *T) {
5634fe6060f1SDimitry Andric     return T->getStmtClass() == OMPTileDirectiveClass;
5635fe6060f1SDimitry Andric   }
5636fe6060f1SDimitry Andric };
5637fe6060f1SDimitry Andric 
5638fe6060f1SDimitry Andric /// This represents the '#pragma omp unroll' loop transformation directive.
5639fe6060f1SDimitry Andric ///
5640fe6060f1SDimitry Andric /// \code
5641fe6060f1SDimitry Andric /// #pragma omp unroll
5642fe6060f1SDimitry Andric /// for (int i = 0; i < 64; ++i)
5643fe6060f1SDimitry Andric /// \endcode
5644349cc55cSDimitry Andric class OMPUnrollDirective final : public OMPLoopTransformationDirective {
5645fe6060f1SDimitry Andric   friend class ASTStmtReader;
5646fe6060f1SDimitry Andric   friend class OMPExecutableDirective;
5647fe6060f1SDimitry Andric 
5648fe6060f1SDimitry Andric   /// Default list of offsets.
5649fe6060f1SDimitry Andric   enum {
5650fe6060f1SDimitry Andric     PreInitsOffset = 0,
5651fe6060f1SDimitry Andric     TransformedStmtOffset,
5652fe6060f1SDimitry Andric   };
5653fe6060f1SDimitry Andric 
OMPUnrollDirective(SourceLocation StartLoc,SourceLocation EndLoc)5654fe6060f1SDimitry Andric   explicit OMPUnrollDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5655349cc55cSDimitry Andric       : OMPLoopTransformationDirective(OMPUnrollDirectiveClass,
5656349cc55cSDimitry Andric                                        llvm::omp::OMPD_unroll, StartLoc, EndLoc,
5657349cc55cSDimitry Andric                                        1) {}
5658fe6060f1SDimitry Andric 
5659fe6060f1SDimitry Andric   /// Set the pre-init statements.
setPreInits(Stmt * PreInits)5660fe6060f1SDimitry Andric   void setPreInits(Stmt *PreInits) {
5661fe6060f1SDimitry Andric     Data->getChildren()[PreInitsOffset] = PreInits;
5662fe6060f1SDimitry Andric   }
5663fe6060f1SDimitry Andric 
5664fe6060f1SDimitry Andric   /// Set the de-sugared statement.
setTransformedStmt(Stmt * S)5665fe6060f1SDimitry Andric   void setTransformedStmt(Stmt *S) {
5666fe6060f1SDimitry Andric     Data->getChildren()[TransformedStmtOffset] = S;
5667fe6060f1SDimitry Andric   }
5668fe6060f1SDimitry Andric 
5669fe6060f1SDimitry Andric public:
5670fe6060f1SDimitry Andric   /// Create a new AST node representation for '#pragma omp unroll'.
5671fe6060f1SDimitry Andric   ///
5672fe6060f1SDimitry Andric   /// \param C         Context of the AST.
5673fe6060f1SDimitry Andric   /// \param StartLoc  Location of the introducer (e.g. the 'omp' token).
5674fe6060f1SDimitry Andric   /// \param EndLoc    Location of the directive's end (e.g. the tok::eod).
5675fe6060f1SDimitry Andric   /// \param Clauses   The directive's clauses.
5676fe6060f1SDimitry Andric   /// \param AssociatedStmt The outermost associated loop.
5677fe6060f1SDimitry Andric   /// \param TransformedStmt The loop nest after tiling, or nullptr in
5678fe6060f1SDimitry Andric   ///                        dependent contexts.
5679fe6060f1SDimitry Andric   /// \param PreInits   Helper preinits statements for the loop nest.
5680fe6060f1SDimitry Andric   static OMPUnrollDirective *
5681fe6060f1SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5682fe6060f1SDimitry Andric          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
5683349cc55cSDimitry Andric          unsigned NumGeneratedLoops, Stmt *TransformedStmt, Stmt *PreInits);
5684fe6060f1SDimitry Andric 
5685fe6060f1SDimitry Andric   /// Build an empty '#pragma omp unroll' AST node for deserialization.
5686fe6060f1SDimitry Andric   ///
5687fe6060f1SDimitry Andric   /// \param C          Context of the AST.
5688fe6060f1SDimitry Andric   /// \param NumClauses Number of clauses to allocate.
5689fe6060f1SDimitry Andric   static OMPUnrollDirective *CreateEmpty(const ASTContext &C,
5690fe6060f1SDimitry Andric                                          unsigned NumClauses);
5691fe6060f1SDimitry Andric 
5692fe6060f1SDimitry Andric   /// Get the de-sugared associated loops after unrolling.
5693fe6060f1SDimitry Andric   ///
5694fe6060f1SDimitry Andric   /// This is only used if the unrolled loop becomes an associated loop of
5695fe6060f1SDimitry Andric   /// another directive, otherwise the loop is emitted directly using loop
5696fe6060f1SDimitry Andric   /// transformation metadata. When the unrolled loop cannot be used by another
5697fe6060f1SDimitry Andric   /// directive (e.g. because of the full clause), the transformed stmt can also
5698fe6060f1SDimitry Andric   /// be nullptr.
getTransformedStmt()5699fe6060f1SDimitry Andric   Stmt *getTransformedStmt() const {
5700fe6060f1SDimitry Andric     return Data->getChildren()[TransformedStmtOffset];
5701fe6060f1SDimitry Andric   }
5702fe6060f1SDimitry Andric 
5703fe6060f1SDimitry Andric   /// Return the pre-init statements.
getPreInits()5704fe6060f1SDimitry Andric   Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
5705fe6060f1SDimitry Andric 
classof(const Stmt * T)5706fe6060f1SDimitry Andric   static bool classof(const Stmt *T) {
5707fe6060f1SDimitry Andric     return T->getStmtClass() == OMPUnrollDirectiveClass;
5708fe6060f1SDimitry Andric   }
5709fe6060f1SDimitry Andric };
5710fe6060f1SDimitry Andric 
57115ffd83dbSDimitry Andric /// This represents '#pragma omp scan' directive.
57125ffd83dbSDimitry Andric ///
57135ffd83dbSDimitry Andric /// \code
57145ffd83dbSDimitry Andric /// #pragma omp scan inclusive(a)
57155ffd83dbSDimitry Andric /// \endcode
57165ffd83dbSDimitry Andric /// In this example directive '#pragma omp scan' has clause 'inclusive' with
57175ffd83dbSDimitry Andric /// list item 'a'.
57185ffd83dbSDimitry Andric class OMPScanDirective final : public OMPExecutableDirective {
57195ffd83dbSDimitry Andric   friend class ASTStmtReader;
5720e8d8bef9SDimitry Andric   friend class OMPExecutableDirective;
57215ffd83dbSDimitry Andric   /// Build directive with the given start and end location.
57225ffd83dbSDimitry Andric   ///
57235ffd83dbSDimitry Andric   /// \param StartLoc Starting location of the directive kind.
57245ffd83dbSDimitry Andric   /// \param EndLoc Ending location of the directive.
57255ffd83dbSDimitry Andric   ///
OMPScanDirective(SourceLocation StartLoc,SourceLocation EndLoc)5726e8d8bef9SDimitry Andric   OMPScanDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5727e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan,
5728e8d8bef9SDimitry Andric                                StartLoc, EndLoc) {}
57295ffd83dbSDimitry Andric 
57305ffd83dbSDimitry Andric   /// Build an empty directive.
57315ffd83dbSDimitry Andric   ///
OMPScanDirective()5732e8d8bef9SDimitry Andric   explicit OMPScanDirective()
5733e8d8bef9SDimitry Andric       : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan,
5734e8d8bef9SDimitry Andric                                SourceLocation(), SourceLocation()) {}
57355ffd83dbSDimitry Andric 
57365ffd83dbSDimitry Andric public:
57375ffd83dbSDimitry Andric   /// Creates directive with a list of \a Clauses.
57385ffd83dbSDimitry Andric   ///
57395ffd83dbSDimitry Andric   /// \param C AST context.
57405ffd83dbSDimitry Andric   /// \param StartLoc Starting location of the directive kind.
57415ffd83dbSDimitry Andric   /// \param EndLoc Ending Location of the directive.
57425ffd83dbSDimitry Andric   /// \param Clauses List of clauses (only single OMPFlushClause clause is
57435ffd83dbSDimitry Andric   /// allowed).
57445ffd83dbSDimitry Andric   ///
57455ffd83dbSDimitry Andric   static OMPScanDirective *Create(const ASTContext &C, SourceLocation StartLoc,
57465ffd83dbSDimitry Andric                                   SourceLocation EndLoc,
57475ffd83dbSDimitry Andric                                   ArrayRef<OMPClause *> Clauses);
57485ffd83dbSDimitry Andric 
57495ffd83dbSDimitry Andric   /// Creates an empty directive with the place for \a NumClauses
57505ffd83dbSDimitry Andric   /// clauses.
57515ffd83dbSDimitry Andric   ///
57525ffd83dbSDimitry Andric   /// \param C AST context.
57535ffd83dbSDimitry Andric   /// \param NumClauses Number of clauses.
57545ffd83dbSDimitry Andric   ///
57555ffd83dbSDimitry Andric   static OMPScanDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
57565ffd83dbSDimitry Andric                                        EmptyShell);
57575ffd83dbSDimitry Andric 
classof(const Stmt * T)57585ffd83dbSDimitry Andric   static bool classof(const Stmt *T) {
57595ffd83dbSDimitry Andric     return T->getStmtClass() == OMPScanDirectiveClass;
57605ffd83dbSDimitry Andric   }
57615ffd83dbSDimitry Andric };
57625ffd83dbSDimitry Andric 
5763fe6060f1SDimitry Andric /// This represents '#pragma omp interop' directive.
5764fe6060f1SDimitry Andric ///
5765fe6060f1SDimitry Andric /// \code
5766fe6060f1SDimitry Andric /// #pragma omp interop init(target:obj) device(x) depend(inout:y) nowait
5767fe6060f1SDimitry Andric /// \endcode
5768fe6060f1SDimitry Andric /// In this example directive '#pragma omp interop' has
5769fe6060f1SDimitry Andric /// clauses 'init', 'device', 'depend' and 'nowait'.
5770fe6060f1SDimitry Andric ///
5771fe6060f1SDimitry Andric class OMPInteropDirective final : public OMPExecutableDirective {
5772fe6060f1SDimitry Andric   friend class ASTStmtReader;
5773fe6060f1SDimitry Andric   friend class OMPExecutableDirective;
5774fe6060f1SDimitry Andric 
5775fe6060f1SDimitry Andric   /// Build directive with the given start and end location.
5776fe6060f1SDimitry Andric   ///
5777fe6060f1SDimitry Andric   /// \param StartLoc Starting location of the directive.
5778fe6060f1SDimitry Andric   /// \param EndLoc Ending location of the directive.
5779fe6060f1SDimitry Andric   ///
OMPInteropDirective(SourceLocation StartLoc,SourceLocation EndLoc)5780fe6060f1SDimitry Andric   OMPInteropDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5781fe6060f1SDimitry Andric       : OMPExecutableDirective(OMPInteropDirectiveClass,
5782fe6060f1SDimitry Andric                                llvm::omp::OMPD_interop, StartLoc, EndLoc) {}
5783fe6060f1SDimitry Andric 
5784fe6060f1SDimitry Andric   /// Build an empty directive.
5785fe6060f1SDimitry Andric   ///
OMPInteropDirective()5786fe6060f1SDimitry Andric   explicit OMPInteropDirective()
5787fe6060f1SDimitry Andric       : OMPExecutableDirective(OMPInteropDirectiveClass,
5788fe6060f1SDimitry Andric                                llvm::omp::OMPD_interop, SourceLocation(),
5789fe6060f1SDimitry Andric                                SourceLocation()) {}
5790fe6060f1SDimitry Andric 
5791fe6060f1SDimitry Andric public:
5792fe6060f1SDimitry Andric   /// Creates directive.
5793fe6060f1SDimitry Andric   ///
5794fe6060f1SDimitry Andric   /// \param C AST context.
5795fe6060f1SDimitry Andric   /// \param StartLoc Starting location of the directive.
5796fe6060f1SDimitry Andric   /// \param EndLoc Ending Location of the directive.
5797fe6060f1SDimitry Andric   /// \param Clauses The directive's clauses.
5798fe6060f1SDimitry Andric   ///
5799fe6060f1SDimitry Andric   static OMPInteropDirective *Create(const ASTContext &C,
5800fe6060f1SDimitry Andric                                      SourceLocation StartLoc,
5801fe6060f1SDimitry Andric                                      SourceLocation EndLoc,
5802fe6060f1SDimitry Andric                                      ArrayRef<OMPClause *> Clauses);
5803fe6060f1SDimitry Andric 
5804fe6060f1SDimitry Andric   /// Creates an empty directive.
5805fe6060f1SDimitry Andric   ///
5806fe6060f1SDimitry Andric   /// \param C AST context.
5807fe6060f1SDimitry Andric   ///
5808fe6060f1SDimitry Andric   static OMPInteropDirective *CreateEmpty(const ASTContext &C,
5809fe6060f1SDimitry Andric                                           unsigned NumClauses, EmptyShell);
5810fe6060f1SDimitry Andric 
classof(const Stmt * T)5811fe6060f1SDimitry Andric   static bool classof(const Stmt *T) {
5812fe6060f1SDimitry Andric     return T->getStmtClass() == OMPInteropDirectiveClass;
5813fe6060f1SDimitry Andric   }
5814fe6060f1SDimitry Andric };
5815fe6060f1SDimitry Andric 
5816fe6060f1SDimitry Andric /// This represents '#pragma omp dispatch' directive.
5817fe6060f1SDimitry Andric ///
5818fe6060f1SDimitry Andric /// \code
5819fe6060f1SDimitry Andric /// #pragma omp dispatch device(dnum)
5820fe6060f1SDimitry Andric /// \endcode
5821fe6060f1SDimitry Andric /// This example shows a directive '#pragma omp dispatch' with a
5822fe6060f1SDimitry Andric /// device clause with variable 'dnum'.
5823fe6060f1SDimitry Andric ///
5824fe6060f1SDimitry Andric class OMPDispatchDirective final : public OMPExecutableDirective {
5825fe6060f1SDimitry Andric   friend class ASTStmtReader;
5826fe6060f1SDimitry Andric   friend class OMPExecutableDirective;
5827fe6060f1SDimitry Andric 
5828fe6060f1SDimitry Andric   /// The location of the target-call.
5829fe6060f1SDimitry Andric   SourceLocation TargetCallLoc;
5830fe6060f1SDimitry Andric 
5831fe6060f1SDimitry Andric   /// Set the location of the target-call.
setTargetCallLoc(SourceLocation Loc)5832fe6060f1SDimitry Andric   void setTargetCallLoc(SourceLocation Loc) { TargetCallLoc = Loc; }
5833fe6060f1SDimitry Andric 
5834fe6060f1SDimitry Andric   /// Build directive with the given start and end location.
5835fe6060f1SDimitry Andric   ///
5836fe6060f1SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
5837fe6060f1SDimitry Andric   /// \param EndLoc Ending location of the directive.
5838fe6060f1SDimitry Andric   ///
OMPDispatchDirective(SourceLocation StartLoc,SourceLocation EndLoc)5839fe6060f1SDimitry Andric   OMPDispatchDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5840fe6060f1SDimitry Andric       : OMPExecutableDirective(OMPDispatchDirectiveClass,
5841fe6060f1SDimitry Andric                                llvm::omp::OMPD_dispatch, StartLoc, EndLoc) {}
5842fe6060f1SDimitry Andric 
5843fe6060f1SDimitry Andric   /// Build an empty directive.
5844fe6060f1SDimitry Andric   ///
OMPDispatchDirective()5845fe6060f1SDimitry Andric   explicit OMPDispatchDirective()
5846fe6060f1SDimitry Andric       : OMPExecutableDirective(OMPDispatchDirectiveClass,
5847fe6060f1SDimitry Andric                                llvm::omp::OMPD_dispatch, SourceLocation(),
5848fe6060f1SDimitry Andric                                SourceLocation()) {}
5849fe6060f1SDimitry Andric 
5850fe6060f1SDimitry Andric public:
5851fe6060f1SDimitry Andric   /// Creates directive with a list of \a Clauses.
5852fe6060f1SDimitry Andric   ///
5853fe6060f1SDimitry Andric   /// \param C AST context.
5854fe6060f1SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
5855fe6060f1SDimitry Andric   /// \param EndLoc Ending Location of the directive.
5856fe6060f1SDimitry Andric   /// \param Clauses List of clauses.
5857fe6060f1SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
5858fe6060f1SDimitry Andric   /// \param TargetCallLoc Location of the target-call.
5859fe6060f1SDimitry Andric   ///
5860fe6060f1SDimitry Andric   static OMPDispatchDirective *
5861fe6060f1SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5862fe6060f1SDimitry Andric          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
5863fe6060f1SDimitry Andric          SourceLocation TargetCallLoc);
5864fe6060f1SDimitry Andric 
5865fe6060f1SDimitry Andric   /// Creates an empty directive with the place for \a NumClauses
5866fe6060f1SDimitry Andric   /// clauses.
5867fe6060f1SDimitry Andric   ///
5868fe6060f1SDimitry Andric   /// \param C AST context.
5869fe6060f1SDimitry Andric   /// \param NumClauses Number of clauses.
5870fe6060f1SDimitry Andric   ///
5871fe6060f1SDimitry Andric   static OMPDispatchDirective *CreateEmpty(const ASTContext &C,
5872fe6060f1SDimitry Andric                                            unsigned NumClauses, EmptyShell);
5873fe6060f1SDimitry Andric 
5874fe6060f1SDimitry Andric   /// Return location of target-call.
getTargetCallLoc()5875fe6060f1SDimitry Andric   SourceLocation getTargetCallLoc() const { return TargetCallLoc; }
5876fe6060f1SDimitry Andric 
classof(const Stmt * T)5877fe6060f1SDimitry Andric   static bool classof(const Stmt *T) {
5878fe6060f1SDimitry Andric     return T->getStmtClass() == OMPDispatchDirectiveClass;
5879fe6060f1SDimitry Andric   }
5880fe6060f1SDimitry Andric };
5881fe6060f1SDimitry Andric 
5882fe6060f1SDimitry Andric /// This represents '#pragma omp masked' directive.
5883fe6060f1SDimitry Andric /// \code
5884fe6060f1SDimitry Andric /// #pragma omp masked filter(tid)
5885fe6060f1SDimitry Andric /// \endcode
5886fe6060f1SDimitry Andric /// This example shows a directive '#pragma omp masked' with a filter clause
5887fe6060f1SDimitry Andric /// with variable 'tid'.
5888fe6060f1SDimitry Andric ///
5889fe6060f1SDimitry Andric class OMPMaskedDirective final : public OMPExecutableDirective {
5890fe6060f1SDimitry Andric   friend class ASTStmtReader;
5891fe6060f1SDimitry Andric   friend class OMPExecutableDirective;
5892fe6060f1SDimitry Andric 
5893fe6060f1SDimitry Andric   /// Build directive with the given start and end location.
5894fe6060f1SDimitry Andric   ///
5895fe6060f1SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
5896fe6060f1SDimitry Andric   /// \param EndLoc Ending location of the directive.
5897fe6060f1SDimitry Andric   ///
OMPMaskedDirective(SourceLocation StartLoc,SourceLocation EndLoc)5898fe6060f1SDimitry Andric   OMPMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5899fe6060f1SDimitry Andric       : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked,
5900fe6060f1SDimitry Andric                                StartLoc, EndLoc) {}
5901fe6060f1SDimitry Andric 
5902fe6060f1SDimitry Andric   /// Build an empty directive.
5903fe6060f1SDimitry Andric   ///
OMPMaskedDirective()5904fe6060f1SDimitry Andric   explicit OMPMaskedDirective()
5905fe6060f1SDimitry Andric       : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked,
5906fe6060f1SDimitry Andric                                SourceLocation(), SourceLocation()) {}
5907fe6060f1SDimitry Andric 
5908fe6060f1SDimitry Andric public:
5909fe6060f1SDimitry Andric   /// Creates directive.
5910fe6060f1SDimitry Andric   ///
5911fe6060f1SDimitry Andric   /// \param C AST context.
5912fe6060f1SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
5913fe6060f1SDimitry Andric   /// \param EndLoc Ending Location of the directive.
5914fe6060f1SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
5915fe6060f1SDimitry Andric   ///
5916fe6060f1SDimitry Andric   static OMPMaskedDirective *
5917fe6060f1SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5918fe6060f1SDimitry Andric          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
5919fe6060f1SDimitry Andric 
5920fe6060f1SDimitry Andric   /// Creates an empty directive.
5921fe6060f1SDimitry Andric   ///
5922fe6060f1SDimitry Andric   /// \param C AST context.
5923fe6060f1SDimitry Andric   ///
5924fe6060f1SDimitry Andric   static OMPMaskedDirective *CreateEmpty(const ASTContext &C,
5925fe6060f1SDimitry Andric                                          unsigned NumClauses, EmptyShell);
5926fe6060f1SDimitry Andric 
classof(const Stmt * T)5927fe6060f1SDimitry Andric   static bool classof(const Stmt *T) {
5928fe6060f1SDimitry Andric     return T->getStmtClass() == OMPMaskedDirectiveClass;
5929fe6060f1SDimitry Andric   }
5930fe6060f1SDimitry Andric };
5931fe6060f1SDimitry Andric 
5932349cc55cSDimitry Andric /// This represents '#pragma omp metadirective' directive.
5933349cc55cSDimitry Andric ///
5934349cc55cSDimitry Andric /// \code
5935349cc55cSDimitry Andric /// #pragma omp metadirective when(user={condition(N>10)}: parallel for)
5936349cc55cSDimitry Andric /// \endcode
5937349cc55cSDimitry Andric /// In this example directive '#pragma omp metadirective' has clauses 'when'
5938349cc55cSDimitry Andric /// with a dynamic user condition to check if a variable 'N > 10'
5939349cc55cSDimitry Andric ///
5940349cc55cSDimitry Andric class OMPMetaDirective final : public OMPExecutableDirective {
5941349cc55cSDimitry Andric   friend class ASTStmtReader;
5942349cc55cSDimitry Andric   friend class OMPExecutableDirective;
5943349cc55cSDimitry Andric   Stmt *IfStmt;
5944349cc55cSDimitry Andric 
OMPMetaDirective(SourceLocation StartLoc,SourceLocation EndLoc)5945349cc55cSDimitry Andric   OMPMetaDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5946349cc55cSDimitry Andric       : OMPExecutableDirective(OMPMetaDirectiveClass,
5947349cc55cSDimitry Andric                                llvm::omp::OMPD_metadirective, StartLoc,
5948349cc55cSDimitry Andric                                EndLoc) {}
OMPMetaDirective()5949349cc55cSDimitry Andric   explicit OMPMetaDirective()
5950349cc55cSDimitry Andric       : OMPExecutableDirective(OMPMetaDirectiveClass,
5951349cc55cSDimitry Andric                                llvm::omp::OMPD_metadirective, SourceLocation(),
5952349cc55cSDimitry Andric                                SourceLocation()) {}
5953349cc55cSDimitry Andric 
setIfStmt(Stmt * S)5954349cc55cSDimitry Andric   void setIfStmt(Stmt *S) { IfStmt = S; }
5955349cc55cSDimitry Andric 
5956349cc55cSDimitry Andric public:
5957349cc55cSDimitry Andric   static OMPMetaDirective *Create(const ASTContext &C, SourceLocation StartLoc,
5958349cc55cSDimitry Andric                                   SourceLocation EndLoc,
5959349cc55cSDimitry Andric                                   ArrayRef<OMPClause *> Clauses,
5960349cc55cSDimitry Andric                                   Stmt *AssociatedStmt, Stmt *IfStmt);
5961349cc55cSDimitry Andric   static OMPMetaDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
5962349cc55cSDimitry Andric                                        EmptyShell);
getIfStmt()5963349cc55cSDimitry Andric   Stmt *getIfStmt() const { return IfStmt; }
5964349cc55cSDimitry Andric 
classof(const Stmt * T)5965349cc55cSDimitry Andric   static bool classof(const Stmt *T) {
5966349cc55cSDimitry Andric     return T->getStmtClass() == OMPMetaDirectiveClass;
5967349cc55cSDimitry Andric   }
5968349cc55cSDimitry Andric };
5969349cc55cSDimitry Andric 
5970349cc55cSDimitry Andric /// This represents '#pragma omp loop' directive.
5971349cc55cSDimitry Andric ///
5972349cc55cSDimitry Andric /// \code
5973349cc55cSDimitry Andric /// #pragma omp loop private(a,b) binding(parallel) order(concurrent)
5974349cc55cSDimitry Andric /// \endcode
5975349cc55cSDimitry Andric /// In this example directive '#pragma omp loop' has
5976349cc55cSDimitry Andric /// clauses 'private' with the variables 'a' and 'b', 'binding' with
5977349cc55cSDimitry Andric /// modifier 'parallel' and 'order(concurrent).
5978349cc55cSDimitry Andric ///
5979349cc55cSDimitry Andric class OMPGenericLoopDirective final : public OMPLoopDirective {
5980349cc55cSDimitry Andric   friend class ASTStmtReader;
5981349cc55cSDimitry Andric   friend class OMPExecutableDirective;
5982349cc55cSDimitry Andric   /// Build directive with the given start and end location.
5983349cc55cSDimitry Andric   ///
5984349cc55cSDimitry Andric   /// \param StartLoc Starting location of the directive kind.
5985349cc55cSDimitry Andric   /// \param EndLoc Ending location of the directive.
5986349cc55cSDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
5987349cc55cSDimitry Andric   ///
OMPGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)5988349cc55cSDimitry Andric   OMPGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
5989349cc55cSDimitry Andric                           unsigned CollapsedNum)
5990349cc55cSDimitry Andric       : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop,
5991349cc55cSDimitry Andric                          StartLoc, EndLoc, CollapsedNum) {}
5992349cc55cSDimitry Andric 
5993349cc55cSDimitry Andric   /// Build an empty directive.
5994349cc55cSDimitry Andric   ///
5995349cc55cSDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
5996349cc55cSDimitry Andric   ///
OMPGenericLoopDirective(unsigned CollapsedNum)5997349cc55cSDimitry Andric   explicit OMPGenericLoopDirective(unsigned CollapsedNum)
5998349cc55cSDimitry Andric       : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop,
5999349cc55cSDimitry Andric                          SourceLocation(), SourceLocation(), CollapsedNum) {}
6000349cc55cSDimitry Andric 
6001349cc55cSDimitry Andric public:
6002349cc55cSDimitry Andric   /// Creates directive with a list of \p Clauses.
6003349cc55cSDimitry Andric   ///
6004349cc55cSDimitry Andric   /// \param C AST context.
6005349cc55cSDimitry Andric   /// \param StartLoc Starting location of the directive kind.
6006349cc55cSDimitry Andric   /// \param EndLoc Ending Location of the directive.
6007349cc55cSDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
6008349cc55cSDimitry Andric   /// \param Clauses List of clauses.
6009349cc55cSDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
6010349cc55cSDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
6011349cc55cSDimitry Andric   ///
6012349cc55cSDimitry Andric   static OMPGenericLoopDirective *
6013349cc55cSDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
6014349cc55cSDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
6015349cc55cSDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
6016349cc55cSDimitry Andric 
6017349cc55cSDimitry Andric   /// Creates an empty directive with a place for \a NumClauses clauses.
6018349cc55cSDimitry Andric   ///
6019349cc55cSDimitry Andric   /// \param C AST context.
6020349cc55cSDimitry Andric   /// \param NumClauses Number of clauses.
6021349cc55cSDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
6022349cc55cSDimitry Andric   ///
6023349cc55cSDimitry Andric   static OMPGenericLoopDirective *CreateEmpty(const ASTContext &C,
6024349cc55cSDimitry Andric                                               unsigned NumClauses,
6025349cc55cSDimitry Andric                                               unsigned CollapsedNum,
6026349cc55cSDimitry Andric                                               EmptyShell);
6027349cc55cSDimitry Andric 
classof(const Stmt * T)6028349cc55cSDimitry Andric   static bool classof(const Stmt *T) {
6029349cc55cSDimitry Andric     return T->getStmtClass() == OMPGenericLoopDirectiveClass;
6030349cc55cSDimitry Andric   }
6031349cc55cSDimitry Andric };
6032349cc55cSDimitry Andric 
603381ad6265SDimitry Andric /// This represents '#pragma omp teams loop' directive.
603481ad6265SDimitry Andric ///
603581ad6265SDimitry Andric /// \code
603681ad6265SDimitry Andric /// #pragma omp teams loop private(a,b) order(concurrent)
603781ad6265SDimitry Andric /// \endcode
603881ad6265SDimitry Andric /// In this example directive '#pragma omp teams loop' has
603981ad6265SDimitry Andric /// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
604081ad6265SDimitry Andric ///
604181ad6265SDimitry Andric class OMPTeamsGenericLoopDirective final : public OMPLoopDirective {
604281ad6265SDimitry Andric   friend class ASTStmtReader;
604381ad6265SDimitry Andric   friend class OMPExecutableDirective;
604481ad6265SDimitry Andric   /// Build directive with the given start and end location.
604581ad6265SDimitry Andric   ///
604681ad6265SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
604781ad6265SDimitry Andric   /// \param EndLoc Ending location of the directive.
604881ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
604981ad6265SDimitry Andric   ///
OMPTeamsGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)605081ad6265SDimitry Andric   OMPTeamsGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
605181ad6265SDimitry Andric                                unsigned CollapsedNum)
605281ad6265SDimitry Andric       : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass,
605381ad6265SDimitry Andric                          llvm::omp::OMPD_teams_loop, StartLoc, EndLoc,
605481ad6265SDimitry Andric                          CollapsedNum) {}
605581ad6265SDimitry Andric 
605681ad6265SDimitry Andric   /// Build an empty directive.
605781ad6265SDimitry Andric   ///
605881ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
605981ad6265SDimitry Andric   ///
OMPTeamsGenericLoopDirective(unsigned CollapsedNum)606081ad6265SDimitry Andric   explicit OMPTeamsGenericLoopDirective(unsigned CollapsedNum)
606181ad6265SDimitry Andric       : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass,
606281ad6265SDimitry Andric                          llvm::omp::OMPD_teams_loop, SourceLocation(),
606381ad6265SDimitry Andric                          SourceLocation(), CollapsedNum) {}
606481ad6265SDimitry Andric 
606581ad6265SDimitry Andric public:
606681ad6265SDimitry Andric   /// Creates directive with a list of \p Clauses.
606781ad6265SDimitry Andric   ///
606881ad6265SDimitry Andric   /// \param C AST context.
606981ad6265SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
607081ad6265SDimitry Andric   /// \param EndLoc Ending Location of the directive.
607181ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
607281ad6265SDimitry Andric   /// \param Clauses List of clauses.
607381ad6265SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
607481ad6265SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
607581ad6265SDimitry Andric   ///
607681ad6265SDimitry Andric   static OMPTeamsGenericLoopDirective *
607781ad6265SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
607881ad6265SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
607981ad6265SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
608081ad6265SDimitry Andric 
608181ad6265SDimitry Andric   /// Creates an empty directive with the place
608281ad6265SDimitry Andric   /// for \a NumClauses clauses.
608381ad6265SDimitry Andric   ///
608481ad6265SDimitry Andric   /// \param C AST context.
608581ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
608681ad6265SDimitry Andric   /// \param NumClauses Number of clauses.
608781ad6265SDimitry Andric   ///
608881ad6265SDimitry Andric   static OMPTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C,
608981ad6265SDimitry Andric                                                    unsigned NumClauses,
609081ad6265SDimitry Andric                                                    unsigned CollapsedNum,
609181ad6265SDimitry Andric                                                    EmptyShell);
609281ad6265SDimitry Andric 
classof(const Stmt * T)609381ad6265SDimitry Andric   static bool classof(const Stmt *T) {
609481ad6265SDimitry Andric     return T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass;
609581ad6265SDimitry Andric   }
609681ad6265SDimitry Andric };
609781ad6265SDimitry Andric 
609881ad6265SDimitry Andric /// This represents '#pragma omp target teams loop' directive.
609981ad6265SDimitry Andric ///
610081ad6265SDimitry Andric /// \code
610181ad6265SDimitry Andric /// #pragma omp target teams loop private(a,b) order(concurrent)
610281ad6265SDimitry Andric /// \endcode
610381ad6265SDimitry Andric /// In this example directive '#pragma omp target teams loop' has
610481ad6265SDimitry Andric /// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
610581ad6265SDimitry Andric ///
610681ad6265SDimitry Andric class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective {
610781ad6265SDimitry Andric   friend class ASTStmtReader;
610881ad6265SDimitry Andric   friend class OMPExecutableDirective;
610981ad6265SDimitry Andric   /// Build directive with the given start and end location.
611081ad6265SDimitry Andric   ///
611181ad6265SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
611281ad6265SDimitry Andric   /// \param EndLoc Ending location of the directive.
611381ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
611481ad6265SDimitry Andric   ///
OMPTargetTeamsGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)611581ad6265SDimitry Andric   OMPTargetTeamsGenericLoopDirective(SourceLocation StartLoc,
611681ad6265SDimitry Andric                                      SourceLocation EndLoc,
611781ad6265SDimitry Andric                                      unsigned CollapsedNum)
611881ad6265SDimitry Andric       : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass,
611981ad6265SDimitry Andric                          llvm::omp::OMPD_target_teams_loop, StartLoc, EndLoc,
612081ad6265SDimitry Andric                          CollapsedNum) {}
612181ad6265SDimitry Andric 
612281ad6265SDimitry Andric   /// Build an empty directive.
612381ad6265SDimitry Andric   ///
612481ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
612581ad6265SDimitry Andric   ///
OMPTargetTeamsGenericLoopDirective(unsigned CollapsedNum)612681ad6265SDimitry Andric   explicit OMPTargetTeamsGenericLoopDirective(unsigned CollapsedNum)
612781ad6265SDimitry Andric       : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass,
612881ad6265SDimitry Andric                          llvm::omp::OMPD_target_teams_loop, SourceLocation(),
612981ad6265SDimitry Andric                          SourceLocation(), CollapsedNum) {}
613081ad6265SDimitry Andric 
613181ad6265SDimitry Andric public:
613281ad6265SDimitry Andric   /// Creates directive with a list of \p Clauses.
613381ad6265SDimitry Andric   ///
613481ad6265SDimitry Andric   /// \param C AST context.
613581ad6265SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
613681ad6265SDimitry Andric   /// \param EndLoc Ending Location of the directive.
613781ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
613881ad6265SDimitry Andric   /// \param Clauses List of clauses.
613981ad6265SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
614081ad6265SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
614181ad6265SDimitry Andric   ///
614281ad6265SDimitry Andric   static OMPTargetTeamsGenericLoopDirective *
614381ad6265SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
614481ad6265SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
614581ad6265SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
614681ad6265SDimitry Andric 
614781ad6265SDimitry Andric   /// Creates an empty directive with the place
614881ad6265SDimitry Andric   /// for \a NumClauses clauses.
614981ad6265SDimitry Andric   ///
615081ad6265SDimitry Andric   /// \param C AST context.
615181ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
615281ad6265SDimitry Andric   /// \param NumClauses Number of clauses.
615381ad6265SDimitry Andric   ///
615481ad6265SDimitry Andric   static OMPTargetTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C,
615581ad6265SDimitry Andric                                                          unsigned NumClauses,
615681ad6265SDimitry Andric                                                          unsigned CollapsedNum,
615781ad6265SDimitry Andric                                                          EmptyShell);
615881ad6265SDimitry Andric 
classof(const Stmt * T)615981ad6265SDimitry Andric   static bool classof(const Stmt *T) {
616081ad6265SDimitry Andric     return T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass;
616181ad6265SDimitry Andric   }
616281ad6265SDimitry Andric };
616381ad6265SDimitry Andric 
616481ad6265SDimitry Andric /// This represents '#pragma omp parallel loop' directive.
616581ad6265SDimitry Andric ///
616681ad6265SDimitry Andric /// \code
616781ad6265SDimitry Andric /// #pragma omp parallel loop private(a,b) order(concurrent)
616881ad6265SDimitry Andric /// \endcode
616981ad6265SDimitry Andric /// In this example directive '#pragma omp parallel loop' has
617081ad6265SDimitry Andric /// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
617181ad6265SDimitry Andric ///
617281ad6265SDimitry Andric class OMPParallelGenericLoopDirective final : public OMPLoopDirective {
617381ad6265SDimitry Andric   friend class ASTStmtReader;
617481ad6265SDimitry Andric   friend class OMPExecutableDirective;
617581ad6265SDimitry Andric   /// Build directive with the given start and end location.
617681ad6265SDimitry Andric   ///
617781ad6265SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
617881ad6265SDimitry Andric   /// \param EndLoc Ending location of the directive.
617981ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
618081ad6265SDimitry Andric   ///
OMPParallelGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)618181ad6265SDimitry Andric   OMPParallelGenericLoopDirective(SourceLocation StartLoc,
618281ad6265SDimitry Andric                                   SourceLocation EndLoc, unsigned CollapsedNum)
618381ad6265SDimitry Andric       : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass,
618481ad6265SDimitry Andric                          llvm::omp::OMPD_parallel_loop, StartLoc, EndLoc,
618581ad6265SDimitry Andric                          CollapsedNum) {}
618681ad6265SDimitry Andric 
618781ad6265SDimitry Andric   /// Build an empty directive.
618881ad6265SDimitry Andric   ///
618981ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
619081ad6265SDimitry Andric   ///
OMPParallelGenericLoopDirective(unsigned CollapsedNum)619181ad6265SDimitry Andric   explicit OMPParallelGenericLoopDirective(unsigned CollapsedNum)
619281ad6265SDimitry Andric       : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass,
619381ad6265SDimitry Andric                          llvm::omp::OMPD_parallel_loop, SourceLocation(),
619481ad6265SDimitry Andric                          SourceLocation(), CollapsedNum) {}
619581ad6265SDimitry Andric 
619681ad6265SDimitry Andric public:
619781ad6265SDimitry Andric   /// Creates directive with a list of \p Clauses.
619881ad6265SDimitry Andric   ///
619981ad6265SDimitry Andric   /// \param C AST context.
620081ad6265SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
620181ad6265SDimitry Andric   /// \param EndLoc Ending Location of the directive.
620281ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
620381ad6265SDimitry Andric   /// \param Clauses List of clauses.
620481ad6265SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
620581ad6265SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
620681ad6265SDimitry Andric   ///
620781ad6265SDimitry Andric   static OMPParallelGenericLoopDirective *
620881ad6265SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
620981ad6265SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
621081ad6265SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
621181ad6265SDimitry Andric 
621281ad6265SDimitry Andric   /// Creates an empty directive with the place
621381ad6265SDimitry Andric   /// for \a NumClauses clauses.
621481ad6265SDimitry Andric   ///
621581ad6265SDimitry Andric   /// \param C AST context.
621681ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
621781ad6265SDimitry Andric   /// \param NumClauses Number of clauses.
621881ad6265SDimitry Andric   ///
621981ad6265SDimitry Andric   static OMPParallelGenericLoopDirective *CreateEmpty(const ASTContext &C,
622081ad6265SDimitry Andric                                                       unsigned NumClauses,
622181ad6265SDimitry Andric                                                       unsigned CollapsedNum,
622281ad6265SDimitry Andric                                                       EmptyShell);
622381ad6265SDimitry Andric 
classof(const Stmt * T)622481ad6265SDimitry Andric   static bool classof(const Stmt *T) {
622581ad6265SDimitry Andric     return T->getStmtClass() == OMPParallelGenericLoopDirectiveClass;
622681ad6265SDimitry Andric   }
622781ad6265SDimitry Andric };
622881ad6265SDimitry Andric 
622981ad6265SDimitry Andric /// This represents '#pragma omp target parallel loop' directive.
623081ad6265SDimitry Andric ///
623181ad6265SDimitry Andric /// \code
623281ad6265SDimitry Andric /// #pragma omp target parallel loop private(a,b) order(concurrent)
623381ad6265SDimitry Andric /// \endcode
623481ad6265SDimitry Andric /// In this example directive '#pragma omp target parallel loop' has
623581ad6265SDimitry Andric /// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
623681ad6265SDimitry Andric ///
623781ad6265SDimitry Andric class OMPTargetParallelGenericLoopDirective final : public OMPLoopDirective {
623881ad6265SDimitry Andric   friend class ASTStmtReader;
623981ad6265SDimitry Andric   friend class OMPExecutableDirective;
624081ad6265SDimitry Andric   /// Build directive with the given start and end location.
624181ad6265SDimitry Andric   ///
624281ad6265SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
624381ad6265SDimitry Andric   /// \param EndLoc Ending location of the directive.
624481ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
624581ad6265SDimitry Andric   ///
OMPTargetParallelGenericLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum)624681ad6265SDimitry Andric   OMPTargetParallelGenericLoopDirective(SourceLocation StartLoc,
624781ad6265SDimitry Andric                                         SourceLocation EndLoc,
624881ad6265SDimitry Andric                                         unsigned CollapsedNum)
624981ad6265SDimitry Andric       : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass,
625081ad6265SDimitry Andric                          llvm::omp::OMPD_target_parallel_loop, StartLoc, EndLoc,
625181ad6265SDimitry Andric                          CollapsedNum) {}
625281ad6265SDimitry Andric 
625381ad6265SDimitry Andric   /// Build an empty directive.
625481ad6265SDimitry Andric   ///
625581ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
625681ad6265SDimitry Andric   ///
OMPTargetParallelGenericLoopDirective(unsigned CollapsedNum)625781ad6265SDimitry Andric   explicit OMPTargetParallelGenericLoopDirective(unsigned CollapsedNum)
625881ad6265SDimitry Andric       : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass,
625981ad6265SDimitry Andric                          llvm::omp::OMPD_target_parallel_loop, SourceLocation(),
626081ad6265SDimitry Andric                          SourceLocation(), CollapsedNum) {}
626181ad6265SDimitry Andric 
626281ad6265SDimitry Andric public:
626381ad6265SDimitry Andric   /// Creates directive with a list of \p Clauses.
626481ad6265SDimitry Andric   ///
626581ad6265SDimitry Andric   /// \param C AST context.
626681ad6265SDimitry Andric   /// \param StartLoc Starting location of the directive kind.
626781ad6265SDimitry Andric   /// \param EndLoc Ending Location of the directive.
626881ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed loops.
626981ad6265SDimitry Andric   /// \param Clauses List of clauses.
627081ad6265SDimitry Andric   /// \param AssociatedStmt Statement, associated with the directive.
627181ad6265SDimitry Andric   /// \param Exprs Helper expressions for CodeGen.
627281ad6265SDimitry Andric   ///
627381ad6265SDimitry Andric   static OMPTargetParallelGenericLoopDirective *
627481ad6265SDimitry Andric   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
627581ad6265SDimitry Andric          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
627681ad6265SDimitry Andric          Stmt *AssociatedStmt, const HelperExprs &Exprs);
627781ad6265SDimitry Andric 
627881ad6265SDimitry Andric   /// Creates an empty directive with the place
627981ad6265SDimitry Andric   /// for \a NumClauses clauses.
628081ad6265SDimitry Andric   ///
628181ad6265SDimitry Andric   /// \param C AST context.
628281ad6265SDimitry Andric   /// \param CollapsedNum Number of collapsed nested loops.
628381ad6265SDimitry Andric   /// \param NumClauses Number of clauses.
628481ad6265SDimitry Andric   ///
628581ad6265SDimitry Andric   static OMPTargetParallelGenericLoopDirective *
628681ad6265SDimitry Andric   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
628781ad6265SDimitry Andric               EmptyShell);
628881ad6265SDimitry Andric 
classof(const Stmt * T)628981ad6265SDimitry Andric   static bool classof(const Stmt *T) {
629081ad6265SDimitry Andric     return T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass;
629181ad6265SDimitry Andric   }
629281ad6265SDimitry Andric };
6293bdd1243dSDimitry Andric 
6294bdd1243dSDimitry Andric /// This represents '#pragma omp error' directive.
6295bdd1243dSDimitry Andric ///
6296bdd1243dSDimitry Andric /// \code
6297bdd1243dSDimitry Andric /// #pragma omp error
6298bdd1243dSDimitry Andric /// \endcode
6299bdd1243dSDimitry Andric class OMPErrorDirective final : public OMPExecutableDirective {
6300bdd1243dSDimitry Andric   friend class ASTStmtReader;
6301bdd1243dSDimitry Andric   friend class OMPExecutableDirective;
6302bdd1243dSDimitry Andric   /// Build directive with the given start and end location.
6303bdd1243dSDimitry Andric   ///
6304bdd1243dSDimitry Andric   /// \param StartLoc Starting location of the directive kind.
6305bdd1243dSDimitry Andric   /// \param EndLoc Ending location of the directive.
6306bdd1243dSDimitry Andric   ///
OMPErrorDirective(SourceLocation StartLoc,SourceLocation EndLoc)6307bdd1243dSDimitry Andric   OMPErrorDirective(SourceLocation StartLoc, SourceLocation EndLoc)
6308bdd1243dSDimitry Andric       : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error,
6309bdd1243dSDimitry Andric                                StartLoc, EndLoc) {}
6310bdd1243dSDimitry Andric   /// Build an empty directive.
6311bdd1243dSDimitry Andric   ///
OMPErrorDirective()6312bdd1243dSDimitry Andric   explicit OMPErrorDirective()
6313bdd1243dSDimitry Andric       : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error,
6314bdd1243dSDimitry Andric                                SourceLocation(), SourceLocation()) {}
6315bdd1243dSDimitry Andric 
6316bdd1243dSDimitry Andric public:
6317bdd1243dSDimitry Andric   ///
6318bdd1243dSDimitry Andric   /// \param C AST context.
6319bdd1243dSDimitry Andric   /// \param StartLoc Starting location of the directive kind.
6320bdd1243dSDimitry Andric   /// \param EndLoc Ending Location of the directive.
6321bdd1243dSDimitry Andric   /// \param Clauses List of clauses.
6322bdd1243dSDimitry Andric   ///
6323bdd1243dSDimitry Andric   static OMPErrorDirective *Create(const ASTContext &C, SourceLocation StartLoc,
6324bdd1243dSDimitry Andric                                    SourceLocation EndLoc,
6325bdd1243dSDimitry Andric                                    ArrayRef<OMPClause *> Clauses);
6326bdd1243dSDimitry Andric 
6327bdd1243dSDimitry Andric   /// Creates an empty directive.
6328bdd1243dSDimitry Andric   ///
6329bdd1243dSDimitry Andric   /// \param C AST context.
6330bdd1243dSDimitry Andric   ///
6331bdd1243dSDimitry Andric   static OMPErrorDirective *CreateEmpty(const ASTContext &C,
6332bdd1243dSDimitry Andric                                         unsigned NumClauses, EmptyShell);
6333bdd1243dSDimitry Andric 
classof(const Stmt * T)6334bdd1243dSDimitry Andric   static bool classof(const Stmt *T) {
6335bdd1243dSDimitry Andric     return T->getStmtClass() == OMPErrorDirectiveClass;
6336bdd1243dSDimitry Andric   }
6337bdd1243dSDimitry Andric };
63380b57cec5SDimitry Andric } // end namespace clang
63390b57cec5SDimitry Andric 
63400b57cec5SDimitry Andric #endif
6341