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