1 //===- StmtOpenMP.h - Classes for OpenMP directives ------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 /// This file defines OpenMP AST classes for executable directives and
12 //===----------------------------------------------------------------------===//
14 #ifndef LLVM_CLANG_AST_STMTOPENMP_H
15 #define LLVM_CLANG_AST_STMTOPENMP_H
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"
27 //===----------------------------------------------------------------------===//
28 // AST classes for directives.
29 //===----------------------------------------------------------------------===//
31 /// Representation of an OpenMP canonical loop.
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
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:
49 /// OMPLoopBasedDirective
50 /// [`- CapturedStmt ]
51 /// [ `- CapturedDecl]
52 /// ` OMPCanonicalLoop
53 /// `- ForStmt/CXXForRangeStmt
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:
65 /// ` OMPCanonicalLoop
66 /// `- ForStmt/CXXForRangeStmt
68 /// |- Leading in-between code (if any)
69 /// |- OMPCanonicalLoop
70 /// | `- ForStmt/CXXForRangeStmt
72 /// `- Trailing in-between code (if any)
74 /// The leading/trailing in-between code must not itself be a OMPCanonicalLoop
75 /// to avoid confusion which loop belongs to the nesting.
77 /// There are three different kinds of iteration variables for different
79 /// * Loop user variable: The user-accessible variable with different value for
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
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.
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
109 /// std::vector<std::string> Container{1,2,3};
110 /// for (std::string Str : Container)
113 /// which is syntactic sugar for approximately:
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;
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
129 /// [&](size_t &Result) { Result = __end - __begin; }
131 /// and the loop variable function is
133 /// [&,__begin](std::vector<std::string>::iterator &Result, size_t Logical) {
134 /// Result = __begin + Logical;
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
142 class OMPCanonicalLoop : public Stmt {
143 friend class ASTStmtReader;
144 friend class ASTStmtWriter;
146 /// Children of this AST node.
152 LastSubStmt = LOOPVAR_REF
156 /// This AST node's children.
157 Stmt *SubStmts[LastSubStmt + 1] = {};
159 OMPCanonicalLoop() : Stmt(StmtClass::OMPCanonicalLoopClass) {}
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);
175 /// Create an empty OMPCanonicalLoop for deserialization.
176 static OMPCanonicalLoop *createEmpty(const ASTContext &Ctx) {
177 return new (Ctx) OMPCanonicalLoop();
180 static bool classof(const Stmt *S) {
181 return S->getStmtClass() == StmtClass::OMPCanonicalLoopClass;
184 SourceLocation getBeginLoc() const { return getLoopStmt()->getBeginLoc(); }
185 SourceLocation getEndLoc() const { return getLoopStmt()->getEndLoc(); }
187 /// Return this AST node's children.
189 child_range children() {
190 return child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1);
192 const_child_range children() const {
193 return const_child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1);
197 /// The wrapped syntactic loop statement (ForStmt or CXXForRangeStmt).
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;
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
212 /// Function signature: void(LogicalTy &Result)
213 /// Any values necessary to compute the distance are captures of the closure.
215 CapturedStmt *getDistanceFunc() {
216 return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]);
218 const CapturedStmt *getDistanceFunc() const {
219 return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]);
221 void setDistanceFunc(CapturedStmt *S) {
222 assert(S && "Expected non-null captured statement");
223 SubStmts[DISTANCE_FUNC] = S;
227 /// The function that computes the loop user variable from a logical iteration
228 /// counter. Can be evaluated as first statement in the loop.
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.
236 CapturedStmt *getLoopVarFunc() {
237 return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]);
239 const CapturedStmt *getLoopVarFunc() const {
240 return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]);
242 void setLoopVarFunc(CapturedStmt *S) {
243 assert(S && "Expected non-null captured statement");
244 SubStmts[LOOPVAR_FUNC] = S;
248 /// Reference to the loop user variable as accessed in the loop body.
250 DeclRefExpr *getLoopVarRef() {
251 return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]);
253 const DeclRefExpr *getLoopVarRef() const {
254 return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]);
256 void setLoopVarRef(DeclRefExpr *E) {
257 assert(E && "Expected non-null loop variable");
258 SubStmts[LOOPVAR_REF] = E;
263 /// This is a basic class for representing single OpenMP executable
266 class OMPExecutableDirective : public Stmt {
267 friend class ASTStmtReader;
268 friend class ASTStmtWriter;
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;
277 /// Get the clauses storage.
278 MutableArrayRef<OMPClause *> getClauses() {
281 return Data->getClauses();
285 /// Data, associated with the directive.
286 OMPChildren *Data = nullptr;
288 /// Build instance of directive of class \a K.
290 /// \param SC Statement class.
291 /// \param K Kind of OpenMP directive.
292 /// \param StartLoc Starting location of the directive (directive keyword).
293 /// \param EndLoc Ending location of the directive.
295 OMPExecutableDirective(StmtClass SC, OpenMPDirectiveKind K,
296 SourceLocation StartLoc, SourceLocation EndLoc)
297 : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
298 EndLoc(std::move(EndLoc)) {}
300 template <typename T, typename... Params>
301 static T *createDirective(const ASTContext &C, ArrayRef<OMPClause *> Clauses,
302 Stmt *AssociatedStmt, unsigned NumChildren,
305 C.Allocate(sizeof(T) + OMPChildren::size(Clauses.size(), AssociatedStmt,
309 auto *Data = OMPChildren::Create(reinterpret_cast<T *>(Mem) + 1, Clauses,
310 AssociatedStmt, NumChildren);
311 auto *Inst = new (Mem) T(std::forward<Params>(P)...);
316 template <typename T, typename... Params>
317 static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses,
318 bool HasAssociatedStmt, unsigned NumChildren,
321 C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt,
325 OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses,
326 HasAssociatedStmt, NumChildren);
327 auto *Inst = new (Mem) T(std::forward<Params>(P)...);
332 template <typename T>
333 static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses,
334 bool HasAssociatedStmt = false,
335 unsigned NumChildren = 0) {
337 C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt,
341 OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses,
342 HasAssociatedStmt, NumChildren);
343 auto *Inst = new (Mem) T;
349 /// Iterates over expressions/statements used in the construct.
350 class used_clauses_child_iterator
351 : public llvm::iterator_adaptor_base<
352 used_clauses_child_iterator, ArrayRef<OMPClause *>::iterator,
353 std::forward_iterator_tag, Stmt *, ptrdiff_t, Stmt *, Stmt *> {
354 ArrayRef<OMPClause *>::iterator End;
355 OMPClause::child_iterator ChildI, ChildEnd;
358 if (ChildI != ChildEnd)
360 while (this->I != End) {
362 if (this->I != End) {
363 ChildI = (*this->I)->used_children().begin();
364 ChildEnd = (*this->I)->used_children().end();
365 if (ChildI != ChildEnd)
372 explicit used_clauses_child_iterator(ArrayRef<OMPClause *> Clauses)
373 : used_clauses_child_iterator::iterator_adaptor_base(Clauses.begin()),
375 if (this->I != End) {
376 ChildI = (*this->I)->used_children().begin();
377 ChildEnd = (*this->I)->used_children().end();
381 Stmt *operator*() const { return *ChildI; }
382 Stmt *operator->() const { return **this; }
384 used_clauses_child_iterator &operator++() {
386 if (ChildI != ChildEnd)
388 if (this->I != End) {
390 if (this->I != End) {
391 ChildI = (*this->I)->used_children().begin();
392 ChildEnd = (*this->I)->used_children().end();
400 static llvm::iterator_range<used_clauses_child_iterator>
401 used_clauses_children(ArrayRef<OMPClause *> Clauses) {
402 return {used_clauses_child_iterator(Clauses),
403 used_clauses_child_iterator(llvm::makeArrayRef(Clauses.end(), 0))};
406 /// Iterates over a filtered subrange of clauses applied to a
409 /// This iterator visits only clauses of type SpecificClause.
410 template <typename SpecificClause>
411 class specific_clause_iterator
412 : public llvm::iterator_adaptor_base<
413 specific_clause_iterator<SpecificClause>,
414 ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag,
415 const SpecificClause *, ptrdiff_t, const SpecificClause *,
416 const SpecificClause *> {
417 ArrayRef<OMPClause *>::const_iterator End;
419 void SkipToNextClause() {
420 while (this->I != End && !isa<SpecificClause>(*this->I))
425 explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses)
426 : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()),
431 const SpecificClause *operator*() const {
432 return cast<SpecificClause>(*this->I);
434 const SpecificClause *operator->() const { return **this; }
436 specific_clause_iterator &operator++() {
443 template <typename SpecificClause>
444 static llvm::iterator_range<specific_clause_iterator<SpecificClause>>
445 getClausesOfKind(ArrayRef<OMPClause *> Clauses) {
446 return {specific_clause_iterator<SpecificClause>(Clauses),
447 specific_clause_iterator<SpecificClause>(
448 llvm::makeArrayRef(Clauses.end(), 0))};
451 template <typename SpecificClause>
452 llvm::iterator_range<specific_clause_iterator<SpecificClause>>
453 getClausesOfKind() const {
454 return getClausesOfKind<SpecificClause>(clauses());
457 /// Gets a single clause of the specified kind associated with the
458 /// current directive iff there is only one clause of this kind (and assertion
459 /// is fired if there is more than one clause is associated with the
460 /// directive). Returns nullptr if no clause of this kind is associated with
462 template <typename SpecificClause>
463 static const SpecificClause *getSingleClause(ArrayRef<OMPClause *> Clauses) {
464 auto ClausesOfKind = getClausesOfKind<SpecificClause>(Clauses);
466 if (ClausesOfKind.begin() != ClausesOfKind.end()) {
467 assert(std::next(ClausesOfKind.begin()) == ClausesOfKind.end() &&
468 "There are at least 2 clauses of the specified kind");
469 return *ClausesOfKind.begin();
474 template <typename SpecificClause>
475 const SpecificClause *getSingleClause() const {
476 return getSingleClause<SpecificClause>(clauses());
479 /// Returns true if the current directive has one or more clauses of a
481 template <typename SpecificClause>
482 bool hasClausesOfKind() const {
483 auto Clauses = getClausesOfKind<SpecificClause>();
484 return Clauses.begin() != Clauses.end();
487 /// Returns starting location of directive kind.
488 SourceLocation getBeginLoc() const { return StartLoc; }
489 /// Returns ending location of directive.
490 SourceLocation getEndLoc() const { return EndLoc; }
492 /// Set starting location of directive kind.
494 /// \param Loc New starting location of directive.
496 void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
497 /// Set ending location of directive.
499 /// \param Loc New ending location of directive.
501 void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
503 /// Get number of clauses.
504 unsigned getNumClauses() const {
507 return Data->getNumClauses();
510 /// Returns specified clause.
512 /// \param I Number of clause.
514 OMPClause *getClause(unsigned I) const { return clauses()[I]; }
516 /// Returns true if directive has associated statement.
517 bool hasAssociatedStmt() const { return Data && Data->hasAssociatedStmt(); }
519 /// Returns statement associated with the directive.
520 const Stmt *getAssociatedStmt() const {
521 return const_cast<OMPExecutableDirective *>(this)->getAssociatedStmt();
523 Stmt *getAssociatedStmt() {
524 assert(hasAssociatedStmt() &&
525 "Expected directive with the associated statement.");
526 return Data->getAssociatedStmt();
529 /// Returns the captured statement associated with the
530 /// component region within the (combined) directive.
532 /// \param RegionKind Component region kind.
533 const CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const {
534 assert(hasAssociatedStmt() &&
535 "Expected directive with the associated statement.");
536 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
537 getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
538 return Data->getCapturedStmt(RegionKind, CaptureRegions);
541 /// Get innermost captured statement for the construct.
542 CapturedStmt *getInnermostCapturedStmt() {
543 assert(hasAssociatedStmt() &&
544 "Expected directive with the associated statement.");
545 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
546 getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
547 return Data->getInnermostCapturedStmt(CaptureRegions);
550 const CapturedStmt *getInnermostCapturedStmt() const {
551 return const_cast<OMPExecutableDirective *>(this)
552 ->getInnermostCapturedStmt();
555 OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
557 static bool classof(const Stmt *S) {
558 return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
559 S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
562 child_range children() {
564 return child_range(child_iterator(), child_iterator());
565 return Data->getAssociatedStmtAsRange();
568 const_child_range children() const {
569 return const_cast<OMPExecutableDirective *>(this)->children();
572 ArrayRef<OMPClause *> clauses() const {
575 return Data->getClauses();
578 /// Returns whether or not this is a Standalone directive.
580 /// Stand-alone directives are executable directives
581 /// that have no associated user code.
582 bool isStandaloneDirective() const;
584 /// Returns the AST node representing OpenMP structured-block of this
585 /// OpenMP executable directive,
586 /// Prerequisite: Executable Directive must not be Standalone directive.
587 const Stmt *getStructuredBlock() const {
588 return const_cast<OMPExecutableDirective *>(this)->getStructuredBlock();
590 Stmt *getStructuredBlock();
592 const Stmt *getRawStmt() const {
593 return const_cast<OMPExecutableDirective *>(this)->getRawStmt();
596 assert(hasAssociatedStmt() &&
597 "Expected directive with the associated statement.");
598 return Data->getRawStmt();
602 /// This represents '#pragma omp parallel' directive.
605 /// #pragma omp parallel private(a,b) reduction(+: c,d)
607 /// In this example directive '#pragma omp parallel' has clauses 'private'
608 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
609 /// variables 'c' and 'd'.
611 class OMPParallelDirective : public OMPExecutableDirective {
612 friend class ASTStmtReader;
613 friend class OMPExecutableDirective;
614 /// true if the construct has inner cancel directive.
615 bool HasCancel = false;
617 /// Build directive with the given start and end location.
619 /// \param StartLoc Starting location of the directive (directive keyword).
620 /// \param EndLoc Ending Location of the directive.
622 OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc)
623 : OMPExecutableDirective(OMPParallelDirectiveClass,
624 llvm::omp::OMPD_parallel, StartLoc, EndLoc) {}
626 /// Build an empty directive.
628 explicit OMPParallelDirective()
629 : OMPExecutableDirective(OMPParallelDirectiveClass,
630 llvm::omp::OMPD_parallel, SourceLocation(),
633 /// Sets special task reduction descriptor.
634 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
636 /// Set cancel state.
637 void setHasCancel(bool Has) { HasCancel = Has; }
640 /// Creates directive with a list of \a Clauses.
642 /// \param C AST context.
643 /// \param StartLoc Starting location of the directive kind.
644 /// \param EndLoc Ending Location of the directive.
645 /// \param Clauses List of clauses.
646 /// \param AssociatedStmt Statement associated with the directive.
647 /// \param TaskRedRef Task reduction special reference expression to handle
648 /// taskgroup descriptor.
649 /// \param HasCancel true if this directive has inner cancel directive.
651 static OMPParallelDirective *
652 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
653 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
656 /// Creates an empty directive with the place for \a N clauses.
658 /// \param C AST context.
659 /// \param NumClauses Number of clauses.
661 static OMPParallelDirective *CreateEmpty(const ASTContext &C,
662 unsigned NumClauses, EmptyShell);
664 /// Returns special task reduction reference expression.
665 Expr *getTaskReductionRefExpr() {
666 return cast_or_null<Expr>(Data->getChildren()[0]);
668 const Expr *getTaskReductionRefExpr() const {
669 return const_cast<OMPParallelDirective *>(this)->getTaskReductionRefExpr();
672 /// Return true if current directive has inner cancel directive.
673 bool hasCancel() const { return HasCancel; }
675 static bool classof(const Stmt *T) {
676 return T->getStmtClass() == OMPParallelDirectiveClass;
680 /// The base class for all loop-based directives, including loop transformation
682 class OMPLoopBasedDirective : public OMPExecutableDirective {
683 friend class ASTStmtReader;
686 /// Number of collapsed loops as specified by 'collapse' clause.
687 unsigned NumAssociatedLoops = 0;
689 /// Build instance of loop directive of class \a Kind.
691 /// \param SC Statement class.
692 /// \param Kind Kind of OpenMP directive.
693 /// \param StartLoc Starting location of the directive (directive keyword).
694 /// \param EndLoc Ending location of the directive.
695 /// \param NumAssociatedLoops Number of loops associated with the construct.
697 OMPLoopBasedDirective(StmtClass SC, OpenMPDirectiveKind Kind,
698 SourceLocation StartLoc, SourceLocation EndLoc,
699 unsigned NumAssociatedLoops)
700 : OMPExecutableDirective(SC, Kind, StartLoc, EndLoc),
701 NumAssociatedLoops(NumAssociatedLoops) {}
704 /// The expressions built to support OpenMP loops in combined/composite
705 /// pragmas (e.g. pragma omp distribute parallel for)
706 struct DistCombinedHelperExprs {
707 /// DistributeLowerBound - used when composing 'omp distribute' with
708 /// 'omp for' in a same construct.
710 /// DistributeUpperBound - used when composing 'omp distribute' with
711 /// 'omp for' in a same construct.
713 /// DistributeEnsureUpperBound - used when composing 'omp distribute'
714 /// with 'omp for' in a same construct, EUB depends on DistUB
716 /// Distribute loop iteration variable init used when composing 'omp
718 /// with 'omp for' in a same construct
720 /// Distribute Loop condition used when composing 'omp distribute'
721 /// with 'omp for' in a same construct
723 /// Update of LowerBound for statically scheduled omp loops for
724 /// outer loop in combined constructs (e.g. 'distribute parallel for')
726 /// Update of UpperBound for statically scheduled omp loops for
727 /// outer loop in combined constructs (e.g. 'distribute parallel for')
729 /// Distribute Loop condition used when composing 'omp distribute'
730 /// with 'omp for' in a same construct when schedule is chunked.
732 /// 'omp parallel for' loop condition used when composed with
733 /// 'omp distribute' in the same construct and when schedule is
734 /// chunked and the chunk size is 1.
735 Expr *ParForInDistCond;
738 /// The expressions built for the OpenMP loop CodeGen for the
739 /// whole collapsed loop nest.
741 /// Loop iteration variable.
742 Expr *IterationVarRef;
743 /// Loop last iteration number.
745 /// Loop number of iterations.
747 /// Calculation of last iteration.
748 Expr *CalcLastIteration;
749 /// Loop pre-condition.
753 /// Loop iteration variable init.
757 /// IsLastIteration - local flag variable passed to runtime.
759 /// LowerBound - local variable passed to runtime.
761 /// UpperBound - local variable passed to runtime.
763 /// Stride - local variable passed to runtime.
765 /// EnsureUpperBound -- expression UB = min(UB, NumIterations).
767 /// Update of LowerBound for statically scheduled 'omp for' loops.
769 /// Update of UpperBound for statically scheduled 'omp for' loops.
771 /// PreviousLowerBound - local variable passed to runtime in the
772 /// enclosing schedule or null if that does not apply.
774 /// PreviousUpperBound - local variable passed to runtime in the
775 /// enclosing schedule or null if that does not apply.
777 /// DistInc - increment expression for distribute loop when found
778 /// combined with a further loop level (e.g. in 'distribute parallel for')
779 /// expression IV = IV + ST
781 /// PrevEUB - expression similar to EUB but to be used when loop
782 /// scheduling uses PrevLB and PrevUB (e.g. in 'distribute parallel for'
783 /// when ensuring that the UB is either the calculated UB by the runtime or
784 /// the end of the assigned distribute chunk)
785 /// expression UB = min (UB, PrevUB)
787 /// Counters Loop counters.
788 SmallVector<Expr *, 4> Counters;
789 /// PrivateCounters Loop counters.
790 SmallVector<Expr *, 4> PrivateCounters;
791 /// Expressions for loop counters inits for CodeGen.
792 SmallVector<Expr *, 4> Inits;
793 /// Expressions for loop counters update for CodeGen.
794 SmallVector<Expr *, 4> Updates;
795 /// Final loop counter values for GodeGen.
796 SmallVector<Expr *, 4> Finals;
797 /// List of counters required for the generation of the non-rectangular
799 SmallVector<Expr *, 4> DependentCounters;
800 /// List of initializers required for the generation of the non-rectangular
802 SmallVector<Expr *, 4> DependentInits;
803 /// List of final conditions required for the generation of the
804 /// non-rectangular loops.
805 SmallVector<Expr *, 4> FinalsConditions;
806 /// Init statement for all captured expressions.
809 /// Expressions used when combining OpenMP loop pragmas
810 DistCombinedHelperExprs DistCombinedFields;
812 /// Check if all the expressions are built (does not check the
813 /// worksharing ones).
815 return IterationVarRef != nullptr && LastIteration != nullptr &&
816 NumIterations != nullptr && PreCond != nullptr &&
817 Cond != nullptr && Init != nullptr && Inc != nullptr;
820 /// Initialize all the fields to null.
821 /// \param Size Number of elements in the
822 /// counters/finals/updates/dependent_counters/dependent_inits/finals_conditions
824 void clear(unsigned Size) {
825 IterationVarRef = nullptr;
826 LastIteration = nullptr;
827 CalcLastIteration = nullptr;
839 NumIterations = nullptr;
844 Counters.resize(Size);
845 PrivateCounters.resize(Size);
847 Updates.resize(Size);
849 DependentCounters.resize(Size);
850 DependentInits.resize(Size);
851 FinalsConditions.resize(Size);
852 for (unsigned I = 0; I < Size; ++I) {
853 Counters[I] = nullptr;
854 PrivateCounters[I] = nullptr;
856 Updates[I] = nullptr;
858 DependentCounters[I] = nullptr;
859 DependentInits[I] = nullptr;
860 FinalsConditions[I] = nullptr;
863 DistCombinedFields.LB = nullptr;
864 DistCombinedFields.UB = nullptr;
865 DistCombinedFields.EUB = nullptr;
866 DistCombinedFields.Init = nullptr;
867 DistCombinedFields.Cond = nullptr;
868 DistCombinedFields.NLB = nullptr;
869 DistCombinedFields.NUB = nullptr;
870 DistCombinedFields.DistCond = nullptr;
871 DistCombinedFields.ParForInDistCond = nullptr;
875 /// Get number of collapsed loops.
876 unsigned getLoopsNumber() const { return NumAssociatedLoops; }
878 /// Try to find the next loop sub-statement in the specified statement \p
880 /// \param TryImperfectlyNestedLoops true, if we need to try to look for the
881 /// imperfectly nested loop.
882 static Stmt *tryToFindNextInnerLoop(Stmt *CurStmt,
883 bool TryImperfectlyNestedLoops);
884 static const Stmt *tryToFindNextInnerLoop(const Stmt *CurStmt,
885 bool TryImperfectlyNestedLoops) {
886 return tryToFindNextInnerLoop(const_cast<Stmt *>(CurStmt),
887 TryImperfectlyNestedLoops);
890 /// Calls the specified callback function for all the loops in \p CurStmt,
891 /// from the outermost to the innermost.
892 static bool doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
894 llvm::function_ref<bool(unsigned, Stmt *)> Callback,
895 llvm::function_ref<void(OMPLoopBasedDirective *)>
896 OnTransformationCallback);
898 doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
900 llvm::function_ref<bool(unsigned, const Stmt *)> Callback,
901 llvm::function_ref<void(const OMPLoopBasedDirective *)>
902 OnTransformationCallback) {
903 auto &&NewCallback = [Callback](unsigned Cnt, Stmt *CurStmt) {
904 return Callback(Cnt, CurStmt);
906 auto &&NewTransformCb =
907 [OnTransformationCallback](OMPLoopBasedDirective *A) {
908 OnTransformationCallback(A);
910 return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
911 NumLoops, NewCallback, NewTransformCb);
914 /// Calls the specified callback function for all the loops in \p CurStmt,
915 /// from the outermost to the innermost.
917 doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
919 llvm::function_ref<bool(unsigned, Stmt *)> Callback) {
920 auto &&TransformCb = [](OMPLoopBasedDirective *) {};
921 return doForAllLoops(CurStmt, TryImperfectlyNestedLoops, NumLoops, Callback,
925 doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
927 llvm::function_ref<bool(unsigned, const Stmt *)> Callback) {
928 auto &&NewCallback = [Callback](unsigned Cnt, const Stmt *CurStmt) {
929 return Callback(Cnt, CurStmt);
931 return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
932 NumLoops, NewCallback);
935 /// Calls the specified callback function for all the loop bodies in \p
936 /// CurStmt, from the outermost loop to the innermost.
937 static void doForAllLoopsBodies(
938 Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops,
939 llvm::function_ref<void(unsigned, Stmt *, Stmt *)> Callback);
940 static void doForAllLoopsBodies(
941 const Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops,
942 llvm::function_ref<void(unsigned, const Stmt *, const Stmt *)> Callback) {
943 auto &&NewCallback = [Callback](unsigned Cnt, Stmt *Loop, Stmt *Body) {
944 Callback(Cnt, Loop, Body);
946 doForAllLoopsBodies(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
947 NumLoops, NewCallback);
950 static bool classof(const Stmt *T) {
951 if (auto *D = dyn_cast<OMPExecutableDirective>(T))
952 return isOpenMPLoopDirective(D->getDirectiveKind());
957 /// This is a common base class for loop directives ('omp simd', 'omp
958 /// for', 'omp for simd' etc.). It is responsible for the loop code generation.
960 class OMPLoopDirective : public OMPLoopBasedDirective {
961 friend class ASTStmtReader;
963 /// Offsets to the stored exprs.
964 /// This enumeration contains offsets to all the pointers to children
965 /// expressions stored in OMPLoopDirective.
966 /// The first 9 children are necessary for all the loop directives,
967 /// the next 8 are specific to the worksharing ones, and the next 11 are
968 /// used for combined constructs containing two pragmas associated to loops.
969 /// After the fixed children, three arrays of length NumAssociatedLoops are
970 /// allocated: loop counters, their updates and final values.
971 /// PrevLowerBound and PrevUpperBound are used to communicate blocking
972 /// information in composite constructs which require loop blocking
973 /// DistInc is used to generate the increment expression for the distribute
974 /// loop when combined with a further nested loop
975 /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the
976 /// for loop when combined with a previous distribute loop in the same pragma
977 /// (e.g. 'distribute parallel for')
980 IterationVariableOffset = 0,
981 LastIterationOffset = 1,
982 CalcLastIterationOffset = 2,
983 PreConditionOffset = 3,
988 // The '...End' enumerators do not correspond to child expressions - they
989 // specify the offset to the end (and start of the following counters/
990 // updates/finals/dependent_counters/dependent_inits/finals_conditions
993 // The following 8 exprs are used by worksharing and distribute loops only.
994 IsLastIterVariableOffset = 8,
995 LowerBoundVariableOffset = 9,
996 UpperBoundVariableOffset = 10,
997 StrideVariableOffset = 11,
998 EnsureUpperBoundOffset = 12,
999 NextLowerBoundOffset = 13,
1000 NextUpperBoundOffset = 14,
1001 NumIterationsOffset = 15,
1002 // Offset to the end for worksharing loop directives.
1003 WorksharingEnd = 16,
1004 PrevLowerBoundVariableOffset = 16,
1005 PrevUpperBoundVariableOffset = 17,
1007 PrevEnsureUpperBoundOffset = 19,
1008 CombinedLowerBoundVariableOffset = 20,
1009 CombinedUpperBoundVariableOffset = 21,
1010 CombinedEnsureUpperBoundOffset = 22,
1011 CombinedInitOffset = 23,
1012 CombinedConditionOffset = 24,
1013 CombinedNextLowerBoundOffset = 25,
1014 CombinedNextUpperBoundOffset = 26,
1015 CombinedDistConditionOffset = 27,
1016 CombinedParForInDistConditionOffset = 28,
1017 // Offset to the end (and start of the following
1018 // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions
1019 // arrays) for combined distribute loop directives.
1020 CombinedDistributeEnd = 29,
1023 /// Get the counters storage.
1024 MutableArrayRef<Expr *> getCounters() {
1025 auto **Storage = reinterpret_cast<Expr **>(
1026 &Data->getChildren()[getArraysOffset(getDirectiveKind())]);
1027 return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
1030 /// Get the private counters storage.
1031 MutableArrayRef<Expr *> getPrivateCounters() {
1032 auto **Storage = reinterpret_cast<Expr **>(
1033 &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1035 return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
1038 /// Get the updates storage.
1039 MutableArrayRef<Expr *> getInits() {
1040 auto **Storage = reinterpret_cast<Expr **>(
1041 &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1042 2 * getLoopsNumber()]);
1043 return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
1046 /// Get the updates storage.
1047 MutableArrayRef<Expr *> getUpdates() {
1048 auto **Storage = reinterpret_cast<Expr **>(
1049 &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1050 3 * getLoopsNumber()]);
1051 return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
1054 /// Get the final counter updates storage.
1055 MutableArrayRef<Expr *> getFinals() {
1056 auto **Storage = reinterpret_cast<Expr **>(
1057 &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1058 4 * getLoopsNumber()]);
1059 return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
1062 /// Get the dependent counters storage.
1063 MutableArrayRef<Expr *> getDependentCounters() {
1064 auto **Storage = reinterpret_cast<Expr **>(
1065 &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1066 5 * getLoopsNumber()]);
1067 return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
1070 /// Get the dependent inits storage.
1071 MutableArrayRef<Expr *> getDependentInits() {
1072 auto **Storage = reinterpret_cast<Expr **>(
1073 &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1074 6 * getLoopsNumber()]);
1075 return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
1078 /// Get the finals conditions storage.
1079 MutableArrayRef<Expr *> getFinalsConditions() {
1080 auto **Storage = reinterpret_cast<Expr **>(
1081 &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1082 7 * getLoopsNumber()]);
1083 return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
1087 /// Build instance of loop directive of class \a Kind.
1089 /// \param SC Statement class.
1090 /// \param Kind Kind of OpenMP directive.
1091 /// \param StartLoc Starting location of the directive (directive keyword).
1092 /// \param EndLoc Ending location of the directive.
1093 /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
1095 OMPLoopDirective(StmtClass SC, OpenMPDirectiveKind Kind,
1096 SourceLocation StartLoc, SourceLocation EndLoc,
1097 unsigned CollapsedNum)
1098 : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, CollapsedNum) {}
1100 /// Offset to the start of children expression arrays.
1101 static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
1102 if (isOpenMPLoopBoundSharingDirective(Kind))
1103 return CombinedDistributeEnd;
1104 if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) ||
1105 isOpenMPDistributeDirective(Kind))
1106 return WorksharingEnd;
1110 /// Children number.
1111 static unsigned numLoopChildren(unsigned CollapsedNum,
1112 OpenMPDirectiveKind Kind) {
1113 return getArraysOffset(Kind) +
1114 8 * CollapsedNum; // Counters, PrivateCounters, Inits,
1115 // Updates, Finals, DependentCounters,
1116 // DependentInits, FinalsConditions.
1119 void setIterationVariable(Expr *IV) {
1120 Data->getChildren()[IterationVariableOffset] = IV;
1122 void setLastIteration(Expr *LI) {
1123 Data->getChildren()[LastIterationOffset] = LI;
1125 void setCalcLastIteration(Expr *CLI) {
1126 Data->getChildren()[CalcLastIterationOffset] = CLI;
1128 void setPreCond(Expr *PC) { Data->getChildren()[PreConditionOffset] = PC; }
1129 void setCond(Expr *Cond) { Data->getChildren()[CondOffset] = Cond; }
1130 void setInit(Expr *Init) { Data->getChildren()[InitOffset] = Init; }
1131 void setInc(Expr *Inc) { Data->getChildren()[IncOffset] = Inc; }
1132 void setPreInits(Stmt *PreInits) {
1133 Data->getChildren()[PreInitsOffset] = PreInits;
1135 void setIsLastIterVariable(Expr *IL) {
1136 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1137 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1138 isOpenMPDistributeDirective(getDirectiveKind())) &&
1139 "expected worksharing loop directive");
1140 Data->getChildren()[IsLastIterVariableOffset] = IL;
1142 void setLowerBoundVariable(Expr *LB) {
1143 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1144 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1145 isOpenMPDistributeDirective(getDirectiveKind())) &&
1146 "expected worksharing loop directive");
1147 Data->getChildren()[LowerBoundVariableOffset] = LB;
1149 void setUpperBoundVariable(Expr *UB) {
1150 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1151 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1152 isOpenMPDistributeDirective(getDirectiveKind())) &&
1153 "expected worksharing loop directive");
1154 Data->getChildren()[UpperBoundVariableOffset] = UB;
1156 void setStrideVariable(Expr *ST) {
1157 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1158 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1159 isOpenMPDistributeDirective(getDirectiveKind())) &&
1160 "expected worksharing loop directive");
1161 Data->getChildren()[StrideVariableOffset] = ST;
1163 void setEnsureUpperBound(Expr *EUB) {
1164 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1165 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1166 isOpenMPDistributeDirective(getDirectiveKind())) &&
1167 "expected worksharing loop directive");
1168 Data->getChildren()[EnsureUpperBoundOffset] = EUB;
1170 void setNextLowerBound(Expr *NLB) {
1171 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1172 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1173 isOpenMPDistributeDirective(getDirectiveKind())) &&
1174 "expected worksharing loop directive");
1175 Data->getChildren()[NextLowerBoundOffset] = NLB;
1177 void setNextUpperBound(Expr *NUB) {
1178 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1179 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1180 isOpenMPDistributeDirective(getDirectiveKind())) &&
1181 "expected worksharing loop directive");
1182 Data->getChildren()[NextUpperBoundOffset] = NUB;
1184 void setNumIterations(Expr *NI) {
1185 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1186 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1187 isOpenMPDistributeDirective(getDirectiveKind())) &&
1188 "expected worksharing loop directive");
1189 Data->getChildren()[NumIterationsOffset] = NI;
1191 void setPrevLowerBoundVariable(Expr *PrevLB) {
1192 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1193 "expected loop bound sharing directive");
1194 Data->getChildren()[PrevLowerBoundVariableOffset] = PrevLB;
1196 void setPrevUpperBoundVariable(Expr *PrevUB) {
1197 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1198 "expected loop bound sharing directive");
1199 Data->getChildren()[PrevUpperBoundVariableOffset] = PrevUB;
1201 void setDistInc(Expr *DistInc) {
1202 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1203 "expected loop bound sharing directive");
1204 Data->getChildren()[DistIncOffset] = DistInc;
1206 void setPrevEnsureUpperBound(Expr *PrevEUB) {
1207 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1208 "expected loop bound sharing directive");
1209 Data->getChildren()[PrevEnsureUpperBoundOffset] = PrevEUB;
1211 void setCombinedLowerBoundVariable(Expr *CombLB) {
1212 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1213 "expected loop bound sharing directive");
1214 Data->getChildren()[CombinedLowerBoundVariableOffset] = CombLB;
1216 void setCombinedUpperBoundVariable(Expr *CombUB) {
1217 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1218 "expected loop bound sharing directive");
1219 Data->getChildren()[CombinedUpperBoundVariableOffset] = CombUB;
1221 void setCombinedEnsureUpperBound(Expr *CombEUB) {
1222 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1223 "expected loop bound sharing directive");
1224 Data->getChildren()[CombinedEnsureUpperBoundOffset] = CombEUB;
1226 void setCombinedInit(Expr *CombInit) {
1227 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1228 "expected loop bound sharing directive");
1229 Data->getChildren()[CombinedInitOffset] = CombInit;
1231 void setCombinedCond(Expr *CombCond) {
1232 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1233 "expected loop bound sharing directive");
1234 Data->getChildren()[CombinedConditionOffset] = CombCond;
1236 void setCombinedNextLowerBound(Expr *CombNLB) {
1237 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1238 "expected loop bound sharing directive");
1239 Data->getChildren()[CombinedNextLowerBoundOffset] = CombNLB;
1241 void setCombinedNextUpperBound(Expr *CombNUB) {
1242 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1243 "expected loop bound sharing directive");
1244 Data->getChildren()[CombinedNextUpperBoundOffset] = CombNUB;
1246 void setCombinedDistCond(Expr *CombDistCond) {
1247 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1248 "expected loop bound distribute sharing directive");
1249 Data->getChildren()[CombinedDistConditionOffset] = CombDistCond;
1251 void setCombinedParForInDistCond(Expr *CombParForInDistCond) {
1252 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1253 "expected loop bound distribute sharing directive");
1254 Data->getChildren()[CombinedParForInDistConditionOffset] =
1255 CombParForInDistCond;
1257 void setCounters(ArrayRef<Expr *> A);
1258 void setPrivateCounters(ArrayRef<Expr *> A);
1259 void setInits(ArrayRef<Expr *> A);
1260 void setUpdates(ArrayRef<Expr *> A);
1261 void setFinals(ArrayRef<Expr *> A);
1262 void setDependentCounters(ArrayRef<Expr *> A);
1263 void setDependentInits(ArrayRef<Expr *> A);
1264 void setFinalsConditions(ArrayRef<Expr *> A);
1267 Expr *getIterationVariable() const {
1268 return cast<Expr>(Data->getChildren()[IterationVariableOffset]);
1270 Expr *getLastIteration() const {
1271 return cast<Expr>(Data->getChildren()[LastIterationOffset]);
1273 Expr *getCalcLastIteration() const {
1274 return cast<Expr>(Data->getChildren()[CalcLastIterationOffset]);
1276 Expr *getPreCond() const {
1277 return cast<Expr>(Data->getChildren()[PreConditionOffset]);
1279 Expr *getCond() const { return cast<Expr>(Data->getChildren()[CondOffset]); }
1280 Expr *getInit() const { return cast<Expr>(Data->getChildren()[InitOffset]); }
1281 Expr *getInc() const { return cast<Expr>(Data->getChildren()[IncOffset]); }
1282 const Stmt *getPreInits() const {
1283 return Data->getChildren()[PreInitsOffset];
1285 Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; }
1286 Expr *getIsLastIterVariable() const {
1287 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1288 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1289 isOpenMPDistributeDirective(getDirectiveKind())) &&
1290 "expected worksharing loop directive");
1291 return cast<Expr>(Data->getChildren()[IsLastIterVariableOffset]);
1293 Expr *getLowerBoundVariable() const {
1294 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1295 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1296 isOpenMPDistributeDirective(getDirectiveKind())) &&
1297 "expected worksharing loop directive");
1298 return cast<Expr>(Data->getChildren()[LowerBoundVariableOffset]);
1300 Expr *getUpperBoundVariable() const {
1301 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1302 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1303 isOpenMPDistributeDirective(getDirectiveKind())) &&
1304 "expected worksharing loop directive");
1305 return cast<Expr>(Data->getChildren()[UpperBoundVariableOffset]);
1307 Expr *getStrideVariable() const {
1308 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1309 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1310 isOpenMPDistributeDirective(getDirectiveKind())) &&
1311 "expected worksharing loop directive");
1312 return cast<Expr>(Data->getChildren()[StrideVariableOffset]);
1314 Expr *getEnsureUpperBound() const {
1315 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1316 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1317 isOpenMPDistributeDirective(getDirectiveKind())) &&
1318 "expected worksharing loop directive");
1319 return cast<Expr>(Data->getChildren()[EnsureUpperBoundOffset]);
1321 Expr *getNextLowerBound() const {
1322 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1323 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1324 isOpenMPDistributeDirective(getDirectiveKind())) &&
1325 "expected worksharing loop directive");
1326 return cast<Expr>(Data->getChildren()[NextLowerBoundOffset]);
1328 Expr *getNextUpperBound() const {
1329 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1330 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1331 isOpenMPDistributeDirective(getDirectiveKind())) &&
1332 "expected worksharing loop directive");
1333 return cast<Expr>(Data->getChildren()[NextUpperBoundOffset]);
1335 Expr *getNumIterations() const {
1336 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1337 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1338 isOpenMPDistributeDirective(getDirectiveKind())) &&
1339 "expected worksharing loop directive");
1340 return cast<Expr>(Data->getChildren()[NumIterationsOffset]);
1342 Expr *getPrevLowerBoundVariable() const {
1343 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1344 "expected loop bound sharing directive");
1345 return cast<Expr>(Data->getChildren()[PrevLowerBoundVariableOffset]);
1347 Expr *getPrevUpperBoundVariable() const {
1348 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1349 "expected loop bound sharing directive");
1350 return cast<Expr>(Data->getChildren()[PrevUpperBoundVariableOffset]);
1352 Expr *getDistInc() const {
1353 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1354 "expected loop bound sharing directive");
1355 return cast<Expr>(Data->getChildren()[DistIncOffset]);
1357 Expr *getPrevEnsureUpperBound() const {
1358 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1359 "expected loop bound sharing directive");
1360 return cast<Expr>(Data->getChildren()[PrevEnsureUpperBoundOffset]);
1362 Expr *getCombinedLowerBoundVariable() const {
1363 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1364 "expected loop bound sharing directive");
1365 return cast<Expr>(Data->getChildren()[CombinedLowerBoundVariableOffset]);
1367 Expr *getCombinedUpperBoundVariable() const {
1368 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1369 "expected loop bound sharing directive");
1370 return cast<Expr>(Data->getChildren()[CombinedUpperBoundVariableOffset]);
1372 Expr *getCombinedEnsureUpperBound() const {
1373 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1374 "expected loop bound sharing directive");
1375 return cast<Expr>(Data->getChildren()[CombinedEnsureUpperBoundOffset]);
1377 Expr *getCombinedInit() const {
1378 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1379 "expected loop bound sharing directive");
1380 return cast<Expr>(Data->getChildren()[CombinedInitOffset]);
1382 Expr *getCombinedCond() const {
1383 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1384 "expected loop bound sharing directive");
1385 return cast<Expr>(Data->getChildren()[CombinedConditionOffset]);
1387 Expr *getCombinedNextLowerBound() const {
1388 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1389 "expected loop bound sharing directive");
1390 return cast<Expr>(Data->getChildren()[CombinedNextLowerBoundOffset]);
1392 Expr *getCombinedNextUpperBound() const {
1393 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1394 "expected loop bound sharing directive");
1395 return cast<Expr>(Data->getChildren()[CombinedNextUpperBoundOffset]);
1397 Expr *getCombinedDistCond() const {
1398 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1399 "expected loop bound distribute sharing directive");
1400 return cast<Expr>(Data->getChildren()[CombinedDistConditionOffset]);
1402 Expr *getCombinedParForInDistCond() const {
1403 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1404 "expected loop bound distribute sharing directive");
1405 return cast<Expr>(Data->getChildren()[CombinedParForInDistConditionOffset]);
1408 const Stmt *getBody() const {
1409 return const_cast<OMPLoopDirective *>(this)->getBody();
1412 ArrayRef<Expr *> counters() { return getCounters(); }
1414 ArrayRef<Expr *> counters() const {
1415 return const_cast<OMPLoopDirective *>(this)->getCounters();
1418 ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
1420 ArrayRef<Expr *> private_counters() const {
1421 return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
1424 ArrayRef<Expr *> inits() { return getInits(); }
1426 ArrayRef<Expr *> inits() const {
1427 return const_cast<OMPLoopDirective *>(this)->getInits();
1430 ArrayRef<Expr *> updates() { return getUpdates(); }
1432 ArrayRef<Expr *> updates() const {
1433 return const_cast<OMPLoopDirective *>(this)->getUpdates();
1436 ArrayRef<Expr *> finals() { return getFinals(); }
1438 ArrayRef<Expr *> finals() const {
1439 return const_cast<OMPLoopDirective *>(this)->getFinals();
1442 ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); }
1444 ArrayRef<Expr *> dependent_counters() const {
1445 return const_cast<OMPLoopDirective *>(this)->getDependentCounters();
1448 ArrayRef<Expr *> dependent_inits() { return getDependentInits(); }
1450 ArrayRef<Expr *> dependent_inits() const {
1451 return const_cast<OMPLoopDirective *>(this)->getDependentInits();
1454 ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); }
1456 ArrayRef<Expr *> finals_conditions() const {
1457 return const_cast<OMPLoopDirective *>(this)->getFinalsConditions();
1460 static bool classof(const Stmt *T) {
1461 return T->getStmtClass() == OMPSimdDirectiveClass ||
1462 T->getStmtClass() == OMPForDirectiveClass ||
1463 T->getStmtClass() == OMPForSimdDirectiveClass ||
1464 T->getStmtClass() == OMPParallelForDirectiveClass ||
1465 T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
1466 T->getStmtClass() == OMPTaskLoopDirectiveClass ||
1467 T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
1468 T->getStmtClass() == OMPMasterTaskLoopDirectiveClass ||
1469 T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass ||
1470 T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass ||
1471 T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass ||
1472 T->getStmtClass() == OMPDistributeDirectiveClass ||
1473 T->getStmtClass() == OMPTargetParallelForDirectiveClass ||
1474 T->getStmtClass() == OMPDistributeParallelForDirectiveClass ||
1475 T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass ||
1476 T->getStmtClass() == OMPDistributeSimdDirectiveClass ||
1477 T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass ||
1478 T->getStmtClass() == OMPTargetSimdDirectiveClass ||
1479 T->getStmtClass() == OMPTeamsDistributeDirectiveClass ||
1480 T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass ||
1481 T->getStmtClass() ==
1482 OMPTeamsDistributeParallelForSimdDirectiveClass ||
1483 T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass ||
1484 T->getStmtClass() ==
1485 OMPTargetTeamsDistributeParallelForDirectiveClass ||
1486 T->getStmtClass() ==
1487 OMPTargetTeamsDistributeParallelForSimdDirectiveClass ||
1488 T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass ||
1489 T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
1493 /// This represents '#pragma omp simd' directive.
1496 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
1498 /// In this example directive '#pragma omp simd' has clauses 'private'
1499 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
1500 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
1502 class OMPSimdDirective : public OMPLoopDirective {
1503 friend class ASTStmtReader;
1504 friend class OMPExecutableDirective;
1505 /// Build directive with the given start and end location.
1507 /// \param StartLoc Starting location of the directive kind.
1508 /// \param EndLoc Ending location of the directive.
1509 /// \param CollapsedNum Number of collapsed nested loops.
1511 OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1512 unsigned CollapsedNum)
1513 : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, StartLoc,
1514 EndLoc, CollapsedNum) {}
1516 /// Build an empty directive.
1518 /// \param CollapsedNum Number of collapsed nested loops.
1520 explicit OMPSimdDirective(unsigned CollapsedNum)
1521 : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd,
1522 SourceLocation(), SourceLocation(), CollapsedNum) {}
1525 /// Creates directive with a list of \a Clauses.
1527 /// \param C AST context.
1528 /// \param StartLoc Starting location of the directive kind.
1529 /// \param EndLoc Ending Location of the directive.
1530 /// \param CollapsedNum Number of collapsed loops.
1531 /// \param Clauses List of clauses.
1532 /// \param AssociatedStmt Statement, associated with the directive.
1533 /// \param Exprs Helper expressions for CodeGen.
1535 static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1536 SourceLocation EndLoc, unsigned CollapsedNum,
1537 ArrayRef<OMPClause *> Clauses,
1538 Stmt *AssociatedStmt,
1539 const HelperExprs &Exprs);
1541 /// Creates an empty directive with the place
1542 /// for \a NumClauses clauses.
1544 /// \param C AST context.
1545 /// \param CollapsedNum Number of collapsed nested loops.
1546 /// \param NumClauses Number of clauses.
1548 static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1549 unsigned CollapsedNum, EmptyShell);
1551 static bool classof(const Stmt *T) {
1552 return T->getStmtClass() == OMPSimdDirectiveClass;
1556 /// This represents '#pragma omp for' directive.
1559 /// #pragma omp for private(a,b) reduction(+:c,d)
1561 /// In this example directive '#pragma omp for' has clauses 'private' with the
1562 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
1565 class OMPForDirective : public OMPLoopDirective {
1566 friend class ASTStmtReader;
1567 friend class OMPExecutableDirective;
1568 /// true if current directive has inner cancel directive.
1569 bool HasCancel = false;
1571 /// Build directive with the given start and end location.
1573 /// \param StartLoc Starting location of the directive kind.
1574 /// \param EndLoc Ending location of the directive.
1575 /// \param CollapsedNum Number of collapsed nested loops.
1577 OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1578 unsigned CollapsedNum)
1579 : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, StartLoc,
1580 EndLoc, CollapsedNum) {}
1582 /// Build an empty directive.
1584 /// \param CollapsedNum Number of collapsed nested loops.
1586 explicit OMPForDirective(unsigned CollapsedNum)
1587 : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for,
1588 SourceLocation(), SourceLocation(), CollapsedNum) {}
1590 /// Sets special task reduction descriptor.
1591 void setTaskReductionRefExpr(Expr *E) {
1592 Data->getChildren()[numLoopChildren(getLoopsNumber(),
1593 llvm::omp::OMPD_for)] = E;
1596 /// Set cancel state.
1597 void setHasCancel(bool Has) { HasCancel = Has; }
1600 /// Creates directive with a list of \a Clauses.
1602 /// \param C AST context.
1603 /// \param StartLoc Starting location of the directive kind.
1604 /// \param EndLoc Ending Location of the directive.
1605 /// \param CollapsedNum Number of collapsed loops.
1606 /// \param Clauses List of clauses.
1607 /// \param AssociatedStmt Statement, associated with the directive.
1608 /// \param Exprs Helper expressions for CodeGen.
1609 /// \param TaskRedRef Task reduction special reference expression to handle
1610 /// taskgroup descriptor.
1611 /// \param HasCancel true if current directive has inner cancel directive.
1613 static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1614 SourceLocation EndLoc, unsigned CollapsedNum,
1615 ArrayRef<OMPClause *> Clauses,
1616 Stmt *AssociatedStmt, const HelperExprs &Exprs,
1617 Expr *TaskRedRef, bool HasCancel);
1619 /// Creates an empty directive with the place
1620 /// for \a NumClauses clauses.
1622 /// \param C AST context.
1623 /// \param CollapsedNum Number of collapsed nested loops.
1624 /// \param NumClauses Number of clauses.
1626 static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1627 unsigned CollapsedNum, EmptyShell);
1629 /// Returns special task reduction reference expression.
1630 Expr *getTaskReductionRefExpr() {
1631 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
1632 getLoopsNumber(), llvm::omp::OMPD_for)]);
1634 const Expr *getTaskReductionRefExpr() const {
1635 return const_cast<OMPForDirective *>(this)->getTaskReductionRefExpr();
1638 /// Return true if current directive has inner cancel directive.
1639 bool hasCancel() const { return HasCancel; }
1641 static bool classof(const Stmt *T) {
1642 return T->getStmtClass() == OMPForDirectiveClass;
1646 /// This represents '#pragma omp for simd' directive.
1649 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
1651 /// In this example directive '#pragma omp for simd' has clauses 'private'
1652 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
1653 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
1655 class OMPForSimdDirective : public OMPLoopDirective {
1656 friend class ASTStmtReader;
1657 friend class OMPExecutableDirective;
1658 /// Build directive with the given start and end location.
1660 /// \param StartLoc Starting location of the directive kind.
1661 /// \param EndLoc Ending location of the directive.
1662 /// \param CollapsedNum Number of collapsed nested loops.
1664 OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1665 unsigned CollapsedNum)
1666 : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
1667 StartLoc, EndLoc, CollapsedNum) {}
1669 /// Build an empty directive.
1671 /// \param CollapsedNum Number of collapsed nested loops.
1673 explicit OMPForSimdDirective(unsigned CollapsedNum)
1674 : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
1675 SourceLocation(), SourceLocation(), CollapsedNum) {}
1678 /// Creates directive with a list of \a Clauses.
1680 /// \param C AST context.
1681 /// \param StartLoc Starting location of the directive kind.
1682 /// \param EndLoc Ending Location of the directive.
1683 /// \param CollapsedNum Number of collapsed loops.
1684 /// \param Clauses List of clauses.
1685 /// \param AssociatedStmt Statement, associated with the directive.
1686 /// \param Exprs Helper expressions for CodeGen.
1688 static OMPForSimdDirective *
1689 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1690 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1691 Stmt *AssociatedStmt, const HelperExprs &Exprs);
1693 /// Creates an empty directive with the place
1694 /// for \a NumClauses clauses.
1696 /// \param C AST context.
1697 /// \param CollapsedNum Number of collapsed nested loops.
1698 /// \param NumClauses Number of clauses.
1700 static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
1701 unsigned NumClauses,
1702 unsigned CollapsedNum, EmptyShell);
1704 static bool classof(const Stmt *T) {
1705 return T->getStmtClass() == OMPForSimdDirectiveClass;
1709 /// This represents '#pragma omp sections' directive.
1712 /// #pragma omp sections private(a,b) reduction(+:c,d)
1714 /// In this example directive '#pragma omp sections' has clauses 'private' with
1715 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
1718 class OMPSectionsDirective : public OMPExecutableDirective {
1719 friend class ASTStmtReader;
1720 friend class OMPExecutableDirective;
1722 /// true if current directive has inner cancel directive.
1723 bool HasCancel = false;
1725 /// Build directive with the given start and end location.
1727 /// \param StartLoc Starting location of the directive kind.
1728 /// \param EndLoc Ending location of the directive.
1730 OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1731 : OMPExecutableDirective(OMPSectionsDirectiveClass,
1732 llvm::omp::OMPD_sections, StartLoc, EndLoc) {}
1734 /// Build an empty directive.
1736 explicit OMPSectionsDirective()
1737 : OMPExecutableDirective(OMPSectionsDirectiveClass,
1738 llvm::omp::OMPD_sections, SourceLocation(),
1739 SourceLocation()) {}
1741 /// Sets special task reduction descriptor.
1742 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
1744 /// Set cancel state.
1745 void setHasCancel(bool Has) { HasCancel = Has; }
1748 /// Creates directive with a list of \a Clauses.
1750 /// \param C AST context.
1751 /// \param StartLoc Starting location of the directive kind.
1752 /// \param EndLoc Ending Location of the directive.
1753 /// \param Clauses List of clauses.
1754 /// \param AssociatedStmt Statement, associated with the directive.
1755 /// \param TaskRedRef Task reduction special reference expression to handle
1756 /// taskgroup descriptor.
1757 /// \param HasCancel true if current directive has inner directive.
1759 static OMPSectionsDirective *
1760 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1761 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
1764 /// Creates an empty directive with the place for \a NumClauses
1767 /// \param C AST context.
1768 /// \param NumClauses Number of clauses.
1770 static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
1771 unsigned NumClauses, EmptyShell);
1773 /// Returns special task reduction reference expression.
1774 Expr *getTaskReductionRefExpr() {
1775 return cast_or_null<Expr>(Data->getChildren()[0]);
1777 const Expr *getTaskReductionRefExpr() const {
1778 return const_cast<OMPSectionsDirective *>(this)->getTaskReductionRefExpr();
1781 /// Return true if current directive has inner cancel directive.
1782 bool hasCancel() const { return HasCancel; }
1784 static bool classof(const Stmt *T) {
1785 return T->getStmtClass() == OMPSectionsDirectiveClass;
1789 /// This represents '#pragma omp section' directive.
1792 /// #pragma omp section
1795 class OMPSectionDirective : public OMPExecutableDirective {
1796 friend class ASTStmtReader;
1797 friend class OMPExecutableDirective;
1799 /// true if current directive has inner cancel directive.
1800 bool HasCancel = false;
1802 /// Build directive with the given start and end location.
1804 /// \param StartLoc Starting location of the directive kind.
1805 /// \param EndLoc Ending location of the directive.
1807 OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1808 : OMPExecutableDirective(OMPSectionDirectiveClass,
1809 llvm::omp::OMPD_section, StartLoc, EndLoc) {}
1811 /// Build an empty directive.
1813 explicit OMPSectionDirective()
1814 : OMPExecutableDirective(OMPSectionDirectiveClass,
1815 llvm::omp::OMPD_section, SourceLocation(),
1816 SourceLocation()) {}
1819 /// Creates directive.
1821 /// \param C AST context.
1822 /// \param StartLoc Starting location of the directive kind.
1823 /// \param EndLoc Ending Location of the directive.
1824 /// \param AssociatedStmt Statement, associated with the directive.
1825 /// \param HasCancel true if current directive has inner directive.
1827 static OMPSectionDirective *Create(const ASTContext &C,
1828 SourceLocation StartLoc,
1829 SourceLocation EndLoc,
1830 Stmt *AssociatedStmt, bool HasCancel);
1832 /// Creates an empty directive.
1834 /// \param C AST context.
1836 static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1838 /// Set cancel state.
1839 void setHasCancel(bool Has) { HasCancel = Has; }
1841 /// Return true if current directive has inner cancel directive.
1842 bool hasCancel() const { return HasCancel; }
1844 static bool classof(const Stmt *T) {
1845 return T->getStmtClass() == OMPSectionDirectiveClass;
1849 /// This represents '#pragma omp single' directive.
1852 /// #pragma omp single private(a,b) copyprivate(c,d)
1854 /// In this example directive '#pragma omp single' has clauses 'private' with
1855 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
1857 class OMPSingleDirective : public OMPExecutableDirective {
1858 friend class ASTStmtReader;
1859 friend class OMPExecutableDirective;
1860 /// Build directive with the given start and end location.
1862 /// \param StartLoc Starting location of the directive kind.
1863 /// \param EndLoc Ending location of the directive.
1865 OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1866 : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
1867 StartLoc, EndLoc) {}
1869 /// Build an empty directive.
1871 explicit OMPSingleDirective()
1872 : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
1873 SourceLocation(), SourceLocation()) {}
1876 /// Creates directive with a list of \a Clauses.
1878 /// \param C AST context.
1879 /// \param StartLoc Starting location of the directive kind.
1880 /// \param EndLoc Ending Location of the directive.
1881 /// \param Clauses List of clauses.
1882 /// \param AssociatedStmt Statement, associated with the directive.
1884 static OMPSingleDirective *
1885 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1886 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1888 /// Creates an empty directive with the place for \a NumClauses
1891 /// \param C AST context.
1892 /// \param NumClauses Number of clauses.
1894 static OMPSingleDirective *CreateEmpty(const ASTContext &C,
1895 unsigned NumClauses, EmptyShell);
1897 static bool classof(const Stmt *T) {
1898 return T->getStmtClass() == OMPSingleDirectiveClass;
1902 /// This represents '#pragma omp master' directive.
1905 /// #pragma omp master
1908 class OMPMasterDirective : public OMPExecutableDirective {
1909 friend class ASTStmtReader;
1910 friend class OMPExecutableDirective;
1911 /// Build directive with the given start and end location.
1913 /// \param StartLoc Starting location of the directive kind.
1914 /// \param EndLoc Ending location of the directive.
1916 OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1917 : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
1918 StartLoc, EndLoc) {}
1920 /// Build an empty directive.
1922 explicit OMPMasterDirective()
1923 : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
1924 SourceLocation(), SourceLocation()) {}
1927 /// Creates directive.
1929 /// \param C AST context.
1930 /// \param StartLoc Starting location of the directive kind.
1931 /// \param EndLoc Ending Location of the directive.
1932 /// \param AssociatedStmt Statement, associated with the directive.
1934 static OMPMasterDirective *Create(const ASTContext &C,
1935 SourceLocation StartLoc,
1936 SourceLocation EndLoc,
1937 Stmt *AssociatedStmt);
1939 /// Creates an empty directive.
1941 /// \param C AST context.
1943 static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1945 static bool classof(const Stmt *T) {
1946 return T->getStmtClass() == OMPMasterDirectiveClass;
1950 /// This represents '#pragma omp critical' directive.
1953 /// #pragma omp critical
1956 class OMPCriticalDirective : public OMPExecutableDirective {
1957 friend class ASTStmtReader;
1958 friend class OMPExecutableDirective;
1959 /// Name of the directive.
1960 DeclarationNameInfo DirName;
1961 /// Build directive with the given start and end location.
1963 /// \param Name Name of the directive.
1964 /// \param StartLoc Starting location of the directive kind.
1965 /// \param EndLoc Ending location of the directive.
1967 OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
1968 SourceLocation EndLoc)
1969 : OMPExecutableDirective(OMPCriticalDirectiveClass,
1970 llvm::omp::OMPD_critical, StartLoc, EndLoc),
1973 /// Build an empty directive.
1975 explicit OMPCriticalDirective()
1976 : OMPExecutableDirective(OMPCriticalDirectiveClass,
1977 llvm::omp::OMPD_critical, SourceLocation(),
1978 SourceLocation()) {}
1980 /// Set name of the directive.
1982 /// \param Name Name of the directive.
1984 void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
1987 /// Creates directive.
1989 /// \param C AST context.
1990 /// \param Name Name of the directive.
1991 /// \param StartLoc Starting location of the directive kind.
1992 /// \param EndLoc Ending Location of the directive.
1993 /// \param Clauses List of clauses.
1994 /// \param AssociatedStmt Statement, associated with the directive.
1996 static OMPCriticalDirective *
1997 Create(const ASTContext &C, const DeclarationNameInfo &Name,
1998 SourceLocation StartLoc, SourceLocation EndLoc,
1999 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2001 /// Creates an empty directive.
2003 /// \param C AST context.
2004 /// \param NumClauses Number of clauses.
2006 static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
2007 unsigned NumClauses, EmptyShell);
2009 /// Return name of the directive.
2011 DeclarationNameInfo getDirectiveName() const { return DirName; }
2013 static bool classof(const Stmt *T) {
2014 return T->getStmtClass() == OMPCriticalDirectiveClass;
2018 /// This represents '#pragma omp parallel for' directive.
2021 /// #pragma omp parallel for private(a,b) reduction(+:c,d)
2023 /// In this example directive '#pragma omp parallel for' has clauses 'private'
2024 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
2025 /// variables 'c' and 'd'.
2027 class OMPParallelForDirective : public OMPLoopDirective {
2028 friend class ASTStmtReader;
2029 friend class OMPExecutableDirective;
2031 /// true if current region has inner cancel directive.
2032 bool HasCancel = false;
2034 /// Build directive with the given start and end location.
2036 /// \param StartLoc Starting location of the directive kind.
2037 /// \param EndLoc Ending location of the directive.
2038 /// \param CollapsedNum Number of collapsed nested loops.
2040 OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2041 unsigned CollapsedNum)
2042 : OMPLoopDirective(OMPParallelForDirectiveClass,
2043 llvm::omp::OMPD_parallel_for, StartLoc, EndLoc,
2046 /// Build an empty directive.
2048 /// \param CollapsedNum Number of collapsed nested loops.
2050 explicit OMPParallelForDirective(unsigned CollapsedNum)
2051 : OMPLoopDirective(OMPParallelForDirectiveClass,
2052 llvm::omp::OMPD_parallel_for, SourceLocation(),
2053 SourceLocation(), CollapsedNum) {}
2055 /// Sets special task reduction descriptor.
2056 void setTaskReductionRefExpr(Expr *E) {
2057 Data->getChildren()[numLoopChildren(getLoopsNumber(),
2058 llvm::omp::OMPD_parallel_for)] = E;
2061 /// Set cancel state.
2062 void setHasCancel(bool Has) { HasCancel = Has; }
2065 /// Creates directive with a list of \a Clauses.
2067 /// \param C AST context.
2068 /// \param StartLoc Starting location of the directive kind.
2069 /// \param EndLoc Ending Location of the directive.
2070 /// \param CollapsedNum Number of collapsed loops.
2071 /// \param Clauses List of clauses.
2072 /// \param AssociatedStmt Statement, associated with the directive.
2073 /// \param Exprs Helper expressions for CodeGen.
2074 /// \param TaskRedRef Task reduction special reference expression to handle
2075 /// taskgroup descriptor.
2076 /// \param HasCancel true if current directive has inner cancel directive.
2078 static OMPParallelForDirective *
2079 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2080 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2081 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
2084 /// Creates an empty directive with the place
2085 /// for \a NumClauses clauses.
2087 /// \param C AST context.
2088 /// \param CollapsedNum Number of collapsed nested loops.
2089 /// \param NumClauses Number of clauses.
2091 static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
2092 unsigned NumClauses,
2093 unsigned CollapsedNum,
2096 /// Returns special task reduction reference expression.
2097 Expr *getTaskReductionRefExpr() {
2098 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
2099 getLoopsNumber(), llvm::omp::OMPD_parallel_for)]);
2101 const Expr *getTaskReductionRefExpr() const {
2102 return const_cast<OMPParallelForDirective *>(this)
2103 ->getTaskReductionRefExpr();
2106 /// Return true if current directive has inner cancel directive.
2107 bool hasCancel() const { return HasCancel; }
2109 static bool classof(const Stmt *T) {
2110 return T->getStmtClass() == OMPParallelForDirectiveClass;
2114 /// This represents '#pragma omp parallel for simd' directive.
2117 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
2119 /// In this example directive '#pragma omp parallel for simd' has clauses
2120 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
2121 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and
2124 class OMPParallelForSimdDirective : public OMPLoopDirective {
2125 friend class ASTStmtReader;
2126 friend class OMPExecutableDirective;
2127 /// Build directive with the given start and end location.
2129 /// \param StartLoc Starting location of the directive kind.
2130 /// \param EndLoc Ending location of the directive.
2131 /// \param CollapsedNum Number of collapsed nested loops.
2133 OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2134 unsigned CollapsedNum)
2135 : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
2136 llvm::omp::OMPD_parallel_for_simd, StartLoc, EndLoc,
2139 /// Build an empty directive.
2141 /// \param CollapsedNum Number of collapsed nested loops.
2143 explicit OMPParallelForSimdDirective(unsigned CollapsedNum)
2144 : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
2145 llvm::omp::OMPD_parallel_for_simd, SourceLocation(),
2146 SourceLocation(), CollapsedNum) {}
2149 /// Creates directive with a list of \a Clauses.
2151 /// \param C AST context.
2152 /// \param StartLoc Starting location of the directive kind.
2153 /// \param EndLoc Ending Location of the directive.
2154 /// \param CollapsedNum Number of collapsed loops.
2155 /// \param Clauses List of clauses.
2156 /// \param AssociatedStmt Statement, associated with the directive.
2157 /// \param Exprs Helper expressions for CodeGen.
2159 static OMPParallelForSimdDirective *
2160 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2161 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2162 Stmt *AssociatedStmt, const HelperExprs &Exprs);
2164 /// Creates an empty directive with the place
2165 /// for \a NumClauses clauses.
2167 /// \param C AST context.
2168 /// \param CollapsedNum Number of collapsed nested loops.
2169 /// \param NumClauses Number of clauses.
2171 static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
2172 unsigned NumClauses,
2173 unsigned CollapsedNum,
2176 static bool classof(const Stmt *T) {
2177 return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
2181 /// This represents '#pragma omp parallel master' directive.
2184 /// #pragma omp parallel master private(a,b)
2186 /// In this example directive '#pragma omp parallel master' has clauses
2187 /// 'private' with the variables 'a' and 'b'
2189 class OMPParallelMasterDirective : public OMPExecutableDirective {
2190 friend class ASTStmtReader;
2191 friend class OMPExecutableDirective;
2193 OMPParallelMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2194 : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
2195 llvm::omp::OMPD_parallel_master, StartLoc,
2198 explicit OMPParallelMasterDirective()
2199 : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
2200 llvm::omp::OMPD_parallel_master,
2201 SourceLocation(), SourceLocation()) {}
2203 /// Sets special task reduction descriptor.
2204 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2207 /// Creates directive with a list of \a Clauses.
2209 /// \param C AST context.
2210 /// \param StartLoc Starting location of the directive kind.
2211 /// \param EndLoc Ending Location of the directive.
2212 /// \param Clauses List of clauses.
2213 /// \param AssociatedStmt Statement, associated with the directive.
2214 /// \param TaskRedRef Task reduction special reference expression to handle
2215 /// taskgroup descriptor.
2217 static OMPParallelMasterDirective *
2218 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2219 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
2221 /// Creates an empty directive with the place for \a NumClauses
2224 /// \param C AST context.
2225 /// \param NumClauses Number of clauses.
2227 static OMPParallelMasterDirective *
2228 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2230 /// Returns special task reduction reference expression.
2231 Expr *getTaskReductionRefExpr() {
2232 return cast_or_null<Expr>(Data->getChildren()[0]);
2234 const Expr *getTaskReductionRefExpr() const {
2235 return const_cast<OMPParallelMasterDirective *>(this)
2236 ->getTaskReductionRefExpr();
2239 static bool classof(const Stmt *T) {
2240 return T->getStmtClass() == OMPParallelMasterDirectiveClass;
2244 /// This represents '#pragma omp parallel sections' directive.
2247 /// #pragma omp parallel sections private(a,b) reduction(+:c,d)
2249 /// In this example directive '#pragma omp parallel sections' has clauses
2250 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
2251 /// and variables 'c' and 'd'.
2253 class OMPParallelSectionsDirective : public OMPExecutableDirective {
2254 friend class ASTStmtReader;
2255 friend class OMPExecutableDirective;
2257 /// true if current directive has inner cancel directive.
2258 bool HasCancel = false;
2260 /// Build directive with the given start and end location.
2262 /// \param StartLoc Starting location of the directive kind.
2263 /// \param EndLoc Ending location of the directive.
2265 OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2266 : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
2267 llvm::omp::OMPD_parallel_sections, StartLoc,
2270 /// Build an empty directive.
2272 explicit OMPParallelSectionsDirective()
2273 : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
2274 llvm::omp::OMPD_parallel_sections,
2275 SourceLocation(), SourceLocation()) {}
2277 /// Sets special task reduction descriptor.
2278 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2280 /// Set cancel state.
2281 void setHasCancel(bool Has) { HasCancel = Has; }
2284 /// Creates directive with a list of \a Clauses.
2286 /// \param C AST context.
2287 /// \param StartLoc Starting location of the directive kind.
2288 /// \param EndLoc Ending Location of the directive.
2289 /// \param Clauses List of clauses.
2290 /// \param AssociatedStmt Statement, associated with the directive.
2291 /// \param TaskRedRef Task reduction special reference expression to handle
2292 /// taskgroup descriptor.
2293 /// \param HasCancel true if current directive has inner cancel directive.
2295 static OMPParallelSectionsDirective *
2296 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2297 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
2300 /// Creates an empty directive with the place for \a NumClauses
2303 /// \param C AST context.
2304 /// \param NumClauses Number of clauses.
2306 static OMPParallelSectionsDirective *
2307 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2309 /// Returns special task reduction reference expression.
2310 Expr *getTaskReductionRefExpr() {
2311 return cast_or_null<Expr>(Data->getChildren()[0]);
2313 const Expr *getTaskReductionRefExpr() const {
2314 return const_cast<OMPParallelSectionsDirective *>(this)
2315 ->getTaskReductionRefExpr();
2318 /// Return true if current directive has inner cancel directive.
2319 bool hasCancel() const { return HasCancel; }
2321 static bool classof(const Stmt *T) {
2322 return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
2326 /// This represents '#pragma omp task' directive.
2329 /// #pragma omp task private(a,b) final(d)
2331 /// In this example directive '#pragma omp task' has clauses 'private' with the
2332 /// variables 'a' and 'b' and 'final' with condition 'd'.
2334 class OMPTaskDirective : public OMPExecutableDirective {
2335 friend class ASTStmtReader;
2336 friend class OMPExecutableDirective;
2337 /// true if this directive has inner cancel directive.
2338 bool HasCancel = false;
2340 /// Build directive with the given start and end location.
2342 /// \param StartLoc Starting location of the directive kind.
2343 /// \param EndLoc Ending location of the directive.
2345 OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2346 : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
2347 StartLoc, EndLoc) {}
2349 /// Build an empty directive.
2351 explicit OMPTaskDirective()
2352 : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
2353 SourceLocation(), SourceLocation()) {}
2355 /// Set cancel state.
2356 void setHasCancel(bool Has) { HasCancel = Has; }
2359 /// Creates directive with a list of \a Clauses.
2361 /// \param C AST context.
2362 /// \param StartLoc Starting location of the directive kind.
2363 /// \param EndLoc Ending Location of the directive.
2364 /// \param Clauses List of clauses.
2365 /// \param AssociatedStmt Statement, associated with the directive.
2366 /// \param HasCancel true, if current directive has inner cancel directive.
2368 static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2369 SourceLocation EndLoc,
2370 ArrayRef<OMPClause *> Clauses,
2371 Stmt *AssociatedStmt, bool HasCancel);
2373 /// Creates an empty directive with the place for \a NumClauses
2376 /// \param C AST context.
2377 /// \param NumClauses Number of clauses.
2379 static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
2382 /// Return true if current directive has inner cancel directive.
2383 bool hasCancel() const { return HasCancel; }
2385 static bool classof(const Stmt *T) {
2386 return T->getStmtClass() == OMPTaskDirectiveClass;
2390 /// This represents '#pragma omp taskyield' directive.
2393 /// #pragma omp taskyield
2396 class OMPTaskyieldDirective : public OMPExecutableDirective {
2397 friend class ASTStmtReader;
2398 friend class OMPExecutableDirective;
2399 /// Build directive with the given start and end location.
2401 /// \param StartLoc Starting location of the directive kind.
2402 /// \param EndLoc Ending location of the directive.
2404 OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2405 : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
2406 llvm::omp::OMPD_taskyield, StartLoc, EndLoc) {}
2408 /// Build an empty directive.
2410 explicit OMPTaskyieldDirective()
2411 : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
2412 llvm::omp::OMPD_taskyield, SourceLocation(),
2413 SourceLocation()) {}
2416 /// Creates directive.
2418 /// \param C AST context.
2419 /// \param StartLoc Starting location of the directive kind.
2420 /// \param EndLoc Ending Location of the directive.
2422 static OMPTaskyieldDirective *
2423 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
2425 /// Creates an empty directive.
2427 /// \param C AST context.
2429 static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2431 static bool classof(const Stmt *T) {
2432 return T->getStmtClass() == OMPTaskyieldDirectiveClass;
2436 /// This represents '#pragma omp barrier' directive.
2439 /// #pragma omp barrier
2442 class OMPBarrierDirective : public OMPExecutableDirective {
2443 friend class ASTStmtReader;
2444 friend class OMPExecutableDirective;
2445 /// Build directive with the given start and end location.
2447 /// \param StartLoc Starting location of the directive kind.
2448 /// \param EndLoc Ending location of the directive.
2450 OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2451 : OMPExecutableDirective(OMPBarrierDirectiveClass,
2452 llvm::omp::OMPD_barrier, StartLoc, EndLoc) {}
2454 /// Build an empty directive.
2456 explicit OMPBarrierDirective()
2457 : OMPExecutableDirective(OMPBarrierDirectiveClass,
2458 llvm::omp::OMPD_barrier, SourceLocation(),
2459 SourceLocation()) {}
2462 /// Creates directive.
2464 /// \param C AST context.
2465 /// \param StartLoc Starting location of the directive kind.
2466 /// \param EndLoc Ending Location of the directive.
2468 static OMPBarrierDirective *
2469 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
2471 /// Creates an empty directive.
2473 /// \param C AST context.
2475 static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2477 static bool classof(const Stmt *T) {
2478 return T->getStmtClass() == OMPBarrierDirectiveClass;
2482 /// This represents '#pragma omp taskwait' directive.
2485 /// #pragma omp taskwait
2488 class OMPTaskwaitDirective : public OMPExecutableDirective {
2489 friend class ASTStmtReader;
2490 friend class OMPExecutableDirective;
2491 /// Build directive with the given start and end location.
2493 /// \param StartLoc Starting location of the directive kind.
2494 /// \param EndLoc Ending location of the directive.
2496 OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2497 : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
2498 llvm::omp::OMPD_taskwait, StartLoc, EndLoc) {}
2500 /// Build an empty directive.
2502 explicit OMPTaskwaitDirective()
2503 : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
2504 llvm::omp::OMPD_taskwait, SourceLocation(),
2505 SourceLocation()) {}
2508 /// Creates directive.
2510 /// \param C AST context.
2511 /// \param StartLoc Starting location of the directive kind.
2512 /// \param EndLoc Ending Location of the directive.
2514 static OMPTaskwaitDirective *
2515 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
2517 /// Creates an empty directive.
2519 /// \param C AST context.
2521 static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2523 static bool classof(const Stmt *T) {
2524 return T->getStmtClass() == OMPTaskwaitDirectiveClass;
2528 /// This represents '#pragma omp taskgroup' directive.
2531 /// #pragma omp taskgroup
2534 class OMPTaskgroupDirective : public OMPExecutableDirective {
2535 friend class ASTStmtReader;
2536 friend class OMPExecutableDirective;
2537 /// Build directive with the given start and end location.
2539 /// \param StartLoc Starting location of the directive kind.
2540 /// \param EndLoc Ending location of the directive.
2542 OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2543 : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
2544 llvm::omp::OMPD_taskgroup, StartLoc, EndLoc) {}
2546 /// Build an empty directive.
2548 explicit OMPTaskgroupDirective()
2549 : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
2550 llvm::omp::OMPD_taskgroup, SourceLocation(),
2551 SourceLocation()) {}
2553 /// Sets the task_reduction return variable.
2554 void setReductionRef(Expr *RR) { Data->getChildren()[0] = RR; }
2557 /// Creates directive.
2559 /// \param C AST context.
2560 /// \param StartLoc Starting location of the directive kind.
2561 /// \param EndLoc Ending Location of the directive.
2562 /// \param Clauses List of clauses.
2563 /// \param AssociatedStmt Statement, associated with the directive.
2564 /// \param ReductionRef Reference to the task_reduction return variable.
2566 static OMPTaskgroupDirective *
2567 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2568 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
2569 Expr *ReductionRef);
2571 /// Creates an empty directive.
2573 /// \param C AST context.
2574 /// \param NumClauses Number of clauses.
2576 static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C,
2577 unsigned NumClauses, EmptyShell);
2580 /// Returns reference to the task_reduction return variable.
2581 const Expr *getReductionRef() const {
2582 return const_cast<OMPTaskgroupDirective *>(this)->getReductionRef();
2584 Expr *getReductionRef() { return cast_or_null<Expr>(Data->getChildren()[0]); }
2586 static bool classof(const Stmt *T) {
2587 return T->getStmtClass() == OMPTaskgroupDirectiveClass;
2591 /// This represents '#pragma omp flush' directive.
2594 /// #pragma omp flush(a,b)
2596 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
2598 /// 'omp flush' directive does not have clauses but have an optional list of
2599 /// variables to flush. This list of variables is stored within some fake clause
2601 class OMPFlushDirective : public OMPExecutableDirective {
2602 friend class ASTStmtReader;
2603 friend class OMPExecutableDirective;
2604 /// Build directive with the given start and end location.
2606 /// \param StartLoc Starting location of the directive kind.
2607 /// \param EndLoc Ending location of the directive.
2609 OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2610 : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
2611 StartLoc, EndLoc) {}
2613 /// Build an empty directive.
2615 explicit OMPFlushDirective()
2616 : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
2617 SourceLocation(), SourceLocation()) {}
2620 /// Creates directive with a list of \a Clauses.
2622 /// \param C AST context.
2623 /// \param StartLoc Starting location of the directive kind.
2624 /// \param EndLoc Ending Location of the directive.
2625 /// \param Clauses List of clauses (only single OMPFlushClause clause is
2628 static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2629 SourceLocation EndLoc,
2630 ArrayRef<OMPClause *> Clauses);
2632 /// Creates an empty directive with the place for \a NumClauses
2635 /// \param C AST context.
2636 /// \param NumClauses Number of clauses.
2638 static OMPFlushDirective *CreateEmpty(const ASTContext &C,
2639 unsigned NumClauses, EmptyShell);
2641 static bool classof(const Stmt *T) {
2642 return T->getStmtClass() == OMPFlushDirectiveClass;
2646 /// This represents '#pragma omp depobj' directive.
2649 /// #pragma omp depobj(a) depend(in:x,y)
2651 /// In this example directive '#pragma omp depobj' initializes a depobj object
2652 /// 'a' with dependence type 'in' and a list with 'x' and 'y' locators.
2653 class OMPDepobjDirective final : public OMPExecutableDirective {
2654 friend class ASTStmtReader;
2655 friend class OMPExecutableDirective;
2657 /// Build directive with the given start and end location.
2659 /// \param StartLoc Starting location of the directive kind.
2660 /// \param EndLoc Ending location of the directive.
2662 OMPDepobjDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2663 : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
2664 StartLoc, EndLoc) {}
2666 /// Build an empty directive.
2668 explicit OMPDepobjDirective()
2669 : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
2670 SourceLocation(), SourceLocation()) {}
2673 /// Creates directive with a list of \a Clauses.
2675 /// \param C AST context.
2676 /// \param StartLoc Starting location of the directive kind.
2677 /// \param EndLoc Ending Location of the directive.
2678 /// \param Clauses List of clauses.
2680 static OMPDepobjDirective *Create(const ASTContext &C,
2681 SourceLocation StartLoc,
2682 SourceLocation EndLoc,
2683 ArrayRef<OMPClause *> Clauses);
2685 /// Creates an empty directive with the place for \a NumClauses
2688 /// \param C AST context.
2689 /// \param NumClauses Number of clauses.
2691 static OMPDepobjDirective *CreateEmpty(const ASTContext &C,
2692 unsigned NumClauses, EmptyShell);
2694 static bool classof(const Stmt *T) {
2695 return T->getStmtClass() == OMPDepobjDirectiveClass;
2699 /// This represents '#pragma omp ordered' directive.
2702 /// #pragma omp ordered
2705 class OMPOrderedDirective : public OMPExecutableDirective {
2706 friend class ASTStmtReader;
2707 friend class OMPExecutableDirective;
2708 /// Build directive with the given start and end location.
2710 /// \param StartLoc Starting location of the directive kind.
2711 /// \param EndLoc Ending location of the directive.
2713 OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2714 : OMPExecutableDirective(OMPOrderedDirectiveClass,
2715 llvm::omp::OMPD_ordered, StartLoc, EndLoc) {}
2717 /// Build an empty directive.
2719 explicit OMPOrderedDirective()
2720 : OMPExecutableDirective(OMPOrderedDirectiveClass,
2721 llvm::omp::OMPD_ordered, SourceLocation(),
2722 SourceLocation()) {}
2725 /// Creates directive.
2727 /// \param C AST context.
2728 /// \param StartLoc Starting location of the directive kind.
2729 /// \param EndLoc Ending Location of the directive.
2730 /// \param Clauses List of clauses.
2731 /// \param AssociatedStmt Statement, associated with the directive.
2733 static OMPOrderedDirective *
2734 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2735 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2737 /// Creates an empty directive.
2739 /// \param C AST context.
2740 /// \param NumClauses Number of clauses.
2741 /// \param IsStandalone true, if the the standalone directive is created.
2743 static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
2744 unsigned NumClauses,
2745 bool IsStandalone, EmptyShell);
2747 static bool classof(const Stmt *T) {
2748 return T->getStmtClass() == OMPOrderedDirectiveClass;
2752 /// This represents '#pragma omp atomic' directive.
2755 /// #pragma omp atomic capture
2757 /// In this example directive '#pragma omp atomic' has clause 'capture'.
2759 class OMPAtomicDirective : public OMPExecutableDirective {
2760 friend class ASTStmtReader;
2761 friend class OMPExecutableDirective;
2762 /// Used for 'atomic update' or 'atomic capture' constructs. They may
2763 /// have atomic expressions of forms
2765 /// x = x binop expr;
2766 /// x = expr binop x;
2768 /// This field is true for the first form of the expression and false for the
2769 /// second. Required for correct codegen of non-associative operations (like
2771 bool IsXLHSInRHSPart = false;
2772 /// Used for 'atomic update' or 'atomic capture' constructs. They may
2773 /// have atomic expressions of forms
2775 /// v = x; <update x>;
2776 /// <update x>; v = x;
2778 /// This field is true for the first(postfix) form of the expression and false
2780 bool IsPostfixUpdate = false;
2782 /// Build directive with the given start and end location.
2784 /// \param StartLoc Starting location of the directive kind.
2785 /// \param EndLoc Ending location of the directive.
2787 OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2788 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
2789 StartLoc, EndLoc) {}
2791 /// Build an empty directive.
2793 explicit OMPAtomicDirective()
2794 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
2795 SourceLocation(), SourceLocation()) {}
2797 /// Set 'x' part of the associated expression/statement.
2798 void setX(Expr *X) { Data->getChildren()[0] = X; }
2799 /// Set helper expression of the form
2800 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
2801 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2802 void setUpdateExpr(Expr *UE) { Data->getChildren()[1] = UE; }
2803 /// Set 'v' part of the associated expression/statement.
2804 void setV(Expr *V) { Data->getChildren()[2] = V; }
2805 /// Set 'expr' part of the associated expression/statement.
2806 void setExpr(Expr *E) { Data->getChildren()[3] = E; }
2809 /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
2810 /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
2811 /// detailed description of 'x', 'v' and 'expr').
2813 /// \param C AST context.
2814 /// \param StartLoc Starting location of the directive kind.
2815 /// \param EndLoc Ending Location of the directive.
2816 /// \param Clauses List of clauses.
2817 /// \param AssociatedStmt Statement, associated with the directive.
2818 /// \param X 'x' part of the associated expression/statement.
2819 /// \param V 'v' part of the associated expression/statement.
2820 /// \param E 'expr' part of the associated expression/statement.
2821 /// \param UE Helper expression of the form
2822 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
2823 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2824 /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the
2826 /// \param IsPostfixUpdate true if original value of 'x' must be stored in
2827 /// 'v', not an updated one.
2828 static OMPAtomicDirective *
2829 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2830 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
2831 Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate);
2833 /// Creates an empty directive with the place for \a NumClauses
2836 /// \param C AST context.
2837 /// \param NumClauses Number of clauses.
2839 static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
2840 unsigned NumClauses, EmptyShell);
2842 /// Get 'x' part of the associated expression/statement.
2843 Expr *getX() { return cast_or_null<Expr>(Data->getChildren()[0]); }
2844 const Expr *getX() const {
2845 return cast_or_null<Expr>(Data->getChildren()[0]);
2847 /// Get helper expression of the form
2848 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
2849 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2850 Expr *getUpdateExpr() { return cast_or_null<Expr>(Data->getChildren()[1]); }
2851 const Expr *getUpdateExpr() const {
2852 return cast_or_null<Expr>(Data->getChildren()[1]);
2854 /// Return true if helper update expression has form
2855 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
2856 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2857 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
2858 /// Return true if 'v' expression must be updated to original value of
2859 /// 'x', false if 'v' must be updated to the new value of 'x'.
2860 bool isPostfixUpdate() const { return IsPostfixUpdate; }
2861 /// Get 'v' part of the associated expression/statement.
2862 Expr *getV() { return cast_or_null<Expr>(Data->getChildren()[2]); }
2863 const Expr *getV() const {
2864 return cast_or_null<Expr>(Data->getChildren()[2]);
2866 /// Get 'expr' part of the associated expression/statement.
2867 Expr *getExpr() { return cast_or_null<Expr>(Data->getChildren()[3]); }
2868 const Expr *getExpr() const {
2869 return cast_or_null<Expr>(Data->getChildren()[3]);
2872 static bool classof(const Stmt *T) {
2873 return T->getStmtClass() == OMPAtomicDirectiveClass;
2877 /// This represents '#pragma omp target' directive.
2880 /// #pragma omp target if(a)
2882 /// In this example directive '#pragma omp target' has clause 'if' with
2885 class OMPTargetDirective : public OMPExecutableDirective {
2886 friend class ASTStmtReader;
2887 friend class OMPExecutableDirective;
2888 /// Build directive with the given start and end location.
2890 /// \param StartLoc Starting location of the directive kind.
2891 /// \param EndLoc Ending location of the directive.
2893 OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2894 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
2895 StartLoc, EndLoc) {}
2897 /// Build an empty directive.
2899 explicit OMPTargetDirective()
2900 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
2901 SourceLocation(), SourceLocation()) {}
2904 /// Creates directive with a list of \a Clauses.
2906 /// \param C AST context.
2907 /// \param StartLoc Starting location of the directive kind.
2908 /// \param EndLoc Ending Location of the directive.
2909 /// \param Clauses List of clauses.
2910 /// \param AssociatedStmt Statement, associated with the directive.
2912 static OMPTargetDirective *
2913 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2914 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2916 /// Creates an empty directive with the place for \a NumClauses
2919 /// \param C AST context.
2920 /// \param NumClauses Number of clauses.
2922 static OMPTargetDirective *CreateEmpty(const ASTContext &C,
2923 unsigned NumClauses, EmptyShell);
2925 static bool classof(const Stmt *T) {
2926 return T->getStmtClass() == OMPTargetDirectiveClass;
2930 /// This represents '#pragma omp target data' directive.
2933 /// #pragma omp target data device(0) if(a) map(b[:])
2935 /// In this example directive '#pragma omp target data' has clauses 'device'
2936 /// with the value '0', 'if' with condition 'a' and 'map' with array
2939 class OMPTargetDataDirective : public OMPExecutableDirective {
2940 friend class ASTStmtReader;
2941 friend class OMPExecutableDirective;
2942 /// Build directive with the given start and end location.
2944 /// \param StartLoc Starting location of the directive kind.
2945 /// \param EndLoc Ending Location of the directive.
2947 OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2948 : OMPExecutableDirective(OMPTargetDataDirectiveClass,
2949 llvm::omp::OMPD_target_data, StartLoc, EndLoc) {}
2951 /// Build an empty directive.
2953 explicit OMPTargetDataDirective()
2954 : OMPExecutableDirective(OMPTargetDataDirectiveClass,
2955 llvm::omp::OMPD_target_data, SourceLocation(),
2956 SourceLocation()) {}
2959 /// Creates directive with a list of \a Clauses.
2961 /// \param C AST context.
2962 /// \param StartLoc Starting location of the directive kind.
2963 /// \param EndLoc Ending Location of the directive.
2964 /// \param Clauses List of clauses.
2965 /// \param AssociatedStmt Statement, associated with the directive.
2967 static OMPTargetDataDirective *
2968 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2969 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2971 /// Creates an empty directive with the place for \a N clauses.
2973 /// \param C AST context.
2974 /// \param N The number of clauses.
2976 static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
2979 static bool classof(const Stmt *T) {
2980 return T->getStmtClass() == OMPTargetDataDirectiveClass;
2984 /// This represents '#pragma omp target enter data' directive.
2987 /// #pragma omp target enter data device(0) if(a) map(b[:])
2989 /// In this example directive '#pragma omp target enter data' has clauses
2990 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
2993 class OMPTargetEnterDataDirective : public OMPExecutableDirective {
2994 friend class ASTStmtReader;
2995 friend class OMPExecutableDirective;
2996 /// Build directive with the given start and end location.
2998 /// \param StartLoc Starting location of the directive kind.
2999 /// \param EndLoc Ending Location of the directive.
3001 OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3002 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3003 llvm::omp::OMPD_target_enter_data, StartLoc,
3006 /// Build an empty directive.
3008 explicit OMPTargetEnterDataDirective()
3009 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3010 llvm::omp::OMPD_target_enter_data,
3011 SourceLocation(), SourceLocation()) {}
3014 /// Creates directive with a list of \a Clauses.
3016 /// \param C AST context.
3017 /// \param StartLoc Starting location of the directive kind.
3018 /// \param EndLoc Ending Location of the directive.
3019 /// \param Clauses List of clauses.
3020 /// \param AssociatedStmt Statement, associated with the directive.
3022 static OMPTargetEnterDataDirective *
3023 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3024 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3026 /// Creates an empty directive with the place for \a N clauses.
3028 /// \param C AST context.
3029 /// \param N The number of clauses.
3031 static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C,
3032 unsigned N, EmptyShell);
3034 static bool classof(const Stmt *T) {
3035 return T->getStmtClass() == OMPTargetEnterDataDirectiveClass;
3039 /// This represents '#pragma omp target exit data' directive.
3042 /// #pragma omp target exit data device(0) if(a) map(b[:])
3044 /// In this example directive '#pragma omp target exit data' has clauses
3045 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
3048 class OMPTargetExitDataDirective : public OMPExecutableDirective {
3049 friend class ASTStmtReader;
3050 friend class OMPExecutableDirective;
3051 /// Build directive with the given start and end location.
3053 /// \param StartLoc Starting location of the directive kind.
3054 /// \param EndLoc Ending Location of the directive.
3056 OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3057 : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3058 llvm::omp::OMPD_target_exit_data, StartLoc,
3061 /// Build an empty directive.
3063 explicit OMPTargetExitDataDirective()
3064 : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3065 llvm::omp::OMPD_target_exit_data,
3066 SourceLocation(), SourceLocation()) {}
3069 /// Creates directive with a list of \a Clauses.
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.
3077 static OMPTargetExitDataDirective *
3078 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3079 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3081 /// Creates an empty directive with the place for \a N clauses.
3083 /// \param C AST context.
3084 /// \param N The number of clauses.
3086 static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
3087 unsigned N, EmptyShell);
3089 static bool classof(const Stmt *T) {
3090 return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
3094 /// This represents '#pragma omp target parallel' directive.
3097 /// #pragma omp target parallel if(a)
3099 /// In this example directive '#pragma omp target parallel' has clause 'if' with
3102 class OMPTargetParallelDirective : public OMPExecutableDirective {
3103 friend class ASTStmtReader;
3104 friend class OMPExecutableDirective;
3105 /// true if the construct has inner cancel directive.
3106 bool HasCancel = false;
3108 /// Build directive with the given start and end location.
3110 /// \param StartLoc Starting location of the directive kind.
3111 /// \param EndLoc Ending location of the directive.
3113 OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3114 : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3115 llvm::omp::OMPD_target_parallel, StartLoc,
3118 /// Build an empty directive.
3120 explicit OMPTargetParallelDirective()
3121 : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3122 llvm::omp::OMPD_target_parallel,
3123 SourceLocation(), SourceLocation()) {}
3125 /// Sets special task reduction descriptor.
3126 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
3127 /// Set cancel state.
3128 void setHasCancel(bool Has) { HasCancel = Has; }
3131 /// Creates directive with a list of \a Clauses.
3133 /// \param C AST context.
3134 /// \param StartLoc Starting location of the directive kind.
3135 /// \param EndLoc Ending Location of the directive.
3136 /// \param Clauses List of clauses.
3137 /// \param AssociatedStmt Statement, associated with the directive.
3138 /// \param TaskRedRef Task reduction special reference expression to handle
3139 /// taskgroup descriptor.
3140 /// \param HasCancel true if this directive has inner cancel directive.
3142 static OMPTargetParallelDirective *
3143 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3144 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
3147 /// Creates an empty directive with the place for \a NumClauses
3150 /// \param C AST context.
3151 /// \param NumClauses Number of clauses.
3153 static OMPTargetParallelDirective *
3154 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
3156 /// Returns special task reduction reference expression.
3157 Expr *getTaskReductionRefExpr() {
3158 return cast_or_null<Expr>(Data->getChildren()[0]);
3160 const Expr *getTaskReductionRefExpr() const {
3161 return const_cast<OMPTargetParallelDirective *>(this)
3162 ->getTaskReductionRefExpr();
3165 /// Return true if current directive has inner cancel directive.
3166 bool hasCancel() const { return HasCancel; }
3168 static bool classof(const Stmt *T) {
3169 return T->getStmtClass() == OMPTargetParallelDirectiveClass;
3173 /// This represents '#pragma omp target parallel for' directive.
3176 /// #pragma omp target parallel for private(a,b) reduction(+:c,d)
3178 /// In this example directive '#pragma omp target parallel for' has clauses
3179 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
3180 /// and variables 'c' and 'd'.
3182 class OMPTargetParallelForDirective : public OMPLoopDirective {
3183 friend class ASTStmtReader;
3184 friend class OMPExecutableDirective;
3186 /// true if current region has inner cancel directive.
3187 bool HasCancel = false;
3189 /// Build directive with the given start and end location.
3191 /// \param StartLoc Starting location of the directive kind.
3192 /// \param EndLoc Ending location of the directive.
3193 /// \param CollapsedNum Number of collapsed nested loops.
3195 OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3196 unsigned CollapsedNum)
3197 : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3198 llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc,
3201 /// Build an empty directive.
3203 /// \param CollapsedNum Number of collapsed nested loops.
3205 explicit OMPTargetParallelForDirective(unsigned CollapsedNum)
3206 : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3207 llvm::omp::OMPD_target_parallel_for, SourceLocation(),
3208 SourceLocation(), CollapsedNum) {}
3210 /// Sets special task reduction descriptor.
3211 void setTaskReductionRefExpr(Expr *E) {
3212 Data->getChildren()[numLoopChildren(
3213 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E;
3216 /// Set cancel state.
3217 void setHasCancel(bool Has) { HasCancel = Has; }
3220 /// Creates directive with a list of \a Clauses.
3222 /// \param C AST context.
3223 /// \param StartLoc Starting location of the directive kind.
3224 /// \param EndLoc Ending Location of the directive.
3225 /// \param CollapsedNum Number of collapsed loops.
3226 /// \param Clauses List of clauses.
3227 /// \param AssociatedStmt Statement, associated with the directive.
3228 /// \param Exprs Helper expressions for CodeGen.
3229 /// \param TaskRedRef Task reduction special reference expression to handle
3230 /// taskgroup descriptor.
3231 /// \param HasCancel true if current directive has inner cancel directive.
3233 static OMPTargetParallelForDirective *
3234 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3235 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3236 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
3239 /// Creates an empty directive with the place
3240 /// for \a NumClauses clauses.
3242 /// \param C AST context.
3243 /// \param CollapsedNum Number of collapsed nested loops.
3244 /// \param NumClauses Number of clauses.
3246 static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C,
3247 unsigned NumClauses,
3248 unsigned CollapsedNum,
3251 /// Returns special task reduction reference expression.
3252 Expr *getTaskReductionRefExpr() {
3253 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
3254 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]);
3256 const Expr *getTaskReductionRefExpr() const {
3257 return const_cast<OMPTargetParallelForDirective *>(this)
3258 ->getTaskReductionRefExpr();
3261 /// Return true if current directive has inner cancel directive.
3262 bool hasCancel() const { return HasCancel; }
3264 static bool classof(const Stmt *T) {
3265 return T->getStmtClass() == OMPTargetParallelForDirectiveClass;
3269 /// This represents '#pragma omp teams' directive.
3272 /// #pragma omp teams if(a)
3274 /// In this example directive '#pragma omp teams' has clause 'if' with
3277 class OMPTeamsDirective : public OMPExecutableDirective {
3278 friend class ASTStmtReader;
3279 friend class OMPExecutableDirective;
3280 /// Build directive with the given start and end location.
3282 /// \param StartLoc Starting location of the directive kind.
3283 /// \param EndLoc Ending location of the directive.
3285 OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3286 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3287 StartLoc, EndLoc) {}
3289 /// Build an empty directive.
3291 explicit OMPTeamsDirective()
3292 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3293 SourceLocation(), SourceLocation()) {}
3296 /// Creates directive with a list of \a Clauses.
3298 /// \param C AST context.
3299 /// \param StartLoc Starting location of the directive kind.
3300 /// \param EndLoc Ending Location of the directive.
3301 /// \param Clauses List of clauses.
3302 /// \param AssociatedStmt Statement, associated with the directive.
3304 static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
3305 SourceLocation EndLoc,
3306 ArrayRef<OMPClause *> Clauses,
3307 Stmt *AssociatedStmt);
3309 /// Creates an empty directive with the place for \a NumClauses
3312 /// \param C AST context.
3313 /// \param NumClauses Number of clauses.
3315 static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
3316 unsigned NumClauses, EmptyShell);
3318 static bool classof(const Stmt *T) {
3319 return T->getStmtClass() == OMPTeamsDirectiveClass;
3323 /// This represents '#pragma omp cancellation point' directive.
3326 /// #pragma omp cancellation point for
3329 /// In this example a cancellation point is created for innermost 'for' region.
3330 class OMPCancellationPointDirective : public OMPExecutableDirective {
3331 friend class ASTStmtReader;
3332 friend class OMPExecutableDirective;
3333 OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
3334 /// Build directive with the given start and end location.
3336 /// \param StartLoc Starting location of the directive kind.
3337 /// \param EndLoc Ending location of the directive.
3338 /// statements and child expressions.
3340 OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3341 : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3342 llvm::omp::OMPD_cancellation_point, StartLoc,
3345 /// Build an empty directive.
3346 explicit OMPCancellationPointDirective()
3347 : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3348 llvm::omp::OMPD_cancellation_point,
3349 SourceLocation(), SourceLocation()) {}
3351 /// Set cancel region for current cancellation point.
3352 /// \param CR Cancellation region.
3353 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
3356 /// Creates directive.
3358 /// \param C AST context.
3359 /// \param StartLoc Starting location of the directive kind.
3360 /// \param EndLoc Ending Location of the directive.
3362 static OMPCancellationPointDirective *
3363 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3364 OpenMPDirectiveKind CancelRegion);
3366 /// Creates an empty directive.
3368 /// \param C AST context.
3370 static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
3373 /// Get cancellation region for the current cancellation point.
3374 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
3376 static bool classof(const Stmt *T) {
3377 return T->getStmtClass() == OMPCancellationPointDirectiveClass;
3381 /// This represents '#pragma omp cancel' directive.
3384 /// #pragma omp cancel for
3387 /// In this example a cancel is created for innermost 'for' region.
3388 class OMPCancelDirective : public OMPExecutableDirective {
3389 friend class ASTStmtReader;
3390 friend class OMPExecutableDirective;
3391 OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
3392 /// Build directive with the given start and end location.
3394 /// \param StartLoc Starting location of the directive kind.
3395 /// \param EndLoc Ending location of the directive.
3397 OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3398 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3399 StartLoc, EndLoc) {}
3401 /// Build an empty directive.
3403 explicit OMPCancelDirective()
3404 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3405 SourceLocation(), SourceLocation()) {}
3407 /// Set cancel region for current cancellation point.
3408 /// \param CR Cancellation region.
3409 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
3412 /// Creates directive.
3414 /// \param C AST context.
3415 /// \param StartLoc Starting location of the directive kind.
3416 /// \param EndLoc Ending Location of the directive.
3417 /// \param Clauses List of clauses.
3419 static OMPCancelDirective *
3420 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3421 ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
3423 /// Creates an empty directive.
3425 /// \param C AST context.
3426 /// \param NumClauses Number of clauses.
3428 static OMPCancelDirective *CreateEmpty(const ASTContext &C,
3429 unsigned NumClauses, EmptyShell);
3431 /// Get cancellation region for the current cancellation point.
3432 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
3434 static bool classof(const Stmt *T) {
3435 return T->getStmtClass() == OMPCancelDirectiveClass;
3439 /// This represents '#pragma omp taskloop' directive.
3442 /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
3444 /// In this example directive '#pragma omp taskloop' has clauses 'private'
3445 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
3446 /// 'num_tasks' with expression 'num'.
3448 class OMPTaskLoopDirective : public OMPLoopDirective {
3449 friend class ASTStmtReader;
3450 friend class OMPExecutableDirective;
3451 /// true if the construct has inner cancel directive.
3452 bool HasCancel = false;
3454 /// Build directive with the given start and end location.
3456 /// \param StartLoc Starting location of the directive kind.
3457 /// \param EndLoc Ending location of the directive.
3458 /// \param CollapsedNum Number of collapsed nested loops.
3460 OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3461 unsigned CollapsedNum)
3462 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3463 StartLoc, EndLoc, CollapsedNum) {}
3465 /// Build an empty directive.
3467 /// \param CollapsedNum Number of collapsed nested loops.
3469 explicit OMPTaskLoopDirective(unsigned CollapsedNum)
3470 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3471 SourceLocation(), SourceLocation(), CollapsedNum) {}
3473 /// Set cancel state.
3474 void setHasCancel(bool Has) { HasCancel = Has; }
3477 /// Creates directive with a list of \a Clauses.
3479 /// \param C AST context.
3480 /// \param StartLoc Starting location of the directive kind.
3481 /// \param EndLoc Ending Location of the directive.
3482 /// \param CollapsedNum Number of collapsed loops.
3483 /// \param Clauses List of clauses.
3484 /// \param AssociatedStmt Statement, associated with the directive.
3485 /// \param Exprs Helper expressions for CodeGen.
3486 /// \param HasCancel true if this directive has inner cancel directive.
3488 static OMPTaskLoopDirective *
3489 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3490 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3491 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3493 /// Creates an empty directive with the place
3494 /// for \a NumClauses clauses.
3496 /// \param C AST context.
3497 /// \param CollapsedNum Number of collapsed nested loops.
3498 /// \param NumClauses Number of clauses.
3500 static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
3501 unsigned NumClauses,
3502 unsigned CollapsedNum, EmptyShell);
3504 /// Return true if current directive has inner cancel directive.
3505 bool hasCancel() const { return HasCancel; }
3507 static bool classof(const Stmt *T) {
3508 return T->getStmtClass() == OMPTaskLoopDirectiveClass;
3512 /// This represents '#pragma omp taskloop simd' directive.
3515 /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
3517 /// In this example directive '#pragma omp taskloop simd' has clauses 'private'
3518 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
3519 /// 'num_tasks' with expression 'num'.
3521 class OMPTaskLoopSimdDirective : public OMPLoopDirective {
3522 friend class ASTStmtReader;
3523 friend class OMPExecutableDirective;
3524 /// Build directive with the given start and end location.
3526 /// \param StartLoc Starting location of the directive kind.
3527 /// \param EndLoc Ending location of the directive.
3528 /// \param CollapsedNum Number of collapsed nested loops.
3530 OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3531 unsigned CollapsedNum)
3532 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3533 llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc,
3536 /// Build an empty directive.
3538 /// \param CollapsedNum Number of collapsed nested loops.
3540 explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum)
3541 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3542 llvm::omp::OMPD_taskloop_simd, SourceLocation(),
3543 SourceLocation(), CollapsedNum) {}
3546 /// Creates directive with a list of \a Clauses.
3548 /// \param C AST context.
3549 /// \param StartLoc Starting location of the directive kind.
3550 /// \param EndLoc Ending Location of the directive.
3551 /// \param CollapsedNum Number of collapsed loops.
3552 /// \param Clauses List of clauses.
3553 /// \param AssociatedStmt Statement, associated with the directive.
3554 /// \param Exprs Helper expressions for CodeGen.
3556 static OMPTaskLoopSimdDirective *
3557 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3558 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3559 Stmt *AssociatedStmt, const HelperExprs &Exprs);
3561 /// Creates an empty directive with the place
3562 /// for \a NumClauses clauses.
3564 /// \param C AST context.
3565 /// \param CollapsedNum Number of collapsed nested loops.
3566 /// \param NumClauses Number of clauses.
3568 static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
3569 unsigned NumClauses,
3570 unsigned CollapsedNum,
3573 static bool classof(const Stmt *T) {
3574 return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
3578 /// This represents '#pragma omp master taskloop' directive.
3581 /// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num)
3583 /// In this example directive '#pragma omp master taskloop' has clauses
3584 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3585 /// and 'num_tasks' with expression 'num'.
3587 class OMPMasterTaskLoopDirective : public OMPLoopDirective {
3588 friend class ASTStmtReader;
3589 friend class OMPExecutableDirective;
3590 /// true if the construct has inner cancel directive.
3591 bool HasCancel = false;
3593 /// Build directive with the given start and end location.
3595 /// \param StartLoc Starting location of the directive kind.
3596 /// \param EndLoc Ending location of the directive.
3597 /// \param CollapsedNum Number of collapsed nested loops.
3599 OMPMasterTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3600 unsigned CollapsedNum)
3601 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3602 llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc,
3605 /// Build an empty directive.
3607 /// \param CollapsedNum Number of collapsed nested loops.
3609 explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum)
3610 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3611 llvm::omp::OMPD_master_taskloop, SourceLocation(),
3612 SourceLocation(), CollapsedNum) {}
3614 /// Set cancel state.
3615 void setHasCancel(bool Has) { HasCancel = Has; }
3618 /// Creates directive with a list of \a Clauses.
3620 /// \param C AST context.
3621 /// \param StartLoc Starting location of the directive kind.
3622 /// \param EndLoc Ending Location of the directive.
3623 /// \param CollapsedNum Number of collapsed loops.
3624 /// \param Clauses List of clauses.
3625 /// \param AssociatedStmt Statement, associated with the directive.
3626 /// \param Exprs Helper expressions for CodeGen.
3627 /// \param HasCancel true if this directive has inner cancel directive.
3629 static OMPMasterTaskLoopDirective *
3630 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3631 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3632 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3634 /// Creates an empty directive with the place
3635 /// for \a NumClauses clauses.
3637 /// \param C AST context.
3638 /// \param CollapsedNum Number of collapsed nested loops.
3639 /// \param NumClauses Number of clauses.
3641 static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
3642 unsigned NumClauses,
3643 unsigned CollapsedNum,
3646 /// Return true if current directive has inner cancel directive.
3647 bool hasCancel() const { return HasCancel; }
3649 static bool classof(const Stmt *T) {
3650 return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass;
3654 /// This represents '#pragma omp master taskloop simd' directive.
3657 /// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num)
3659 /// In this example directive '#pragma omp master taskloop simd' has clauses
3660 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3661 /// and 'num_tasks' with expression 'num'.
3663 class OMPMasterTaskLoopSimdDirective : public OMPLoopDirective {
3664 friend class ASTStmtReader;
3665 friend class OMPExecutableDirective;
3666 /// Build directive with the given start and end location.
3668 /// \param StartLoc Starting location of the directive kind.
3669 /// \param EndLoc Ending location of the directive.
3670 /// \param CollapsedNum Number of collapsed nested loops.
3672 OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3673 unsigned CollapsedNum)
3674 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
3675 llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc,
3678 /// Build an empty directive.
3680 /// \param CollapsedNum Number of collapsed nested loops.
3682 explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum)
3683 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
3684 llvm::omp::OMPD_master_taskloop_simd, SourceLocation(),
3685 SourceLocation(), CollapsedNum) {}
3688 /// Creates directive with a list of \p Clauses.
3690 /// \param C AST context.
3691 /// \param StartLoc Starting location of the directive kind.
3692 /// \param EndLoc Ending Location of the directive.
3693 /// \param CollapsedNum Number of collapsed loops.
3694 /// \param Clauses List of clauses.
3695 /// \param AssociatedStmt Statement, associated with the directive.
3696 /// \param Exprs Helper expressions for CodeGen.
3698 static OMPMasterTaskLoopSimdDirective *
3699 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3700 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3701 Stmt *AssociatedStmt, const HelperExprs &Exprs);
3703 /// Creates an empty directive with the place for \p NumClauses clauses.
3705 /// \param C AST context.
3706 /// \param CollapsedNum Number of collapsed nested loops.
3707 /// \param NumClauses Number of clauses.
3709 static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
3710 unsigned NumClauses,
3711 unsigned CollapsedNum,
3714 static bool classof(const Stmt *T) {
3715 return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass;
3719 /// This represents '#pragma omp parallel master taskloop' directive.
3722 /// #pragma omp parallel master taskloop private(a,b) grainsize(val)
3725 /// In this example directive '#pragma omp parallel master taskloop' has clauses
3726 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3727 /// and 'num_tasks' with expression 'num'.
3729 class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective {
3730 friend class ASTStmtReader;
3731 friend class OMPExecutableDirective;
3732 /// true if the construct has inner cancel directive.
3733 bool HasCancel = false;
3735 /// Build directive with the given start and end location.
3737 /// \param StartLoc Starting location of the directive kind.
3738 /// \param EndLoc Ending location of the directive.
3739 /// \param CollapsedNum Number of collapsed nested loops.
3741 OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc,
3742 SourceLocation EndLoc,
3743 unsigned CollapsedNum)
3744 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
3745 llvm::omp::OMPD_parallel_master_taskloop, StartLoc,
3746 EndLoc, CollapsedNum) {}
3748 /// Build an empty directive.
3750 /// \param CollapsedNum Number of collapsed nested loops.
3752 explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum)
3753 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
3754 llvm::omp::OMPD_parallel_master_taskloop,
3755 SourceLocation(), SourceLocation(), CollapsedNum) {}
3757 /// Set cancel state.
3758 void setHasCancel(bool Has) { HasCancel = Has; }
3761 /// Creates directive with a list of \a Clauses.
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.
3772 static OMPParallelMasterTaskLoopDirective *
3773 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3774 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3775 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3777 /// Creates an empty directive with the place
3778 /// for \a NumClauses clauses.
3780 /// \param C AST context.
3781 /// \param CollapsedNum Number of collapsed nested loops.
3782 /// \param NumClauses Number of clauses.
3784 static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
3785 unsigned NumClauses,
3786 unsigned CollapsedNum,
3789 /// Return true if current directive has inner cancel directive.
3790 bool hasCancel() const { return HasCancel; }
3792 static bool classof(const Stmt *T) {
3793 return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass;
3797 /// This represents '#pragma omp parallel master taskloop simd' directive.
3800 /// #pragma omp parallel master taskloop simd private(a,b) grainsize(val)
3803 /// In this example directive '#pragma omp parallel master taskloop simd' has
3804 /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
3805 /// expression 'val' and 'num_tasks' with expression 'num'.
3807 class OMPParallelMasterTaskLoopSimdDirective : public OMPLoopDirective {
3808 friend class ASTStmtReader;
3809 friend class OMPExecutableDirective;
3810 /// Build directive with the given start and end location.
3812 /// \param StartLoc Starting location of the directive kind.
3813 /// \param EndLoc Ending location of the directive.
3814 /// \param CollapsedNum Number of collapsed nested loops.
3816 OMPParallelMasterTaskLoopSimdDirective(SourceLocation StartLoc,
3817 SourceLocation EndLoc,
3818 unsigned CollapsedNum)
3819 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
3820 llvm::omp::OMPD_parallel_master_taskloop_simd,
3821 StartLoc, EndLoc, CollapsedNum) {}
3823 /// Build an empty directive.
3825 /// \param CollapsedNum Number of collapsed nested loops.
3827 explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum)
3828 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
3829 llvm::omp::OMPD_parallel_master_taskloop_simd,
3830 SourceLocation(), SourceLocation(), CollapsedNum) {}
3833 /// Creates directive with a list of \p Clauses.
3835 /// \param C AST context.
3836 /// \param StartLoc Starting location of the directive kind.
3837 /// \param EndLoc Ending Location of the directive.
3838 /// \param CollapsedNum Number of collapsed loops.
3839 /// \param Clauses List of clauses.
3840 /// \param AssociatedStmt Statement, associated with the directive.
3841 /// \param Exprs Helper expressions for CodeGen.
3843 static OMPParallelMasterTaskLoopSimdDirective *
3844 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3845 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3846 Stmt *AssociatedStmt, const HelperExprs &Exprs);
3848 /// Creates an empty directive with the place
3849 /// for \a NumClauses clauses.
3851 /// \param C AST context.
3852 /// \param CollapsedNum Number of collapsed nested loops.
3853 /// \param NumClauses Number of clauses.
3855 static OMPParallelMasterTaskLoopSimdDirective *
3856 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
3859 static bool classof(const Stmt *T) {
3860 return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass;
3864 /// This represents '#pragma omp distribute' directive.
3867 /// #pragma omp distribute private(a,b)
3869 /// In this example directive '#pragma omp distribute' has clauses 'private'
3870 /// with the variables 'a' and 'b'
3872 class OMPDistributeDirective : public OMPLoopDirective {
3873 friend class ASTStmtReader;
3874 friend class OMPExecutableDirective;
3876 /// Build directive with the given start and end location.
3878 /// \param StartLoc Starting location of the directive kind.
3879 /// \param EndLoc Ending location of the directive.
3880 /// \param CollapsedNum Number of collapsed nested loops.
3882 OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3883 unsigned CollapsedNum)
3884 : OMPLoopDirective(OMPDistributeDirectiveClass,
3885 llvm::omp::OMPD_distribute, StartLoc, EndLoc,
3888 /// Build an empty directive.
3890 /// \param CollapsedNum Number of collapsed nested loops.
3892 explicit OMPDistributeDirective(unsigned CollapsedNum)
3893 : OMPLoopDirective(OMPDistributeDirectiveClass,
3894 llvm::omp::OMPD_distribute, SourceLocation(),
3895 SourceLocation(), CollapsedNum) {}
3898 /// Creates directive with a list of \a Clauses.
3900 /// \param C AST context.
3901 /// \param StartLoc Starting location of the directive kind.
3902 /// \param EndLoc Ending Location of the directive.
3903 /// \param CollapsedNum Number of collapsed loops.
3904 /// \param Clauses List of clauses.
3905 /// \param AssociatedStmt Statement, associated with the directive.
3906 /// \param Exprs Helper expressions for CodeGen.
3908 static OMPDistributeDirective *
3909 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3910 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3911 Stmt *AssociatedStmt, const HelperExprs &Exprs);
3913 /// Creates an empty directive with the place
3914 /// for \a NumClauses clauses.
3916 /// \param C AST context.
3917 /// \param CollapsedNum Number of collapsed nested loops.
3918 /// \param NumClauses Number of clauses.
3920 static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
3921 unsigned NumClauses,
3922 unsigned CollapsedNum, EmptyShell);
3924 static bool classof(const Stmt *T) {
3925 return T->getStmtClass() == OMPDistributeDirectiveClass;
3929 /// This represents '#pragma omp target update' directive.
3932 /// #pragma omp target update to(a) from(b) device(1)
3934 /// In this example directive '#pragma omp target update' has clause 'to' with
3935 /// argument 'a', clause 'from' with argument 'b' and clause 'device' with
3938 class OMPTargetUpdateDirective : public OMPExecutableDirective {
3939 friend class ASTStmtReader;
3940 friend class OMPExecutableDirective;
3941 /// Build directive with the given start and end location.
3943 /// \param StartLoc Starting location of the directive kind.
3944 /// \param EndLoc Ending Location of the directive.
3946 OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3947 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
3948 llvm::omp::OMPD_target_update, StartLoc,
3951 /// Build an empty directive.
3953 explicit OMPTargetUpdateDirective()
3954 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
3955 llvm::omp::OMPD_target_update, SourceLocation(),
3956 SourceLocation()) {}
3959 /// Creates directive with a list of \a Clauses.
3961 /// \param C AST context.
3962 /// \param StartLoc Starting location of the directive kind.
3963 /// \param EndLoc Ending Location of the directive.
3964 /// \param Clauses List of clauses.
3965 /// \param AssociatedStmt Statement, associated with the directive.
3967 static OMPTargetUpdateDirective *
3968 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3969 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3971 /// Creates an empty directive with the place for \a NumClauses
3974 /// \param C AST context.
3975 /// \param NumClauses The number of clauses.
3977 static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C,
3978 unsigned NumClauses, EmptyShell);
3980 static bool classof(const Stmt *T) {
3981 return T->getStmtClass() == OMPTargetUpdateDirectiveClass;
3985 /// This represents '#pragma omp distribute parallel for' composite
3989 /// #pragma omp distribute parallel for private(a,b)
3991 /// In this example directive '#pragma omp distribute parallel for' has clause
3992 /// 'private' with the variables 'a' and 'b'
3994 class OMPDistributeParallelForDirective : public OMPLoopDirective {
3995 friend class ASTStmtReader;
3996 friend class OMPExecutableDirective;
3997 /// true if the construct has inner cancel directive.
3998 bool HasCancel = false;
4000 /// Build directive with the given start and end location.
4002 /// \param StartLoc Starting location of the directive kind.
4003 /// \param EndLoc Ending location of the directive.
4004 /// \param CollapsedNum Number of collapsed nested loops.
4006 OMPDistributeParallelForDirective(SourceLocation StartLoc,
4007 SourceLocation EndLoc,
4008 unsigned CollapsedNum)
4009 : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4010 llvm::omp::OMPD_distribute_parallel_for, StartLoc,
4011 EndLoc, CollapsedNum) {}
4013 /// Build an empty directive.
4015 /// \param CollapsedNum Number of collapsed nested loops.
4017 explicit OMPDistributeParallelForDirective(unsigned CollapsedNum)
4018 : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4019 llvm::omp::OMPD_distribute_parallel_for,
4020 SourceLocation(), SourceLocation(), CollapsedNum) {}
4022 /// Sets special task reduction descriptor.
4023 void setTaskReductionRefExpr(Expr *E) {
4024 Data->getChildren()[numLoopChildren(
4025 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E;
4028 /// Set cancel state.
4029 void setHasCancel(bool Has) { HasCancel = Has; }
4032 /// Creates directive with a list of \a Clauses.
4034 /// \param C AST context.
4035 /// \param StartLoc Starting location of the directive kind.
4036 /// \param EndLoc Ending Location of the directive.
4037 /// \param CollapsedNum Number of collapsed loops.
4038 /// \param Clauses List of clauses.
4039 /// \param AssociatedStmt Statement, associated with the directive.
4040 /// \param Exprs Helper expressions for CodeGen.
4041 /// \param TaskRedRef Task reduction special reference expression to handle
4042 /// taskgroup descriptor.
4043 /// \param HasCancel true if this directive has inner cancel directive.
4045 static OMPDistributeParallelForDirective *
4046 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4047 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4048 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
4051 /// Creates an empty directive with the place
4052 /// for \a NumClauses clauses.
4054 /// \param C AST context.
4055 /// \param CollapsedNum Number of collapsed nested loops.
4056 /// \param NumClauses Number of clauses.
4058 static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C,
4059 unsigned NumClauses,
4060 unsigned CollapsedNum,
4063 /// Returns special task reduction reference expression.
4064 Expr *getTaskReductionRefExpr() {
4065 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
4066 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]);
4068 const Expr *getTaskReductionRefExpr() const {
4069 return const_cast<OMPDistributeParallelForDirective *>(this)
4070 ->getTaskReductionRefExpr();
4073 /// Return true if current directive has inner cancel directive.
4074 bool hasCancel() const { return HasCancel; }
4076 static bool classof(const Stmt *T) {
4077 return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
4081 /// This represents '#pragma omp distribute parallel for simd' composite
4085 /// #pragma omp distribute parallel for simd private(x)
4087 /// In this example directive '#pragma omp distribute parallel for simd' has
4088 /// clause 'private' with the variables 'x'
4090 class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective {
4091 friend class ASTStmtReader;
4092 friend class OMPExecutableDirective;
4094 /// Build directive with the given start and end location.
4096 /// \param StartLoc Starting location of the directive kind.
4097 /// \param EndLoc Ending location of the directive.
4098 /// \param CollapsedNum Number of collapsed nested loops.
4100 OMPDistributeParallelForSimdDirective(SourceLocation StartLoc,
4101 SourceLocation EndLoc,
4102 unsigned CollapsedNum)
4103 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4104 llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc,
4105 EndLoc, CollapsedNum) {}
4107 /// Build an empty directive.
4109 /// \param CollapsedNum Number of collapsed nested loops.
4111 explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum)
4112 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4113 llvm::omp::OMPD_distribute_parallel_for_simd,
4114 SourceLocation(), SourceLocation(), CollapsedNum) {}
4117 /// Creates directive with a list of \a Clauses.
4119 /// \param C AST context.
4120 /// \param StartLoc Starting location of the directive kind.
4121 /// \param EndLoc Ending Location of the directive.
4122 /// \param CollapsedNum Number of collapsed loops.
4123 /// \param Clauses List of clauses.
4124 /// \param AssociatedStmt Statement, associated with the directive.
4125 /// \param Exprs Helper expressions for CodeGen.
4127 static OMPDistributeParallelForSimdDirective *Create(
4128 const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4129 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4130 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4132 /// Creates an empty directive with the place for \a NumClauses clauses.
4134 /// \param C AST context.
4135 /// \param CollapsedNum Number of collapsed nested loops.
4136 /// \param NumClauses Number of clauses.
4138 static OMPDistributeParallelForSimdDirective *CreateEmpty(
4139 const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4142 static bool classof(const Stmt *T) {
4143 return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass;
4147 /// This represents '#pragma omp distribute simd' composite directive.
4150 /// #pragma omp distribute simd private(x)
4152 /// In this example directive '#pragma omp distribute simd' has clause
4153 /// 'private' with the variables 'x'
4155 class OMPDistributeSimdDirective final : public OMPLoopDirective {
4156 friend class ASTStmtReader;
4157 friend class OMPExecutableDirective;
4159 /// Build directive with the given start and end location.
4161 /// \param StartLoc Starting location of the directive kind.
4162 /// \param EndLoc Ending location of the directive.
4163 /// \param CollapsedNum Number of collapsed nested loops.
4165 OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4166 unsigned CollapsedNum)
4167 : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4168 llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc,
4171 /// Build an empty directive.
4173 /// \param CollapsedNum Number of collapsed nested loops.
4175 explicit OMPDistributeSimdDirective(unsigned CollapsedNum)
4176 : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4177 llvm::omp::OMPD_distribute_simd, SourceLocation(),
4178 SourceLocation(), CollapsedNum) {}
4181 /// Creates directive with a list of \a Clauses.
4183 /// \param C AST context.
4184 /// \param StartLoc Starting location of the directive kind.
4185 /// \param EndLoc Ending Location of the directive.
4186 /// \param CollapsedNum Number of collapsed loops.
4187 /// \param Clauses List of clauses.
4188 /// \param AssociatedStmt Statement, associated with the directive.
4189 /// \param Exprs Helper expressions for CodeGen.
4191 static OMPDistributeSimdDirective *
4192 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4193 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4194 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4196 /// Creates an empty directive with the place for \a NumClauses clauses.
4198 /// \param C AST context.
4199 /// \param CollapsedNum Number of collapsed nested loops.
4200 /// \param NumClauses Number of clauses.
4202 static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C,
4203 unsigned NumClauses,
4204 unsigned CollapsedNum,
4207 static bool classof(const Stmt *T) {
4208 return T->getStmtClass() == OMPDistributeSimdDirectiveClass;
4212 /// This represents '#pragma omp target parallel for simd' directive.
4215 /// #pragma omp target parallel for simd private(a) map(b) safelen(c)
4217 /// In this example directive '#pragma omp target parallel for simd' has clauses
4218 /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen'
4219 /// with the variable 'c'.
4221 class OMPTargetParallelForSimdDirective final : public OMPLoopDirective {
4222 friend class ASTStmtReader;
4223 friend class OMPExecutableDirective;
4225 /// Build directive with the given start and end location.
4227 /// \param StartLoc Starting location of the directive kind.
4228 /// \param EndLoc Ending location of the directive.
4229 /// \param CollapsedNum Number of collapsed nested loops.
4231 OMPTargetParallelForSimdDirective(SourceLocation StartLoc,
4232 SourceLocation EndLoc,
4233 unsigned CollapsedNum)
4234 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4235 llvm::omp::OMPD_target_parallel_for_simd, StartLoc,
4236 EndLoc, CollapsedNum) {}
4238 /// Build an empty directive.
4240 /// \param CollapsedNum Number of collapsed nested loops.
4242 explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum)
4243 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4244 llvm::omp::OMPD_target_parallel_for_simd,
4245 SourceLocation(), SourceLocation(), CollapsedNum) {}
4248 /// Creates directive with a list of \a Clauses.
4250 /// \param C AST context.
4251 /// \param StartLoc Starting location of the directive kind.
4252 /// \param EndLoc Ending Location of the directive.
4253 /// \param CollapsedNum Number of collapsed loops.
4254 /// \param Clauses List of clauses.
4255 /// \param AssociatedStmt Statement, associated with the directive.
4256 /// \param Exprs Helper expressions for CodeGen.
4258 static OMPTargetParallelForSimdDirective *
4259 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4260 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4261 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4263 /// Creates an empty directive with the place for \a NumClauses clauses.
4265 /// \param C AST context.
4266 /// \param CollapsedNum Number of collapsed nested loops.
4267 /// \param NumClauses Number of clauses.
4269 static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C,
4270 unsigned NumClauses,
4271 unsigned CollapsedNum,
4274 static bool classof(const Stmt *T) {
4275 return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
4279 /// This represents '#pragma omp target simd' directive.
4282 /// #pragma omp target simd private(a) map(b) safelen(c)
4284 /// In this example directive '#pragma omp target simd' has clauses 'private'
4285 /// with the variable 'a', 'map' with the variable 'b' and 'safelen' with
4286 /// the variable 'c'.
4288 class OMPTargetSimdDirective final : public OMPLoopDirective {
4289 friend class ASTStmtReader;
4290 friend class OMPExecutableDirective;
4292 /// Build directive with the given start and end location.
4294 /// \param StartLoc Starting location of the directive kind.
4295 /// \param EndLoc Ending location of the directive.
4296 /// \param CollapsedNum Number of collapsed nested loops.
4298 OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4299 unsigned CollapsedNum)
4300 : OMPLoopDirective(OMPTargetSimdDirectiveClass,
4301 llvm::omp::OMPD_target_simd, StartLoc, EndLoc,
4304 /// Build an empty directive.
4306 /// \param CollapsedNum Number of collapsed nested loops.
4308 explicit OMPTargetSimdDirective(unsigned CollapsedNum)
4309 : OMPLoopDirective(OMPTargetSimdDirectiveClass,
4310 llvm::omp::OMPD_target_simd, SourceLocation(),
4311 SourceLocation(), CollapsedNum) {}
4314 /// Creates directive with a list of \a Clauses.
4316 /// \param C AST context.
4317 /// \param StartLoc Starting location of the directive kind.
4318 /// \param EndLoc Ending Location of the directive.
4319 /// \param CollapsedNum Number of collapsed loops.
4320 /// \param Clauses List of clauses.
4321 /// \param AssociatedStmt Statement, associated with the directive.
4322 /// \param Exprs Helper expressions for CodeGen.
4324 static OMPTargetSimdDirective *
4325 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4326 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4327 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4329 /// Creates an empty directive with the place for \a NumClauses clauses.
4331 /// \param C AST context.
4332 /// \param CollapsedNum Number of collapsed nested loops.
4333 /// \param NumClauses Number of clauses.
4335 static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C,
4336 unsigned NumClauses,
4337 unsigned CollapsedNum,
4340 static bool classof(const Stmt *T) {
4341 return T->getStmtClass() == OMPTargetSimdDirectiveClass;
4345 /// This represents '#pragma omp teams distribute' directive.
4348 /// #pragma omp teams distribute private(a,b)
4350 /// In this example directive '#pragma omp teams distribute' has clauses
4351 /// 'private' with the variables 'a' and 'b'
4353 class OMPTeamsDistributeDirective final : public OMPLoopDirective {
4354 friend class ASTStmtReader;
4355 friend class OMPExecutableDirective;
4357 /// Build directive with the given start and end location.
4359 /// \param StartLoc Starting location of the directive kind.
4360 /// \param EndLoc Ending location of the directive.
4361 /// \param CollapsedNum Number of collapsed nested loops.
4363 OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4364 unsigned CollapsedNum)
4365 : OMPLoopDirective(OMPTeamsDistributeDirectiveClass,
4366 llvm::omp::OMPD_teams_distribute, StartLoc, EndLoc,
4369 /// Build an empty directive.
4371 /// \param CollapsedNum Number of collapsed nested loops.
4373 explicit OMPTeamsDistributeDirective(unsigned CollapsedNum)
4374 : OMPLoopDirective(OMPTeamsDistributeDirectiveClass,
4375 llvm::omp::OMPD_teams_distribute, SourceLocation(),
4376 SourceLocation(), CollapsedNum) {}
4379 /// Creates directive with a list of \a Clauses.
4381 /// \param C AST context.
4382 /// \param StartLoc Starting location of the directive kind.
4383 /// \param EndLoc Ending Location of the directive.
4384 /// \param CollapsedNum Number of collapsed loops.
4385 /// \param Clauses List of clauses.
4386 /// \param AssociatedStmt Statement, associated with the directive.
4387 /// \param Exprs Helper expressions for CodeGen.
4389 static OMPTeamsDistributeDirective *
4390 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4391 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4392 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4394 /// Creates an empty directive with the place for \a NumClauses clauses.
4396 /// \param C AST context.
4397 /// \param CollapsedNum Number of collapsed nested loops.
4398 /// \param NumClauses Number of clauses.
4400 static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C,
4401 unsigned NumClauses,
4402 unsigned CollapsedNum,
4405 static bool classof(const Stmt *T) {
4406 return T->getStmtClass() == OMPTeamsDistributeDirectiveClass;
4410 /// This represents '#pragma omp teams distribute simd'
4411 /// combined directive.
4414 /// #pragma omp teams distribute simd private(a,b)
4416 /// In this example directive '#pragma omp teams distribute simd'
4417 /// has clause 'private' with the variables 'a' and 'b'
4419 class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective {
4420 friend class ASTStmtReader;
4421 friend class OMPExecutableDirective;
4423 /// Build directive with the given start and end location.
4425 /// \param StartLoc Starting location of the directive kind.
4426 /// \param EndLoc Ending location of the directive.
4427 /// \param CollapsedNum Number of collapsed nested loops.
4429 OMPTeamsDistributeSimdDirective(SourceLocation StartLoc,
4430 SourceLocation EndLoc, unsigned CollapsedNum)
4431 : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass,
4432 llvm::omp::OMPD_teams_distribute_simd, StartLoc,
4433 EndLoc, CollapsedNum) {}
4435 /// Build an empty directive.
4437 /// \param CollapsedNum Number of collapsed nested loops.
4439 explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum)
4440 : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass,
4441 llvm::omp::OMPD_teams_distribute_simd,
4442 SourceLocation(), SourceLocation(), CollapsedNum) {}
4445 /// Creates directive with a list of \a Clauses.
4447 /// \param C AST context.
4448 /// \param StartLoc Starting location of the directive kind.
4449 /// \param EndLoc Ending Location of the directive.
4450 /// \param CollapsedNum Number of collapsed loops.
4451 /// \param Clauses List of clauses.
4452 /// \param AssociatedStmt Statement, associated with the directive.
4453 /// \param Exprs Helper expressions for CodeGen.
4455 static OMPTeamsDistributeSimdDirective *
4456 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4457 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4458 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4460 /// Creates an empty directive with the place
4461 /// for \a NumClauses clauses.
4463 /// \param C AST context.
4464 /// \param CollapsedNum Number of collapsed nested loops.
4465 /// \param NumClauses Number of clauses.
4467 static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C,
4468 unsigned NumClauses,
4469 unsigned CollapsedNum,
4472 static bool classof(const Stmt *T) {
4473 return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass;
4477 /// This represents '#pragma omp teams distribute parallel for simd' composite
4481 /// #pragma omp teams distribute parallel for simd private(x)
4483 /// In this example directive '#pragma omp teams distribute parallel for simd'
4484 /// has clause 'private' with the variables 'x'
4486 class OMPTeamsDistributeParallelForSimdDirective final
4487 : public OMPLoopDirective {
4488 friend class ASTStmtReader;
4489 friend class OMPExecutableDirective;
4491 /// Build directive with the given start and end location.
4493 /// \param StartLoc Starting location of the directive kind.
4494 /// \param EndLoc Ending location of the directive.
4495 /// \param CollapsedNum Number of collapsed nested loops.
4497 OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
4498 SourceLocation EndLoc,
4499 unsigned CollapsedNum)
4500 : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass,
4501 llvm::omp::OMPD_teams_distribute_parallel_for_simd,
4502 StartLoc, EndLoc, CollapsedNum) {}
4504 /// Build an empty directive.
4506 /// \param CollapsedNum Number of collapsed nested loops.
4508 explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum)
4509 : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass,
4510 llvm::omp::OMPD_teams_distribute_parallel_for_simd,
4511 SourceLocation(), SourceLocation(), CollapsedNum) {}
4514 /// Creates directive with a list of \a Clauses.
4516 /// \param C AST context.
4517 /// \param StartLoc Starting location of the directive kind.
4518 /// \param EndLoc Ending Location of the directive.
4519 /// \param CollapsedNum Number of collapsed loops.
4520 /// \param Clauses List of clauses.
4521 /// \param AssociatedStmt Statement, associated with the directive.
4522 /// \param Exprs Helper expressions for CodeGen.
4524 static OMPTeamsDistributeParallelForSimdDirective *
4525 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4526 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4527 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4529 /// Creates an empty directive with the place for \a NumClauses clauses.
4531 /// \param C AST context.
4532 /// \param CollapsedNum Number of collapsed nested loops.
4533 /// \param NumClauses Number of clauses.
4535 static OMPTeamsDistributeParallelForSimdDirective *
4536 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4539 static bool classof(const Stmt *T) {
4540 return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass;
4544 /// This represents '#pragma omp teams distribute parallel for' composite
4548 /// #pragma omp teams distribute parallel for private(x)
4550 /// In this example directive '#pragma omp teams distribute parallel for'
4551 /// has clause 'private' with the variables 'x'
4553 class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
4554 friend class ASTStmtReader;
4555 friend class OMPExecutableDirective;
4556 /// true if the construct has inner cancel directive.
4557 bool HasCancel = false;
4559 /// Build directive with the given start and end location.
4561 /// \param StartLoc Starting location of the directive kind.
4562 /// \param EndLoc Ending location of the directive.
4563 /// \param CollapsedNum Number of collapsed nested loops.
4565 OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc,
4566 SourceLocation EndLoc,
4567 unsigned CollapsedNum)
4568 : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass,
4569 llvm::omp::OMPD_teams_distribute_parallel_for,
4570 StartLoc, EndLoc, CollapsedNum) {}
4572 /// Build an empty directive.
4574 /// \param CollapsedNum Number of collapsed nested loops.
4576 explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum)
4577 : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass,
4578 llvm::omp::OMPD_teams_distribute_parallel_for,
4579 SourceLocation(), SourceLocation(), CollapsedNum) {}
4581 /// Sets special task reduction descriptor.
4582 void setTaskReductionRefExpr(Expr *E) {
4583 Data->getChildren()[numLoopChildren(
4584 getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)] = E;
4587 /// Set cancel state.
4588 void setHasCancel(bool Has) { HasCancel = Has; }
4591 /// Creates directive with a list of \a Clauses.
4593 /// \param C AST context.
4594 /// \param StartLoc Starting location of the directive kind.
4595 /// \param EndLoc Ending Location of the directive.
4596 /// \param CollapsedNum Number of collapsed loops.
4597 /// \param Clauses List of clauses.
4598 /// \param AssociatedStmt Statement, associated with the directive.
4599 /// \param Exprs Helper expressions for CodeGen.
4600 /// \param TaskRedRef Task reduction special reference expression to handle
4601 /// taskgroup descriptor.
4602 /// \param HasCancel true if this directive has inner cancel directive.
4604 static OMPTeamsDistributeParallelForDirective *
4605 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4606 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4607 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
4610 /// Creates an empty directive with the place for \a NumClauses clauses.
4612 /// \param C AST context.
4613 /// \param CollapsedNum Number of collapsed nested loops.
4614 /// \param NumClauses Number of clauses.
4616 static OMPTeamsDistributeParallelForDirective *
4617 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4620 /// Returns special task reduction reference expression.
4621 Expr *getTaskReductionRefExpr() {
4622 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
4623 getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)]);
4625 const Expr *getTaskReductionRefExpr() const {
4626 return const_cast<OMPTeamsDistributeParallelForDirective *>(this)
4627 ->getTaskReductionRefExpr();
4630 /// Return true if current directive has inner cancel directive.
4631 bool hasCancel() const { return HasCancel; }
4633 static bool classof(const Stmt *T) {
4634 return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass;
4638 /// This represents '#pragma omp target teams' directive.
4641 /// #pragma omp target teams if(a>0)
4643 /// In this example directive '#pragma omp target teams' has clause 'if' with
4644 /// condition 'a>0'.
4646 class OMPTargetTeamsDirective final : public OMPExecutableDirective {
4647 friend class ASTStmtReader;
4648 friend class OMPExecutableDirective;
4649 /// Build directive with the given start and end location.
4651 /// \param StartLoc Starting location of the directive kind.
4652 /// \param EndLoc Ending location of the directive.
4654 OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
4655 : OMPExecutableDirective(OMPTargetTeamsDirectiveClass,
4656 llvm::omp::OMPD_target_teams, StartLoc, EndLoc) {
4659 /// Build an empty directive.
4661 explicit OMPTargetTeamsDirective()
4662 : OMPExecutableDirective(OMPTargetTeamsDirectiveClass,
4663 llvm::omp::OMPD_target_teams, SourceLocation(),
4664 SourceLocation()) {}
4667 /// Creates directive with a list of \a Clauses.
4669 /// \param C AST context.
4670 /// \param StartLoc Starting location of the directive kind.
4671 /// \param EndLoc Ending Location of the directive.
4672 /// \param Clauses List of clauses.
4673 /// \param AssociatedStmt Statement, associated with the directive.
4675 static OMPTargetTeamsDirective *Create(const ASTContext &C,
4676 SourceLocation StartLoc,
4677 SourceLocation EndLoc,
4678 ArrayRef<OMPClause *> Clauses,
4679 Stmt *AssociatedStmt);
4681 /// Creates an empty directive with the place for \a NumClauses clauses.
4683 /// \param C AST context.
4684 /// \param NumClauses Number of clauses.
4686 static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C,
4687 unsigned NumClauses, EmptyShell);
4689 static bool classof(const Stmt *T) {
4690 return T->getStmtClass() == OMPTargetTeamsDirectiveClass;
4694 /// This represents '#pragma omp target teams distribute' combined directive.
4697 /// #pragma omp target teams distribute private(x)
4699 /// In this example directive '#pragma omp target teams distribute' has clause
4700 /// 'private' with the variables 'x'
4702 class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective {
4703 friend class ASTStmtReader;
4704 friend class OMPExecutableDirective;
4706 /// Build directive with the given start and end location.
4708 /// \param StartLoc Starting location of the directive kind.
4709 /// \param EndLoc Ending location of the directive.
4710 /// \param CollapsedNum Number of collapsed nested loops.
4712 OMPTargetTeamsDistributeDirective(SourceLocation StartLoc,
4713 SourceLocation EndLoc,
4714 unsigned CollapsedNum)
4715 : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass,
4716 llvm::omp::OMPD_target_teams_distribute, StartLoc,
4717 EndLoc, CollapsedNum) {}
4719 /// Build an empty directive.
4721 /// \param CollapsedNum Number of collapsed nested loops.
4723 explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum)
4724 : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass,
4725 llvm::omp::OMPD_target_teams_distribute,
4726 SourceLocation(), SourceLocation(), CollapsedNum) {}
4729 /// Creates directive with a list of \a Clauses.
4731 /// \param C AST context.
4732 /// \param StartLoc Starting location of the directive kind.
4733 /// \param EndLoc Ending Location of the directive.
4734 /// \param CollapsedNum Number of collapsed loops.
4735 /// \param Clauses List of clauses.
4736 /// \param AssociatedStmt Statement, associated with the directive.
4737 /// \param Exprs Helper expressions for CodeGen.
4739 static OMPTargetTeamsDistributeDirective *
4740 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4741 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4742 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4744 /// Creates an empty directive with the place for \a NumClauses clauses.
4746 /// \param C AST context.
4747 /// \param CollapsedNum Number of collapsed nested loops.
4748 /// \param NumClauses Number of clauses.
4750 static OMPTargetTeamsDistributeDirective *
4751 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4754 static bool classof(const Stmt *T) {
4755 return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass;
4759 /// This represents '#pragma omp target teams distribute parallel for' combined
4763 /// #pragma omp target teams distribute parallel for private(x)
4765 /// In this example directive '#pragma omp target teams distribute parallel
4766 /// for' has clause 'private' with the variables 'x'
4768 class OMPTargetTeamsDistributeParallelForDirective final
4769 : public OMPLoopDirective {
4770 friend class ASTStmtReader;
4771 friend class OMPExecutableDirective;
4772 /// true if the construct has inner cancel directive.
4773 bool HasCancel = false;
4775 /// Build directive with the given start and end location.
4777 /// \param StartLoc Starting location of the directive kind.
4778 /// \param EndLoc Ending location of the directive.
4779 /// \param CollapsedNum Number of collapsed nested loops.
4781 OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc,
4782 SourceLocation EndLoc,
4783 unsigned CollapsedNum)
4784 : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass,
4785 llvm::omp::OMPD_target_teams_distribute_parallel_for,
4786 StartLoc, EndLoc, CollapsedNum) {}
4788 /// Build an empty directive.
4790 /// \param CollapsedNum Number of collapsed nested loops.
4792 explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum)
4793 : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass,
4794 llvm::omp::OMPD_target_teams_distribute_parallel_for,
4795 SourceLocation(), SourceLocation(), CollapsedNum) {}
4797 /// Sets special task reduction descriptor.
4798 void setTaskReductionRefExpr(Expr *E) {
4799 Data->getChildren()[numLoopChildren(
4801 llvm::omp::OMPD_target_teams_distribute_parallel_for)] = E;
4804 /// Set cancel state.
4805 void setHasCancel(bool Has) { HasCancel = Has; }
4808 /// Creates directive with a list of \a Clauses.
4810 /// \param C AST context.
4811 /// \param StartLoc Starting location of the directive kind.
4812 /// \param EndLoc Ending Location of the directive.
4813 /// \param CollapsedNum Number of collapsed loops.
4814 /// \param Clauses List of clauses.
4815 /// \param AssociatedStmt Statement, associated with the directive.
4816 /// \param Exprs Helper expressions for CodeGen.
4817 /// \param TaskRedRef Task reduction special reference expression to handle
4818 /// taskgroup descriptor.
4819 /// \param HasCancel true if this directive has inner cancel directive.
4821 static OMPTargetTeamsDistributeParallelForDirective *
4822 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4823 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4824 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
4827 /// Creates an empty directive with the place for \a NumClauses clauses.
4829 /// \param C AST context.
4830 /// \param CollapsedNum Number of collapsed nested loops.
4831 /// \param NumClauses Number of clauses.
4833 static OMPTargetTeamsDistributeParallelForDirective *
4834 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4837 /// Returns special task reduction reference expression.
4838 Expr *getTaskReductionRefExpr() {
4839 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
4841 llvm::omp::OMPD_target_teams_distribute_parallel_for)]);
4843 const Expr *getTaskReductionRefExpr() const {
4844 return const_cast<OMPTargetTeamsDistributeParallelForDirective *>(this)
4845 ->getTaskReductionRefExpr();
4848 /// Return true if current directive has inner cancel directive.
4849 bool hasCancel() const { return HasCancel; }
4851 static bool classof(const Stmt *T) {
4852 return T->getStmtClass() ==
4853 OMPTargetTeamsDistributeParallelForDirectiveClass;
4857 /// This represents '#pragma omp target teams distribute parallel for simd'
4858 /// combined directive.
4861 /// #pragma omp target teams distribute parallel for simd private(x)
4863 /// In this example directive '#pragma omp target teams distribute parallel
4864 /// for simd' has clause 'private' with the variables 'x'
4866 class OMPTargetTeamsDistributeParallelForSimdDirective final
4867 : public OMPLoopDirective {
4868 friend class ASTStmtReader;
4869 friend class OMPExecutableDirective;
4871 /// Build directive with the given start and end location.
4873 /// \param StartLoc Starting location of the directive kind.
4874 /// \param EndLoc Ending location of the directive.
4875 /// \param CollapsedNum Number of collapsed nested loops.
4877 OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
4878 SourceLocation EndLoc,
4879 unsigned CollapsedNum)
4881 OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
4882 llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, StartLoc,
4883 EndLoc, CollapsedNum) {}
4885 /// Build an empty directive.
4887 /// \param CollapsedNum Number of collapsed nested loops.
4889 explicit OMPTargetTeamsDistributeParallelForSimdDirective(
4890 unsigned CollapsedNum)
4892 OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
4893 llvm::omp::OMPD_target_teams_distribute_parallel_for_simd,
4894 SourceLocation(), SourceLocation(), CollapsedNum) {}
4897 /// Creates directive with a list of \a Clauses.
4899 /// \param C AST context.
4900 /// \param StartLoc Starting location of the directive kind.
4901 /// \param EndLoc Ending Location of the directive.
4902 /// \param CollapsedNum Number of collapsed loops.
4903 /// \param Clauses List of clauses.
4904 /// \param AssociatedStmt Statement, associated with the directive.
4905 /// \param Exprs Helper expressions for CodeGen.
4907 static OMPTargetTeamsDistributeParallelForSimdDirective *
4908 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4909 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4910 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4912 /// Creates an empty directive with the place for \a NumClauses clauses.
4914 /// \param C AST context.
4915 /// \param CollapsedNum Number of collapsed nested loops.
4916 /// \param NumClauses Number of clauses.
4918 static OMPTargetTeamsDistributeParallelForSimdDirective *
4919 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4922 static bool classof(const Stmt *T) {
4923 return T->getStmtClass() ==
4924 OMPTargetTeamsDistributeParallelForSimdDirectiveClass;
4928 /// This represents '#pragma omp target teams distribute simd' combined
4932 /// #pragma omp target teams distribute simd private(x)
4934 /// In this example directive '#pragma omp target teams distribute simd'
4935 /// has clause 'private' with the variables 'x'
4937 class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective {
4938 friend class ASTStmtReader;
4939 friend class OMPExecutableDirective;
4941 /// Build directive with the given start and end location.
4943 /// \param StartLoc Starting location of the directive kind.
4944 /// \param EndLoc Ending location of the directive.
4945 /// \param CollapsedNum Number of collapsed nested loops.
4947 OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc,
4948 SourceLocation EndLoc,
4949 unsigned CollapsedNum)
4950 : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass,
4951 llvm::omp::OMPD_target_teams_distribute_simd, StartLoc,
4952 EndLoc, CollapsedNum) {}
4954 /// Build an empty directive.
4956 /// \param CollapsedNum Number of collapsed nested loops.
4958 explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum)
4959 : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass,
4960 llvm::omp::OMPD_target_teams_distribute_simd,
4961 SourceLocation(), SourceLocation(), CollapsedNum) {}
4964 /// Creates directive with a list of \a Clauses.
4966 /// \param C AST context.
4967 /// \param StartLoc Starting location of the directive kind.
4968 /// \param EndLoc Ending Location of the directive.
4969 /// \param CollapsedNum Number of collapsed loops.
4970 /// \param Clauses List of clauses.
4971 /// \param AssociatedStmt Statement, associated with the directive.
4972 /// \param Exprs Helper expressions for CodeGen.
4974 static OMPTargetTeamsDistributeSimdDirective *
4975 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4976 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4977 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4979 /// Creates an empty directive with the place for \a NumClauses clauses.
4981 /// \param C AST context.
4982 /// \param CollapsedNum Number of collapsed nested loops.
4983 /// \param NumClauses Number of clauses.
4985 static OMPTargetTeamsDistributeSimdDirective *
4986 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4989 static bool classof(const Stmt *T) {
4990 return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
4994 /// This represents the '#pragma omp tile' loop transformation directive.
4995 class OMPTileDirective final : public OMPLoopBasedDirective {
4996 friend class ASTStmtReader;
4997 friend class OMPExecutableDirective;
4999 /// Default list of offsets.
5002 TransformedStmtOffset,
5005 explicit OMPTileDirective(SourceLocation StartLoc, SourceLocation EndLoc,
5007 : OMPLoopBasedDirective(OMPTileDirectiveClass, llvm::omp::OMPD_tile,
5008 StartLoc, EndLoc, NumLoops) {}
5010 void setPreInits(Stmt *PreInits) {
5011 Data->getChildren()[PreInitsOffset] = PreInits;
5014 void setTransformedStmt(Stmt *S) {
5015 Data->getChildren()[TransformedStmtOffset] = S;
5019 /// Create a new AST node representation for '#pragma omp tile'.
5021 /// \param C Context of the AST.
5022 /// \param StartLoc Location of the introducer (e.g. the 'omp' token).
5023 /// \param EndLoc Location of the directive's end (e.g. the tok::eod).
5024 /// \param Clauses The directive's clauses.
5025 /// \param NumLoops Number of associated loops (number of items in the
5026 /// 'sizes' clause).
5027 /// \param AssociatedStmt The outermost associated loop.
5028 /// \param TransformedStmt The loop nest after tiling, or nullptr in
5029 /// dependent contexts.
5030 /// \param PreInits Helper preinits statements for the loop nest.
5031 static OMPTileDirective *Create(const ASTContext &C, SourceLocation StartLoc,
5032 SourceLocation EndLoc,
5033 ArrayRef<OMPClause *> Clauses,
5034 unsigned NumLoops, Stmt *AssociatedStmt,
5035 Stmt *TransformedStmt, Stmt *PreInits);
5037 /// Build an empty '#pragma omp tile' AST node for deserialization.
5039 /// \param C Context of the AST.
5040 /// \param NumClauses Number of clauses to allocate.
5041 /// \param NumLoops Number of associated loops to allocate.
5042 static OMPTileDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
5045 unsigned getNumAssociatedLoops() const { return getLoopsNumber(); }
5047 /// Gets/sets the associated loops after tiling.
5049 /// This is in de-sugared format stored as a CompoundStmt.
5056 /// Note that if the generated loops a become associated loops of another
5057 /// directive, they may need to be hoisted before them.
5058 Stmt *getTransformedStmt() const {
5059 return Data->getChildren()[TransformedStmtOffset];
5062 /// Return preinits statement.
5063 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
5065 static bool classof(const Stmt *T) {
5066 return T->getStmtClass() == OMPTileDirectiveClass;
5070 /// This represents the '#pragma omp unroll' loop transformation directive.
5073 /// #pragma omp unroll
5074 /// for (int i = 0; i < 64; ++i)
5076 class OMPUnrollDirective final : public OMPLoopBasedDirective {
5077 friend class ASTStmtReader;
5078 friend class OMPExecutableDirective;
5080 /// Default list of offsets.
5083 TransformedStmtOffset,
5086 explicit OMPUnrollDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5087 : OMPLoopBasedDirective(OMPUnrollDirectiveClass, llvm::omp::OMPD_unroll,
5088 StartLoc, EndLoc, 1) {}
5090 /// Set the pre-init statements.
5091 void setPreInits(Stmt *PreInits) {
5092 Data->getChildren()[PreInitsOffset] = PreInits;
5095 /// Set the de-sugared statement.
5096 void setTransformedStmt(Stmt *S) {
5097 Data->getChildren()[TransformedStmtOffset] = S;
5101 /// Create a new AST node representation for '#pragma omp unroll'.
5103 /// \param C Context of the AST.
5104 /// \param StartLoc Location of the introducer (e.g. the 'omp' token).
5105 /// \param EndLoc Location of the directive's end (e.g. the tok::eod).
5106 /// \param Clauses The directive's clauses.
5107 /// \param AssociatedStmt The outermost associated loop.
5108 /// \param TransformedStmt The loop nest after tiling, or nullptr in
5109 /// dependent contexts.
5110 /// \param PreInits Helper preinits statements for the loop nest.
5111 static OMPUnrollDirective *
5112 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5113 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
5114 Stmt *TransformedStmt, Stmt *PreInits);
5116 /// Build an empty '#pragma omp unroll' AST node for deserialization.
5118 /// \param C Context of the AST.
5119 /// \param NumClauses Number of clauses to allocate.
5120 static OMPUnrollDirective *CreateEmpty(const ASTContext &C,
5121 unsigned NumClauses);
5123 /// Get the de-sugared associated loops after unrolling.
5125 /// This is only used if the unrolled loop becomes an associated loop of
5126 /// another directive, otherwise the loop is emitted directly using loop
5127 /// transformation metadata. When the unrolled loop cannot be used by another
5128 /// directive (e.g. because of the full clause), the transformed stmt can also
5130 Stmt *getTransformedStmt() const {
5131 return Data->getChildren()[TransformedStmtOffset];
5134 /// Return the pre-init statements.
5135 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
5137 static bool classof(const Stmt *T) {
5138 return T->getStmtClass() == OMPUnrollDirectiveClass;
5142 /// This represents '#pragma omp scan' directive.
5145 /// #pragma omp scan inclusive(a)
5147 /// In this example directive '#pragma omp scan' has clause 'inclusive' with
5149 class OMPScanDirective final : public OMPExecutableDirective {
5150 friend class ASTStmtReader;
5151 friend class OMPExecutableDirective;
5152 /// Build directive with the given start and end location.
5154 /// \param StartLoc Starting location of the directive kind.
5155 /// \param EndLoc Ending location of the directive.
5157 OMPScanDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5158 : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan,
5159 StartLoc, EndLoc) {}
5161 /// Build an empty directive.
5163 explicit OMPScanDirective()
5164 : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan,
5165 SourceLocation(), SourceLocation()) {}
5168 /// Creates directive with a list of \a Clauses.
5170 /// \param C AST context.
5171 /// \param StartLoc Starting location of the directive kind.
5172 /// \param EndLoc Ending Location of the directive.
5173 /// \param Clauses List of clauses (only single OMPFlushClause clause is
5176 static OMPScanDirective *Create(const ASTContext &C, SourceLocation StartLoc,
5177 SourceLocation EndLoc,
5178 ArrayRef<OMPClause *> Clauses);
5180 /// Creates an empty directive with the place for \a NumClauses
5183 /// \param C AST context.
5184 /// \param NumClauses Number of clauses.
5186 static OMPScanDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
5189 static bool classof(const Stmt *T) {
5190 return T->getStmtClass() == OMPScanDirectiveClass;
5194 /// This represents '#pragma omp interop' directive.
5197 /// #pragma omp interop init(target:obj) device(x) depend(inout:y) nowait
5199 /// In this example directive '#pragma omp interop' has
5200 /// clauses 'init', 'device', 'depend' and 'nowait'.
5202 class OMPInteropDirective final : public OMPExecutableDirective {
5203 friend class ASTStmtReader;
5204 friend class OMPExecutableDirective;
5206 /// Build directive with the given start and end location.
5208 /// \param StartLoc Starting location of the directive.
5209 /// \param EndLoc Ending location of the directive.
5211 OMPInteropDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5212 : OMPExecutableDirective(OMPInteropDirectiveClass,
5213 llvm::omp::OMPD_interop, StartLoc, EndLoc) {}
5215 /// Build an empty directive.
5217 explicit OMPInteropDirective()
5218 : OMPExecutableDirective(OMPInteropDirectiveClass,
5219 llvm::omp::OMPD_interop, SourceLocation(),
5220 SourceLocation()) {}
5223 /// Creates directive.
5225 /// \param C AST context.
5226 /// \param StartLoc Starting location of the directive.
5227 /// \param EndLoc Ending Location of the directive.
5228 /// \param Clauses The directive's clauses.
5230 static OMPInteropDirective *Create(const ASTContext &C,
5231 SourceLocation StartLoc,
5232 SourceLocation EndLoc,
5233 ArrayRef<OMPClause *> Clauses);
5235 /// Creates an empty directive.
5237 /// \param C AST context.
5239 static OMPInteropDirective *CreateEmpty(const ASTContext &C,
5240 unsigned NumClauses, EmptyShell);
5242 static bool classof(const Stmt *T) {
5243 return T->getStmtClass() == OMPInteropDirectiveClass;
5247 /// This represents '#pragma omp dispatch' directive.
5250 /// #pragma omp dispatch device(dnum)
5252 /// This example shows a directive '#pragma omp dispatch' with a
5253 /// device clause with variable 'dnum'.
5255 class OMPDispatchDirective final : public OMPExecutableDirective {
5256 friend class ASTStmtReader;
5257 friend class OMPExecutableDirective;
5259 /// The location of the target-call.
5260 SourceLocation TargetCallLoc;
5262 /// Set the location of the target-call.
5263 void setTargetCallLoc(SourceLocation Loc) { TargetCallLoc = Loc; }
5265 /// Build directive with the given start and end location.
5267 /// \param StartLoc Starting location of the directive kind.
5268 /// \param EndLoc Ending location of the directive.
5270 OMPDispatchDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5271 : OMPExecutableDirective(OMPDispatchDirectiveClass,
5272 llvm::omp::OMPD_dispatch, StartLoc, EndLoc) {}
5274 /// Build an empty directive.
5276 explicit OMPDispatchDirective()
5277 : OMPExecutableDirective(OMPDispatchDirectiveClass,
5278 llvm::omp::OMPD_dispatch, SourceLocation(),
5279 SourceLocation()) {}
5282 /// Creates directive with a list of \a Clauses.
5284 /// \param C AST context.
5285 /// \param StartLoc Starting location of the directive kind.
5286 /// \param EndLoc Ending Location of the directive.
5287 /// \param Clauses List of clauses.
5288 /// \param AssociatedStmt Statement, associated with the directive.
5289 /// \param TargetCallLoc Location of the target-call.
5291 static OMPDispatchDirective *
5292 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5293 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
5294 SourceLocation TargetCallLoc);
5296 /// Creates an empty directive with the place for \a NumClauses
5299 /// \param C AST context.
5300 /// \param NumClauses Number of clauses.
5302 static OMPDispatchDirective *CreateEmpty(const ASTContext &C,
5303 unsigned NumClauses, EmptyShell);
5305 /// Return location of target-call.
5306 SourceLocation getTargetCallLoc() const { return TargetCallLoc; }
5308 static bool classof(const Stmt *T) {
5309 return T->getStmtClass() == OMPDispatchDirectiveClass;
5313 /// This represents '#pragma omp masked' directive.
5315 /// #pragma omp masked filter(tid)
5317 /// This example shows a directive '#pragma omp masked' with a filter clause
5318 /// with variable 'tid'.
5320 class OMPMaskedDirective final : public OMPExecutableDirective {
5321 friend class ASTStmtReader;
5322 friend class OMPExecutableDirective;
5324 /// Build directive with the given start and end location.
5326 /// \param StartLoc Starting location of the directive kind.
5327 /// \param EndLoc Ending location of the directive.
5329 OMPMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5330 : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked,
5331 StartLoc, EndLoc) {}
5333 /// Build an empty directive.
5335 explicit OMPMaskedDirective()
5336 : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked,
5337 SourceLocation(), SourceLocation()) {}
5340 /// Creates directive.
5342 /// \param C AST context.
5343 /// \param StartLoc Starting location of the directive kind.
5344 /// \param EndLoc Ending Location of the directive.
5345 /// \param AssociatedStmt Statement, associated with the directive.
5347 static OMPMaskedDirective *
5348 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5349 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
5351 /// Creates an empty directive.
5353 /// \param C AST context.
5355 static OMPMaskedDirective *CreateEmpty(const ASTContext &C,
5356 unsigned NumClauses, EmptyShell);
5358 static bool classof(const Stmt *T) {
5359 return T->getStmtClass() == OMPMaskedDirectiveClass;
5363 } // end namespace clang