clang 20.0.0git
StmtOpenMP.h
Go to the documentation of this file.
1//===- StmtOpenMP.h - Classes for OpenMP directives ------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file defines OpenMP AST classes for executable directives and
10/// clauses.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_STMTOPENMP_H
15#define LLVM_CLANG_AST_STMTOPENMP_H
16
18#include "clang/AST/Expr.h"
20#include "clang/AST/Stmt.h"
21#include "clang/AST/StmtCXX.h"
24
25namespace clang {
26
27//===----------------------------------------------------------------------===//
28// AST classes for directives.
29//===----------------------------------------------------------------------===//
30
31/// Representation of an OpenMP canonical loop.
32///
33/// OpenMP 1.0 C/C++, section 2.4.1 for Construct; canonical-shape
34/// OpenMP 2.0 C/C++, section 2.4.1 for Construct; canonical-shape
35/// OpenMP 2.5, section 2.5.1 Loop Construct; canonical form
36/// OpenMP 3.1, section 2.5.1 Loop Construct; canonical form
37/// OpenMP 4.0, section 2.6 Canonical Loop Form
38/// OpenMP 4.5, section 2.6 Canonical Loop Form
39/// OpenMP 5.0, section 2.9.1 Canonical Loop Form
40/// OpenMP 5.1, section 2.11.1 Canonical Loop Nest Form
41///
42/// An OpenMP canonical loop is a for-statement or range-based for-statement
43/// with additional requirements that ensure that the number of iterations is
44/// known before entering the loop and allow skipping to an arbitrary iteration.
45/// The OMPCanonicalLoop AST node wraps a ForStmt or CXXForRangeStmt that is
46/// known to fulfill OpenMP's canonical loop requirements because of being
47/// associated to an OMPLoopBasedDirective. That is, the general structure is:
48///
49/// OMPLoopBasedDirective
50/// [`- CapturedStmt ]
51/// [ `- CapturedDecl]
52/// ` OMPCanonicalLoop
53/// `- ForStmt/CXXForRangeStmt
54/// `- Stmt
55///
56/// One or multiple CapturedStmt/CapturedDecl pairs may be inserted by some
57/// directives such as OMPParallelForDirective, but others do not need them
58/// (such as OMPTileDirective). In The OMPCanonicalLoop and
59/// ForStmt/CXXForRangeStmt pair is repeated for loop associated with the
60/// directive. A OMPCanonicalLoop must not appear in the AST unless associated
61/// with a OMPLoopBasedDirective. In an imperfectly nested loop nest, the
62/// OMPCanonicalLoop may also be wrapped in a CompoundStmt:
63///
64/// [...]
65/// ` OMPCanonicalLoop
66/// `- ForStmt/CXXForRangeStmt
67/// `- CompoundStmt
68/// |- Leading in-between code (if any)
69/// |- OMPCanonicalLoop
70/// | `- ForStmt/CXXForRangeStmt
71/// | `- ...
72/// `- Trailing in-between code (if any)
73///
74/// The leading/trailing in-between code must not itself be a OMPCanonicalLoop
75/// to avoid confusion which loop belongs to the nesting.
76///
77/// There are three different kinds of iteration variables for different
78/// purposes:
79/// * Loop user variable: The user-accessible variable with different value for
80/// each iteration.
81/// * Loop iteration variable: The variable used to identify a loop iteration;
82/// for range-based for-statement, this is the hidden iterator '__begin'. For
83/// other loops, it is identical to the loop user variable. Must be a
84/// random-access iterator, pointer or integer type.
85/// * Logical iteration counter: Normalized loop counter starting at 0 and
86/// incrementing by one at each iteration. Allows abstracting over the type
87/// of the loop iteration variable and is always an unsigned integer type
88/// appropriate to represent the range of the loop iteration variable. Its
89/// value corresponds to the logical iteration number in the OpenMP
90/// specification.
91///
92/// This AST node provides two captured statements:
93/// * The distance function which computes the number of iterations.
94/// * The loop user variable function that computes the loop user variable when
95/// given a logical iteration number.
96///
97/// These captured statements provide the link between C/C++ semantics and the
98/// logical iteration counters used by the OpenMPIRBuilder which is
99/// language-agnostic and therefore does not know e.g. how to advance a
100/// random-access iterator. The OpenMPIRBuilder will use this information to
101/// apply simd, workshare-loop, distribute, taskloop and loop directives to the
102/// loop. For compatibility with the non-OpenMPIRBuilder codegen path, an
103/// OMPCanonicalLoop can itself also be wrapped into the CapturedStmts of an
104/// OMPLoopDirective and skipped when searching for the associated syntactical
105/// loop.
106///
107/// Example:
108/// <code>
109/// std::vector<std::string> Container{1,2,3};
110/// for (std::string Str : Container)
111/// Body(Str);
112/// </code>
113/// which is syntactic sugar for approximately:
114/// <code>
115/// auto &&__range = Container;
116/// auto __begin = std::begin(__range);
117/// auto __end = std::end(__range);
118/// for (; __begin != __end; ++__begin) {
119/// std::String Str = *__begin;
120/// Body(Str);
121/// }
122/// </code>
123/// In this example, the loop user variable is `Str`, the loop iteration
124/// variable is `__begin` of type `std::vector<std::string>::iterator` and the
125/// logical iteration number type is `size_t` (unsigned version of
126/// `std::vector<std::string>::iterator::difference_type` aka `ptrdiff_t`).
127/// Therefore, the distance function will be
128/// <code>
129/// [&](size_t &Result) { Result = __end - __begin; }
130/// </code>
131/// and the loop variable function is
132/// <code>
133/// [&,__begin](std::vector<std::string>::iterator &Result, size_t Logical) {
134/// Result = __begin + Logical;
135/// }
136/// </code>
137/// The variable `__begin`, aka the loop iteration variable, is captured by
138/// value because it is modified in the loop body, but both functions require
139/// the initial value. The OpenMP specification explicitly leaves unspecified
140/// when the loop expressions are evaluated such that a capture by reference is
141/// sufficient.
142class OMPCanonicalLoop : public Stmt {
143 friend class ASTStmtReader;
144 friend class ASTStmtWriter;
145
146 /// Children of this AST node.
147 enum {
148 LOOP_STMT,
149 DISTANCE_FUNC,
150 LOOPVAR_FUNC,
151 LOOPVAR_REF,
152 LastSubStmt = LOOPVAR_REF
153 };
154
155private:
156 /// This AST node's children.
157 Stmt *SubStmts[LastSubStmt + 1] = {};
158
159 OMPCanonicalLoop() : Stmt(StmtClass::OMPCanonicalLoopClass) {}
160
161public:
162 /// Create a new OMPCanonicalLoop.
163 static OMPCanonicalLoop *create(const ASTContext &Ctx, Stmt *LoopStmt,
164 CapturedStmt *DistanceFunc,
165 CapturedStmt *LoopVarFunc,
166 DeclRefExpr *LoopVarRef) {
167 OMPCanonicalLoop *S = new (Ctx) OMPCanonicalLoop();
168 S->setLoopStmt(LoopStmt);
169 S->setDistanceFunc(DistanceFunc);
170 S->setLoopVarFunc(LoopVarFunc);
171 S->setLoopVarRef(LoopVarRef);
172 return S;
173 }
174
175 /// Create an empty OMPCanonicalLoop for deserialization.
177 return new (Ctx) OMPCanonicalLoop();
178 }
179
180 static bool classof(const Stmt *S) {
181 return S->getStmtClass() == StmtClass::OMPCanonicalLoopClass;
182 }
183
186
187 /// Return this AST node's children.
188 /// @{
190 return child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1);
191 }
193 return const_child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1);
194 }
195 /// @}
196
197 /// The wrapped syntactic loop statement (ForStmt or CXXForRangeStmt).
198 /// @{
199 Stmt *getLoopStmt() { return SubStmts[LOOP_STMT]; }
200 const Stmt *getLoopStmt() const { return SubStmts[LOOP_STMT]; }
201 void setLoopStmt(Stmt *S) {
202 assert((isa<ForStmt>(S) || isa<CXXForRangeStmt>(S)) &&
203 "Canonical loop must be a for loop (range-based or otherwise)");
204 SubStmts[LOOP_STMT] = S;
205 }
206 /// @}
207
208 /// The function that computes the number of loop iterations. Can be evaluated
209 /// before entering the loop but after the syntactical loop's init
210 /// statement(s).
211 ///
212 /// Function signature: void(LogicalTy &Result)
213 /// Any values necessary to compute the distance are captures of the closure.
214 /// @{
216 return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]);
217 }
219 return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]);
220 }
222 assert(S && "Expected non-null captured statement");
223 SubStmts[DISTANCE_FUNC] = S;
224 }
225 /// @}
226
227 /// The function that computes the loop user variable from a logical iteration
228 /// counter. Can be evaluated as first statement in the loop.
229 ///
230 /// Function signature: void(LoopVarTy &Result, LogicalTy Number)
231 /// Any other values required to compute the loop user variable (such as start
232 /// value, step size) are captured by the closure. In particular, the initial
233 /// value of loop iteration variable is captured by value to be unaffected by
234 /// previous iterations.
235 /// @{
237 return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]);
238 }
240 return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]);
241 }
243 assert(S && "Expected non-null captured statement");
244 SubStmts[LOOPVAR_FUNC] = S;
245 }
246 /// @}
247
248 /// Reference to the loop user variable as accessed in the loop body.
249 /// @{
251 return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]);
252 }
253 const DeclRefExpr *getLoopVarRef() const {
254 return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]);
255 }
257 assert(E && "Expected non-null loop variable");
258 SubStmts[LOOPVAR_REF] = E;
259 }
260 /// @}
261};
262
263/// This is a basic class for representing single OpenMP executable
264/// directive.
265///
267 friend class ASTStmtReader;
268 friend class ASTStmtWriter;
269
270 /// Kind of the directive.
271 OpenMPDirectiveKind Kind = llvm::omp::OMPD_unknown;
272 /// Starting location of the directive (directive keyword).
273 SourceLocation StartLoc;
274 /// Ending location of the directive.
275 SourceLocation EndLoc;
276
277 /// Get the clauses storage.
278 MutableArrayRef<OMPClause *> getClauses() {
279 if (!Data)
280 return std::nullopt;
281 return Data->getClauses();
282 }
283
284protected:
285 /// Data, associated with the directive.
286 OMPChildren *Data = nullptr;
287
288 /// Build instance of directive of class \a K.
289 ///
290 /// \param SC Statement class.
291 /// \param K Kind of OpenMP directive.
292 /// \param StartLoc Starting location of the directive (directive keyword).
293 /// \param EndLoc Ending location of the directive.
294 ///
296 SourceLocation StartLoc, SourceLocation EndLoc)
297 : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
298 EndLoc(std::move(EndLoc)) {}
299
300 template <typename T, typename... Params>
302 Stmt *AssociatedStmt, unsigned NumChildren,
303 Params &&... P) {
304 void *Mem =
305 C.Allocate(sizeof(T) + OMPChildren::size(Clauses.size(), AssociatedStmt,
306 NumChildren),
307 alignof(T));
308
309 auto *Data = OMPChildren::Create(reinterpret_cast<T *>(Mem) + 1, Clauses,
310 AssociatedStmt, NumChildren);
311 auto *Inst = new (Mem) T(std::forward<Params>(P)...);
312 Inst->Data = Data;
313 return Inst;
314 }
315
316 template <typename T, typename... Params>
317 static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses,
318 bool HasAssociatedStmt, unsigned NumChildren,
319 Params &&... P) {
320 void *Mem =
321 C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt,
322 NumChildren),
323 alignof(T));
324 auto *Data =
325 OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses,
326 HasAssociatedStmt, NumChildren);
327 auto *Inst = new (Mem) T(std::forward<Params>(P)...);
328 Inst->Data = Data;
329 return Inst;
330 }
331
332 template <typename T>
333 static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses,
334 bool HasAssociatedStmt = false,
335 unsigned NumChildren = 0) {
336 void *Mem =
337 C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt,
338 NumChildren),
339 alignof(T));
340 auto *Data =
341 OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses,
342 HasAssociatedStmt, NumChildren);
343 auto *Inst = new (Mem) T;
344 Inst->Data = Data;
345 return Inst;
346 }
347
348public:
349 /// Iterates over expressions/statements used in the construct.
351 : public llvm::iterator_adaptor_base<
352 used_clauses_child_iterator, ArrayRef<OMPClause *>::iterator,
353 std::forward_iterator_tag, Stmt *, ptrdiff_t, Stmt *, Stmt *> {
355 OMPClause::child_iterator ChildI, ChildEnd;
356
357 void MoveToNext() {
358 if (ChildI != ChildEnd)
359 return;
360 while (this->I != End) {
361 ++this->I;
362 if (this->I != End) {
363 ChildI = (*this->I)->used_children().begin();
364 ChildEnd = (*this->I)->used_children().end();
365 if (ChildI != ChildEnd)
366 return;
367 }
368 }
369 }
370
371 public:
373 : used_clauses_child_iterator::iterator_adaptor_base(Clauses.begin()),
374 End(Clauses.end()) {
375 if (this->I != End) {
376 ChildI = (*this->I)->used_children().begin();
377 ChildEnd = (*this->I)->used_children().end();
378 MoveToNext();
379 }
380 }
381 Stmt *operator*() const { return *ChildI; }
382 Stmt *operator->() const { return **this; }
383
385 ++ChildI;
386 if (ChildI != ChildEnd)
387 return *this;
388 if (this->I != End) {
389 ++this->I;
390 if (this->I != End) {
391 ChildI = (*this->I)->used_children().begin();
392 ChildEnd = (*this->I)->used_children().end();
393 }
394 }
395 MoveToNext();
396 return *this;
397 }
398 };
399
400 static llvm::iterator_range<used_clauses_child_iterator>
402 return {
404 used_clauses_child_iterator(llvm::ArrayRef(Clauses.end(), (size_t)0))};
405 }
406
407 /// Iterates over a filtered subrange of clauses applied to a
408 /// directive.
409 ///
410 /// This iterator visits only clauses of type SpecificClause.
411 template <typename SpecificClause>
413 : public llvm::iterator_adaptor_base<
414 specific_clause_iterator<SpecificClause>,
415 ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag,
416 const SpecificClause *, ptrdiff_t, const SpecificClause *,
417 const SpecificClause *> {
419
420 void SkipToNextClause() {
421 while (this->I != End && !isa<SpecificClause>(*this->I))
422 ++this->I;
423 }
424
425 public:
427 : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()),
428 End(Clauses.end()) {
429 SkipToNextClause();
430 }
431
432 const SpecificClause *operator*() const {
433 return cast<SpecificClause>(*this->I);
434 }
435 const SpecificClause *operator->() const { return **this; }
436
438 ++this->I;
439 SkipToNextClause();
440 return *this;
441 }
442 };
443
444 template <typename SpecificClause>
445 static llvm::iterator_range<specific_clause_iterator<SpecificClause>>
449 llvm::ArrayRef(Clauses.end(), (size_t)0))};
450 }
451
452 template <typename SpecificClause>
453 llvm::iterator_range<specific_clause_iterator<SpecificClause>>
455 return getClausesOfKind<SpecificClause>(clauses());
456 }
457
458 /// Gets a single clause of the specified kind associated with the
459 /// current directive iff there is only one clause of this kind (and assertion
460 /// is fired if there is more than one clause is associated with the
461 /// directive). Returns nullptr if no clause of this kind is associated with
462 /// the directive.
463 template <typename SpecificClause>
464 static const SpecificClause *getSingleClause(ArrayRef<OMPClause *> Clauses) {
465 auto ClausesOfKind = getClausesOfKind<SpecificClause>(Clauses);
466
467 if (ClausesOfKind.begin() != ClausesOfKind.end()) {
468 assert(std::next(ClausesOfKind.begin()) == ClausesOfKind.end() &&
469 "There are at least 2 clauses of the specified kind");
470 return *ClausesOfKind.begin();
471 }
472 return nullptr;
473 }
474
475 template <typename SpecificClause>
476 const SpecificClause *getSingleClause() const {
477 return getSingleClause<SpecificClause>(clauses());
478 }
479
480 /// Returns true if the current directive has one or more clauses of a
481 /// specific kind.
482 template <typename SpecificClause>
483 bool hasClausesOfKind() const {
484 auto Clauses = getClausesOfKind<SpecificClause>();
485 return Clauses.begin() != Clauses.end();
486 }
487
488 /// Returns starting location of directive kind.
489 SourceLocation getBeginLoc() const { return StartLoc; }
490 /// Returns ending location of directive.
491 SourceLocation getEndLoc() const { return EndLoc; }
492
493 /// Set starting location of directive kind.
494 ///
495 /// \param Loc New starting location of directive.
496 ///
497 void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
498 /// Set ending location of directive.
499 ///
500 /// \param Loc New ending location of directive.
501 ///
502 void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
503
504 /// Get number of clauses.
505 unsigned getNumClauses() const {
506 if (!Data)
507 return 0;
508 return Data->getNumClauses();
509 }
510
511 /// Returns specified clause.
512 ///
513 /// \param I Number of clause.
514 ///
515 OMPClause *getClause(unsigned I) const { return clauses()[I]; }
516
517 /// Returns true if directive has associated statement.
518 bool hasAssociatedStmt() const { return Data && Data->hasAssociatedStmt(); }
519
520 /// Returns statement associated with the directive.
521 const Stmt *getAssociatedStmt() const {
522 return const_cast<OMPExecutableDirective *>(this)->getAssociatedStmt();
523 }
525 assert(hasAssociatedStmt() &&
526 "Expected directive with the associated statement.");
527 return Data->getAssociatedStmt();
528 }
529
530 /// Returns the captured statement associated with the
531 /// component region within the (combined) directive.
532 ///
533 /// \param RegionKind Component region kind.
535 assert(hasAssociatedStmt() &&
536 "Expected directive with the associated statement.");
538 getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
539 return Data->getCapturedStmt(RegionKind, CaptureRegions);
540 }
541
542 /// Get innermost captured statement for the construct.
544 assert(hasAssociatedStmt() &&
545 "Expected directive with the associated statement.");
547 getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
548 return Data->getInnermostCapturedStmt(CaptureRegions);
549 }
550
552 return const_cast<OMPExecutableDirective *>(this)
554 }
555
556 OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
557
558 static bool classof(const Stmt *S) {
559 return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
560 S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
561 }
562
564 if (!Data)
567 }
568
570 return const_cast<OMPExecutableDirective *>(this)->children();
571 }
572
574 if (!Data)
575 return std::nullopt;
576 return Data->getClauses();
577 }
578
579 /// Returns whether or not this is a Standalone directive.
580 ///
581 /// Stand-alone directives are executable directives
582 /// that have no associated user code.
583 bool isStandaloneDirective() const;
584
585 /// Returns the AST node representing OpenMP structured-block of this
586 /// OpenMP executable directive,
587 /// Prerequisite: Executable Directive must not be Standalone directive.
588 const Stmt *getStructuredBlock() const {
589 return const_cast<OMPExecutableDirective *>(this)->getStructuredBlock();
590 }
592
593 const Stmt *getRawStmt() const {
594 return const_cast<OMPExecutableDirective *>(this)->getRawStmt();
595 }
597 assert(hasAssociatedStmt() &&
598 "Expected directive with the associated statement.");
599 return Data->getRawStmt();
600 }
601};
602
603/// This represents '#pragma omp parallel' directive.
604///
605/// \code
606/// #pragma omp parallel private(a,b) reduction(+: c,d)
607/// \endcode
608/// In this example directive '#pragma omp parallel' has clauses 'private'
609/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
610/// variables 'c' and 'd'.
611///
613 friend class ASTStmtReader;
615 /// true if the construct has inner cancel directive.
616 bool HasCancel = false;
617
618 /// Build directive with the given start and end location.
619 ///
620 /// \param StartLoc Starting location of the directive (directive keyword).
621 /// \param EndLoc Ending Location of the directive.
622 ///
624 : OMPExecutableDirective(OMPParallelDirectiveClass,
625 llvm::omp::OMPD_parallel, StartLoc, EndLoc) {}
626
627 /// Build an empty directive.
628 ///
629 explicit OMPParallelDirective()
630 : OMPExecutableDirective(OMPParallelDirectiveClass,
631 llvm::omp::OMPD_parallel, SourceLocation(),
632 SourceLocation()) {}
633
634 /// Sets special task reduction descriptor.
635 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
636
637 /// Set cancel state.
638 void setHasCancel(bool Has) { HasCancel = Has; }
639
640public:
641 /// Creates directive with a list of \a Clauses.
642 ///
643 /// \param C AST context.
644 /// \param StartLoc Starting location of the directive kind.
645 /// \param EndLoc Ending Location of the directive.
646 /// \param Clauses List of clauses.
647 /// \param AssociatedStmt Statement associated with the directive.
648 /// \param TaskRedRef Task reduction special reference expression to handle
649 /// taskgroup descriptor.
650 /// \param HasCancel true if this directive has inner cancel directive.
651 ///
652 static OMPParallelDirective *
653 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
654 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
655 bool HasCancel);
656
657 /// Creates an empty directive with the place for \a N clauses.
658 ///
659 /// \param C AST context.
660 /// \param NumClauses Number of clauses.
661 ///
662 static OMPParallelDirective *CreateEmpty(const ASTContext &C,
663 unsigned NumClauses, EmptyShell);
664
665 /// Returns special task reduction reference expression.
667 return cast_or_null<Expr>(Data->getChildren()[0]);
668 }
670 return const_cast<OMPParallelDirective *>(this)->getTaskReductionRefExpr();
671 }
672
673 /// Return true if current directive has inner cancel directive.
674 bool hasCancel() const { return HasCancel; }
675
676 static bool classof(const Stmt *T) {
677 return T->getStmtClass() == OMPParallelDirectiveClass;
678 }
679};
680
681/// The base class for all loop-based directives, including loop transformation
682/// directives.
684 friend class ASTStmtReader;
685
686protected:
687 /// Number of collapsed loops as specified by 'collapse' clause.
688 unsigned NumAssociatedLoops = 0;
689
690 /// Build instance of loop directive of class \a Kind.
691 ///
692 /// \param SC Statement class.
693 /// \param Kind Kind of OpenMP directive.
694 /// \param StartLoc Starting location of the directive (directive keyword).
695 /// \param EndLoc Ending location of the directive.
696 /// \param NumAssociatedLoops Number of loops associated with the construct.
697 ///
699 SourceLocation StartLoc, SourceLocation EndLoc,
700 unsigned NumAssociatedLoops)
701 : OMPExecutableDirective(SC, Kind, StartLoc, EndLoc),
703
704public:
705 /// The expressions built to support OpenMP loops in combined/composite
706 /// pragmas (e.g. pragma omp distribute parallel for)
708 /// DistributeLowerBound - used when composing 'omp distribute' with
709 /// 'omp for' in a same construct.
711 /// DistributeUpperBound - used when composing 'omp distribute' with
712 /// 'omp for' in a same construct.
714 /// DistributeEnsureUpperBound - used when composing 'omp distribute'
715 /// with 'omp for' in a same construct, EUB depends on DistUB
717 /// Distribute loop iteration variable init used when composing 'omp
718 /// distribute'
719 /// with 'omp for' in a same construct
721 /// Distribute Loop condition used when composing 'omp distribute'
722 /// with 'omp for' in a same construct
724 /// Update of LowerBound for statically scheduled omp loops for
725 /// outer loop in combined constructs (e.g. 'distribute parallel for')
727 /// Update of UpperBound for statically scheduled omp loops for
728 /// outer loop in combined constructs (e.g. 'distribute parallel for')
730 /// Distribute Loop condition used when composing 'omp distribute'
731 /// with 'omp for' in a same construct when schedule is chunked.
733 /// 'omp parallel for' loop condition used when composed with
734 /// 'omp distribute' in the same construct and when schedule is
735 /// chunked and the chunk size is 1.
737 };
738
739 /// The expressions built for the OpenMP loop CodeGen for the
740 /// whole collapsed loop nest.
741 struct HelperExprs {
742 /// Loop iteration variable.
744 /// Loop last iteration number.
746 /// Loop number of iterations.
748 /// Calculation of last iteration.
750 /// Loop pre-condition.
752 /// Loop condition.
754 /// Loop iteration variable init.
756 /// Loop increment.
758 /// IsLastIteration - local flag variable passed to runtime.
760 /// LowerBound - local variable passed to runtime.
762 /// UpperBound - local variable passed to runtime.
764 /// Stride - local variable passed to runtime.
766 /// EnsureUpperBound -- expression UB = min(UB, NumIterations).
768 /// Update of LowerBound for statically scheduled 'omp for' loops.
770 /// Update of UpperBound for statically scheduled 'omp for' loops.
772 /// PreviousLowerBound - local variable passed to runtime in the
773 /// enclosing schedule or null if that does not apply.
775 /// PreviousUpperBound - local variable passed to runtime in the
776 /// enclosing schedule or null if that does not apply.
778 /// DistInc - increment expression for distribute loop when found
779 /// combined with a further loop level (e.g. in 'distribute parallel for')
780 /// expression IV = IV + ST
782 /// PrevEUB - expression similar to EUB but to be used when loop
783 /// scheduling uses PrevLB and PrevUB (e.g. in 'distribute parallel for'
784 /// when ensuring that the UB is either the calculated UB by the runtime or
785 /// the end of the assigned distribute chunk)
786 /// expression UB = min (UB, PrevUB)
788 /// Counters Loop counters.
790 /// PrivateCounters Loop counters.
792 /// Expressions for loop counters inits for CodeGen.
794 /// Expressions for loop counters update for CodeGen.
796 /// Final loop counter values for GodeGen.
798 /// List of counters required for the generation of the non-rectangular
799 /// loops.
801 /// List of initializers required for the generation of the non-rectangular
802 /// loops.
804 /// List of final conditions required for the generation of the
805 /// non-rectangular loops.
807 /// Init statement for all captured expressions.
809
810 /// Expressions used when combining OpenMP loop pragmas
812
813 /// Check if all the expressions are built (does not check the
814 /// worksharing ones).
815 bool builtAll() {
816 return IterationVarRef != nullptr && LastIteration != nullptr &&
817 NumIterations != nullptr && PreCond != nullptr &&
818 Cond != nullptr && Init != nullptr && Inc != nullptr;
819 }
820
821 /// Initialize all the fields to null.
822 /// \param Size Number of elements in the
823 /// counters/finals/updates/dependent_counters/dependent_inits/finals_conditions
824 /// arrays.
825 void clear(unsigned Size) {
826 IterationVarRef = nullptr;
827 LastIteration = nullptr;
828 CalcLastIteration = nullptr;
829 PreCond = nullptr;
830 Cond = nullptr;
831 Init = nullptr;
832 Inc = nullptr;
833 IL = nullptr;
834 LB = nullptr;
835 UB = nullptr;
836 ST = nullptr;
837 EUB = nullptr;
838 NLB = nullptr;
839 NUB = nullptr;
840 NumIterations = nullptr;
841 PrevLB = nullptr;
842 PrevUB = nullptr;
843 DistInc = nullptr;
844 PrevEUB = nullptr;
845 Counters.resize(Size);
846 PrivateCounters.resize(Size);
847 Inits.resize(Size);
848 Updates.resize(Size);
849 Finals.resize(Size);
850 DependentCounters.resize(Size);
851 DependentInits.resize(Size);
852 FinalsConditions.resize(Size);
853 for (unsigned I = 0; I < Size; ++I) {
854 Counters[I] = nullptr;
855 PrivateCounters[I] = nullptr;
856 Inits[I] = nullptr;
857 Updates[I] = nullptr;
858 Finals[I] = nullptr;
859 DependentCounters[I] = nullptr;
860 DependentInits[I] = nullptr;
861 FinalsConditions[I] = nullptr;
862 }
863 PreInits = nullptr;
864 DistCombinedFields.LB = nullptr;
865 DistCombinedFields.UB = nullptr;
866 DistCombinedFields.EUB = nullptr;
867 DistCombinedFields.Init = nullptr;
868 DistCombinedFields.Cond = nullptr;
869 DistCombinedFields.NLB = nullptr;
870 DistCombinedFields.NUB = nullptr;
873 }
874 };
875
876 /// Get number of collapsed loops.
877 unsigned getLoopsNumber() const { return NumAssociatedLoops; }
878
879 /// Try to find the next loop sub-statement in the specified statement \p
880 /// CurStmt.
881 /// \param TryImperfectlyNestedLoops true, if we need to try to look for the
882 /// imperfectly nested loop.
883 static Stmt *tryToFindNextInnerLoop(Stmt *CurStmt,
884 bool TryImperfectlyNestedLoops);
885 static const Stmt *tryToFindNextInnerLoop(const Stmt *CurStmt,
886 bool TryImperfectlyNestedLoops) {
887 return tryToFindNextInnerLoop(const_cast<Stmt *>(CurStmt),
888 TryImperfectlyNestedLoops);
889 }
890
891 /// Calls the specified callback function for all the loops in \p CurStmt,
892 /// from the outermost to the innermost.
893 static bool
894 doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
895 unsigned NumLoops,
896 llvm::function_ref<bool(unsigned, Stmt *)> Callback,
897 llvm::function_ref<void(OMPLoopTransformationDirective *)>
898 OnTransformationCallback);
899 static bool
900 doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
901 unsigned NumLoops,
902 llvm::function_ref<bool(unsigned, const Stmt *)> Callback,
903 llvm::function_ref<void(const OMPLoopTransformationDirective *)>
904 OnTransformationCallback) {
905 auto &&NewCallback = [Callback](unsigned Cnt, Stmt *CurStmt) {
906 return Callback(Cnt, CurStmt);
907 };
908 auto &&NewTransformCb =
909 [OnTransformationCallback](OMPLoopTransformationDirective *A) {
910 OnTransformationCallback(A);
911 };
912 return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
913 NumLoops, NewCallback, NewTransformCb);
914 }
915
916 /// Calls the specified callback function for all the loops in \p CurStmt,
917 /// from the outermost to the innermost.
918 static bool
919 doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
920 unsigned NumLoops,
921 llvm::function_ref<bool(unsigned, Stmt *)> Callback) {
922 auto &&TransformCb = [](OMPLoopTransformationDirective *) {};
923 return doForAllLoops(CurStmt, TryImperfectlyNestedLoops, NumLoops, Callback,
924 TransformCb);
925 }
926 static bool
927 doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
928 unsigned NumLoops,
929 llvm::function_ref<bool(unsigned, const Stmt *)> Callback) {
930 auto &&NewCallback = [Callback](unsigned Cnt, const Stmt *CurStmt) {
931 return Callback(Cnt, CurStmt);
932 };
933 return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
934 NumLoops, NewCallback);
935 }
936
937 /// Calls the specified callback function for all the loop bodies in \p
938 /// CurStmt, from the outermost loop to the innermost.
939 static void doForAllLoopsBodies(
940 Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops,
941 llvm::function_ref<void(unsigned, Stmt *, Stmt *)> Callback);
943 const Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops,
944 llvm::function_ref<void(unsigned, const Stmt *, const Stmt *)> Callback) {
945 auto &&NewCallback = [Callback](unsigned Cnt, Stmt *Loop, Stmt *Body) {
946 Callback(Cnt, Loop, Body);
947 };
948 doForAllLoopsBodies(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
949 NumLoops, NewCallback);
950 }
951
952 static bool classof(const Stmt *T) {
953 if (auto *D = dyn_cast<OMPExecutableDirective>(T))
954 return isOpenMPLoopDirective(D->getDirectiveKind());
955 return false;
956 }
957};
958
959/// The base class for all loop transformation directives.
961 friend class ASTStmtReader;
962
963 /// Number of loops generated by this loop transformation.
964 unsigned NumGeneratedLoops = 0;
965
966protected:
969 SourceLocation StartLoc,
970 SourceLocation EndLoc,
971 unsigned NumAssociatedLoops)
972 : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, NumAssociatedLoops) {}
973
974 /// Set the number of loops generated by this loop transformation.
975 void setNumGeneratedLoops(unsigned Num) { NumGeneratedLoops = Num; }
976
977public:
978 /// Return the number of associated (consumed) loops.
979 unsigned getNumAssociatedLoops() const { return getLoopsNumber(); }
980
981 /// Return the number of loops generated by this loop transformation.
982 unsigned getNumGeneratedLoops() const { return NumGeneratedLoops; }
983
984 /// Get the de-sugared statements after the loop transformation.
985 ///
986 /// Might be nullptr if either the directive generates no loops and is handled
987 /// directly in CodeGen, or resolving a template-dependence context is
988 /// required.
989 Stmt *getTransformedStmt() const;
990
991 /// Return preinits statement.
992 Stmt *getPreInits() const;
993
994 static bool classof(const Stmt *T) {
995 Stmt::StmtClass C = T->getStmtClass();
996 return C == OMPTileDirectiveClass || C == OMPUnrollDirectiveClass ||
997 C == OMPReverseDirectiveClass || C == OMPInterchangeDirectiveClass;
998 }
999};
1000
1001/// This is a common base class for loop directives ('omp simd', 'omp
1002/// for', 'omp for simd' etc.). It is responsible for the loop code generation.
1003///
1005 friend class ASTStmtReader;
1006
1007 /// Offsets to the stored exprs.
1008 /// This enumeration contains offsets to all the pointers to children
1009 /// expressions stored in OMPLoopDirective.
1010 /// The first 9 children are necessary for all the loop directives,
1011 /// the next 8 are specific to the worksharing ones, and the next 11 are
1012 /// used for combined constructs containing two pragmas associated to loops.
1013 /// After the fixed children, three arrays of length NumAssociatedLoops are
1014 /// allocated: loop counters, their updates and final values.
1015 /// PrevLowerBound and PrevUpperBound are used to communicate blocking
1016 /// information in composite constructs which require loop blocking
1017 /// DistInc is used to generate the increment expression for the distribute
1018 /// loop when combined with a further nested loop
1019 /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the
1020 /// for loop when combined with a previous distribute loop in the same pragma
1021 /// (e.g. 'distribute parallel for')
1022 ///
1023 enum {
1024 IterationVariableOffset = 0,
1025 LastIterationOffset = 1,
1026 CalcLastIterationOffset = 2,
1027 PreConditionOffset = 3,
1028 CondOffset = 4,
1029 InitOffset = 5,
1030 IncOffset = 6,
1031 PreInitsOffset = 7,
1032 // The '...End' enumerators do not correspond to child expressions - they
1033 // specify the offset to the end (and start of the following counters/
1034 // updates/finals/dependent_counters/dependent_inits/finals_conditions
1035 // arrays).
1036 DefaultEnd = 8,
1037 // The following 8 exprs are used by worksharing and distribute loops only.
1038 IsLastIterVariableOffset = 8,
1039 LowerBoundVariableOffset = 9,
1040 UpperBoundVariableOffset = 10,
1041 StrideVariableOffset = 11,
1042 EnsureUpperBoundOffset = 12,
1043 NextLowerBoundOffset = 13,
1044 NextUpperBoundOffset = 14,
1045 NumIterationsOffset = 15,
1046 // Offset to the end for worksharing loop directives.
1047 WorksharingEnd = 16,
1048 PrevLowerBoundVariableOffset = 16,
1049 PrevUpperBoundVariableOffset = 17,
1050 DistIncOffset = 18,
1051 PrevEnsureUpperBoundOffset = 19,
1052 CombinedLowerBoundVariableOffset = 20,
1053 CombinedUpperBoundVariableOffset = 21,
1054 CombinedEnsureUpperBoundOffset = 22,
1055 CombinedInitOffset = 23,
1056 CombinedConditionOffset = 24,
1057 CombinedNextLowerBoundOffset = 25,
1058 CombinedNextUpperBoundOffset = 26,
1059 CombinedDistConditionOffset = 27,
1060 CombinedParForInDistConditionOffset = 28,
1061 // Offset to the end (and start of the following
1062 // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions
1063 // arrays) for combined distribute loop directives.
1064 CombinedDistributeEnd = 29,
1065 };
1066
1067 /// Get the counters storage.
1068 MutableArrayRef<Expr *> getCounters() {
1069 auto **Storage = reinterpret_cast<Expr **>(
1071 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1072 }
1073
1074 /// Get the private counters storage.
1075 MutableArrayRef<Expr *> getPrivateCounters() {
1076 auto **Storage = reinterpret_cast<Expr **>(
1078 getLoopsNumber()]);
1079 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1080 }
1081
1082 /// Get the updates storage.
1083 MutableArrayRef<Expr *> getInits() {
1084 auto **Storage = reinterpret_cast<Expr **>(
1086 2 * getLoopsNumber()]);
1087 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1088 }
1089
1090 /// Get the updates storage.
1091 MutableArrayRef<Expr *> getUpdates() {
1092 auto **Storage = reinterpret_cast<Expr **>(
1094 3 * getLoopsNumber()]);
1095 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1096 }
1097
1098 /// Get the final counter updates storage.
1099 MutableArrayRef<Expr *> getFinals() {
1100 auto **Storage = reinterpret_cast<Expr **>(
1102 4 * getLoopsNumber()]);
1103 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1104 }
1105
1106 /// Get the dependent counters storage.
1107 MutableArrayRef<Expr *> getDependentCounters() {
1108 auto **Storage = reinterpret_cast<Expr **>(
1110 5 * getLoopsNumber()]);
1111 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1112 }
1113
1114 /// Get the dependent inits storage.
1115 MutableArrayRef<Expr *> getDependentInits() {
1116 auto **Storage = reinterpret_cast<Expr **>(
1118 6 * getLoopsNumber()]);
1119 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1120 }
1121
1122 /// Get the finals conditions storage.
1123 MutableArrayRef<Expr *> getFinalsConditions() {
1124 auto **Storage = reinterpret_cast<Expr **>(
1126 7 * getLoopsNumber()]);
1127 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1128 }
1129
1130protected:
1131 /// Build instance of loop directive of class \a Kind.
1132 ///
1133 /// \param SC Statement class.
1134 /// \param Kind Kind of OpenMP directive.
1135 /// \param StartLoc Starting location of the directive (directive keyword).
1136 /// \param EndLoc Ending location of the directive.
1137 /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
1138 ///
1140 SourceLocation StartLoc, SourceLocation EndLoc,
1141 unsigned CollapsedNum)
1142 : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, CollapsedNum) {}
1143
1144 /// Offset to the start of children expression arrays.
1147 return CombinedDistributeEnd;
1150 return WorksharingEnd;
1151 return DefaultEnd;
1152 }
1153
1154 /// Children number.
1155 static unsigned numLoopChildren(unsigned CollapsedNum,
1157 return getArraysOffset(Kind) +
1158 8 * CollapsedNum; // Counters, PrivateCounters, Inits,
1159 // Updates, Finals, DependentCounters,
1160 // DependentInits, FinalsConditions.
1161 }
1162
1164 Data->getChildren()[IterationVariableOffset] = IV;
1165 }
1167 Data->getChildren()[LastIterationOffset] = LI;
1168 }
1170 Data->getChildren()[CalcLastIterationOffset] = CLI;
1171 }
1172 void setPreCond(Expr *PC) { Data->getChildren()[PreConditionOffset] = PC; }
1173 void setCond(Expr *Cond) { Data->getChildren()[CondOffset] = Cond; }
1174 void setInit(Expr *Init) { Data->getChildren()[InitOffset] = Init; }
1175 void setInc(Expr *Inc) { Data->getChildren()[IncOffset] = Inc; }
1176 void setPreInits(Stmt *PreInits) {
1177 Data->getChildren()[PreInitsOffset] = PreInits;
1178 }
1184 "expected worksharing loop directive");
1185 Data->getChildren()[IsLastIterVariableOffset] = IL;
1186 }
1192 "expected worksharing loop directive");
1193 Data->getChildren()[LowerBoundVariableOffset] = LB;
1194 }
1200 "expected worksharing loop directive");
1201 Data->getChildren()[UpperBoundVariableOffset] = UB;
1202 }
1208 "expected worksharing loop directive");
1209 Data->getChildren()[StrideVariableOffset] = ST;
1210 }
1216 "expected worksharing loop directive");
1217 Data->getChildren()[EnsureUpperBoundOffset] = EUB;
1218 }
1224 "expected worksharing loop directive");
1225 Data->getChildren()[NextLowerBoundOffset] = NLB;
1226 }
1232 "expected worksharing loop directive");
1233 Data->getChildren()[NextUpperBoundOffset] = NUB;
1234 }
1240 "expected worksharing loop directive");
1241 Data->getChildren()[NumIterationsOffset] = NI;
1242 }
1245 "expected loop bound sharing directive");
1246 Data->getChildren()[PrevLowerBoundVariableOffset] = PrevLB;
1247 }
1250 "expected loop bound sharing directive");
1251 Data->getChildren()[PrevUpperBoundVariableOffset] = PrevUB;
1252 }
1253 void setDistInc(Expr *DistInc) {
1255 "expected loop bound sharing directive");
1256 Data->getChildren()[DistIncOffset] = DistInc;
1257 }
1260 "expected loop bound sharing directive");
1261 Data->getChildren()[PrevEnsureUpperBoundOffset] = PrevEUB;
1262 }
1265 "expected loop bound sharing directive");
1266 Data->getChildren()[CombinedLowerBoundVariableOffset] = CombLB;
1267 }
1270 "expected loop bound sharing directive");
1271 Data->getChildren()[CombinedUpperBoundVariableOffset] = CombUB;
1272 }
1275 "expected loop bound sharing directive");
1276 Data->getChildren()[CombinedEnsureUpperBoundOffset] = CombEUB;
1277 }
1278 void setCombinedInit(Expr *CombInit) {
1280 "expected loop bound sharing directive");
1281 Data->getChildren()[CombinedInitOffset] = CombInit;
1282 }
1283 void setCombinedCond(Expr *CombCond) {
1285 "expected loop bound sharing directive");
1286 Data->getChildren()[CombinedConditionOffset] = CombCond;
1287 }
1290 "expected loop bound sharing directive");
1291 Data->getChildren()[CombinedNextLowerBoundOffset] = CombNLB;
1292 }
1295 "expected loop bound sharing directive");
1296 Data->getChildren()[CombinedNextUpperBoundOffset] = CombNUB;
1297 }
1298 void setCombinedDistCond(Expr *CombDistCond) {
1300 "expected loop bound distribute sharing directive");
1301 Data->getChildren()[CombinedDistConditionOffset] = CombDistCond;
1302 }
1303 void setCombinedParForInDistCond(Expr *CombParForInDistCond) {
1305 "expected loop bound distribute sharing directive");
1306 Data->getChildren()[CombinedParForInDistConditionOffset] =
1307 CombParForInDistCond;
1308 }
1311 void setInits(ArrayRef<Expr *> A);
1317
1318public:
1320 return cast<Expr>(Data->getChildren()[IterationVariableOffset]);
1321 }
1323 return cast<Expr>(Data->getChildren()[LastIterationOffset]);
1324 }
1326 return cast<Expr>(Data->getChildren()[CalcLastIterationOffset]);
1327 }
1328 Expr *getPreCond() const {
1329 return cast<Expr>(Data->getChildren()[PreConditionOffset]);
1330 }
1331 Expr *getCond() const { return cast<Expr>(Data->getChildren()[CondOffset]); }
1332 Expr *getInit() const { return cast<Expr>(Data->getChildren()[InitOffset]); }
1333 Expr *getInc() const { return cast<Expr>(Data->getChildren()[IncOffset]); }
1334 const Stmt *getPreInits() const {
1335 return Data->getChildren()[PreInitsOffset];
1336 }
1337 Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; }
1343 "expected worksharing loop directive");
1344 return cast<Expr>(Data->getChildren()[IsLastIterVariableOffset]);
1345 }
1351 "expected worksharing loop directive");
1352 return cast<Expr>(Data->getChildren()[LowerBoundVariableOffset]);
1353 }
1359 "expected worksharing loop directive");
1360 return cast<Expr>(Data->getChildren()[UpperBoundVariableOffset]);
1361 }
1367 "expected worksharing loop directive");
1368 return cast<Expr>(Data->getChildren()[StrideVariableOffset]);
1369 }
1375 "expected worksharing loop directive");
1376 return cast<Expr>(Data->getChildren()[EnsureUpperBoundOffset]);
1377 }
1383 "expected worksharing loop directive");
1384 return cast<Expr>(Data->getChildren()[NextLowerBoundOffset]);
1385 }
1391 "expected worksharing loop directive");
1392 return cast<Expr>(Data->getChildren()[NextUpperBoundOffset]);
1393 }
1399 "expected worksharing loop directive");
1400 return cast<Expr>(Data->getChildren()[NumIterationsOffset]);
1401 }
1404 "expected loop bound sharing directive");
1405 return cast<Expr>(Data->getChildren()[PrevLowerBoundVariableOffset]);
1406 }
1409 "expected loop bound sharing directive");
1410 return cast<Expr>(Data->getChildren()[PrevUpperBoundVariableOffset]);
1411 }
1412 Expr *getDistInc() const {
1414 "expected loop bound sharing directive");
1415 return cast<Expr>(Data->getChildren()[DistIncOffset]);
1416 }
1419 "expected loop bound sharing directive");
1420 return cast<Expr>(Data->getChildren()[PrevEnsureUpperBoundOffset]);
1421 }
1424 "expected loop bound sharing directive");
1425 return cast<Expr>(Data->getChildren()[CombinedLowerBoundVariableOffset]);
1426 }
1429 "expected loop bound sharing directive");
1430 return cast<Expr>(Data->getChildren()[CombinedUpperBoundVariableOffset]);
1431 }
1434 "expected loop bound sharing directive");
1435 return cast<Expr>(Data->getChildren()[CombinedEnsureUpperBoundOffset]);
1436 }
1439 "expected loop bound sharing directive");
1440 return cast<Expr>(Data->getChildren()[CombinedInitOffset]);
1441 }
1444 "expected loop bound sharing directive");
1445 return cast<Expr>(Data->getChildren()[CombinedConditionOffset]);
1446 }
1449 "expected loop bound sharing directive");
1450 return cast<Expr>(Data->getChildren()[CombinedNextLowerBoundOffset]);
1451 }
1454 "expected loop bound sharing directive");
1455 return cast<Expr>(Data->getChildren()[CombinedNextUpperBoundOffset]);
1456 }
1459 "expected loop bound distribute sharing directive");
1460 return cast<Expr>(Data->getChildren()[CombinedDistConditionOffset]);
1461 }
1464 "expected loop bound distribute sharing directive");
1465 return cast<Expr>(Data->getChildren()[CombinedParForInDistConditionOffset]);
1466 }
1467 Stmt *getBody();
1468 const Stmt *getBody() const {
1469 return const_cast<OMPLoopDirective *>(this)->getBody();
1470 }
1471
1472 ArrayRef<Expr *> counters() { return getCounters(); }
1473
1475 return const_cast<OMPLoopDirective *>(this)->getCounters();
1476 }
1477
1478 ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
1479
1481 return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
1482 }
1483
1484 ArrayRef<Expr *> inits() { return getInits(); }
1485
1487 return const_cast<OMPLoopDirective *>(this)->getInits();
1488 }
1489
1490 ArrayRef<Expr *> updates() { return getUpdates(); }
1491
1493 return const_cast<OMPLoopDirective *>(this)->getUpdates();
1494 }
1495
1496 ArrayRef<Expr *> finals() { return getFinals(); }
1497
1499 return const_cast<OMPLoopDirective *>(this)->getFinals();
1500 }
1501
1502 ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); }
1503
1505 return const_cast<OMPLoopDirective *>(this)->getDependentCounters();
1506 }
1507
1508 ArrayRef<Expr *> dependent_inits() { return getDependentInits(); }
1509
1511 return const_cast<OMPLoopDirective *>(this)->getDependentInits();
1512 }
1513
1514 ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); }
1515
1517 return const_cast<OMPLoopDirective *>(this)->getFinalsConditions();
1518 }
1519
1520 static bool classof(const Stmt *T) {
1521 return T->getStmtClass() == OMPSimdDirectiveClass ||
1522 T->getStmtClass() == OMPForDirectiveClass ||
1523 T->getStmtClass() == OMPForSimdDirectiveClass ||
1524 T->getStmtClass() == OMPParallelForDirectiveClass ||
1525 T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
1526 T->getStmtClass() == OMPTaskLoopDirectiveClass ||
1527 T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
1528 T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass ||
1529 T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass ||
1530 T->getStmtClass() == OMPMasterTaskLoopDirectiveClass ||
1531 T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass ||
1532 T->getStmtClass() == OMPGenericLoopDirectiveClass ||
1533 T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass ||
1534 T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass ||
1535 T->getStmtClass() == OMPParallelGenericLoopDirectiveClass ||
1536 T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass ||
1537 T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass ||
1538 T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass ||
1539 T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass ||
1540 T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass ||
1541 T->getStmtClass() == OMPDistributeDirectiveClass ||
1542 T->getStmtClass() == OMPTargetParallelForDirectiveClass ||
1543 T->getStmtClass() == OMPDistributeParallelForDirectiveClass ||
1544 T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass ||
1545 T->getStmtClass() == OMPDistributeSimdDirectiveClass ||
1546 T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass ||
1547 T->getStmtClass() == OMPTargetSimdDirectiveClass ||
1548 T->getStmtClass() == OMPTeamsDistributeDirectiveClass ||
1549 T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass ||
1550 T->getStmtClass() ==
1551 OMPTeamsDistributeParallelForSimdDirectiveClass ||
1552 T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass ||
1553 T->getStmtClass() ==
1554 OMPTargetTeamsDistributeParallelForDirectiveClass ||
1555 T->getStmtClass() ==
1556 OMPTargetTeamsDistributeParallelForSimdDirectiveClass ||
1557 T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass ||
1558 T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
1559 }
1560};
1561
1562/// This represents '#pragma omp simd' directive.
1563///
1564/// \code
1565/// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
1566/// \endcode
1567/// In this example directive '#pragma omp simd' has clauses 'private'
1568/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
1569/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
1570///
1572 friend class ASTStmtReader;
1574 /// Build directive with the given start and end location.
1575 ///
1576 /// \param StartLoc Starting location of the directive kind.
1577 /// \param EndLoc Ending location of the directive.
1578 /// \param CollapsedNum Number of collapsed nested loops.
1579 ///
1581 unsigned CollapsedNum)
1582 : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, StartLoc,
1583 EndLoc, CollapsedNum) {}
1584
1585 /// Build an empty directive.
1586 ///
1587 /// \param CollapsedNum Number of collapsed nested loops.
1588 ///
1589 explicit OMPSimdDirective(unsigned CollapsedNum)
1590 : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd,
1591 SourceLocation(), SourceLocation(), CollapsedNum) {}
1592
1593public:
1594 /// Creates directive with a list of \a Clauses.
1595 ///
1596 /// \param C AST context.
1597 /// \param StartLoc Starting location of the directive kind.
1598 /// \param EndLoc Ending Location of the directive.
1599 /// \param CollapsedNum Number of collapsed loops.
1600 /// \param Clauses List of clauses.
1601 /// \param AssociatedStmt Statement, associated with the directive.
1602 /// \param Exprs Helper expressions for CodeGen.
1603 ///
1604 static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1605 SourceLocation EndLoc, unsigned CollapsedNum,
1606 ArrayRef<OMPClause *> Clauses,
1607 Stmt *AssociatedStmt,
1608 const HelperExprs &Exprs);
1609
1610 /// Creates an empty directive with the place
1611 /// for \a NumClauses clauses.
1612 ///
1613 /// \param C AST context.
1614 /// \param CollapsedNum Number of collapsed nested loops.
1615 /// \param NumClauses Number of clauses.
1616 ///
1617 static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1618 unsigned CollapsedNum, EmptyShell);
1619
1620 static bool classof(const Stmt *T) {
1621 return T->getStmtClass() == OMPSimdDirectiveClass;
1622 }
1623};
1624
1625/// This represents '#pragma omp for' directive.
1626///
1627/// \code
1628/// #pragma omp for private(a,b) reduction(+:c,d)
1629/// \endcode
1630/// In this example directive '#pragma omp for' has clauses 'private' with the
1631/// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
1632/// and 'd'.
1633///
1635 friend class ASTStmtReader;
1637 /// true if current directive has inner cancel directive.
1638 bool HasCancel = false;
1639
1640 /// Build directive with the given start and end location.
1641 ///
1642 /// \param StartLoc Starting location of the directive kind.
1643 /// \param EndLoc Ending location of the directive.
1644 /// \param CollapsedNum Number of collapsed nested loops.
1645 ///
1647 unsigned CollapsedNum)
1648 : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, StartLoc,
1649 EndLoc, CollapsedNum) {}
1650
1651 /// Build an empty directive.
1652 ///
1653 /// \param CollapsedNum Number of collapsed nested loops.
1654 ///
1655 explicit OMPForDirective(unsigned CollapsedNum)
1656 : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for,
1657 SourceLocation(), SourceLocation(), CollapsedNum) {}
1658
1659 /// Sets special task reduction descriptor.
1660 void setTaskReductionRefExpr(Expr *E) {
1661 Data->getChildren()[numLoopChildren(getLoopsNumber(),
1662 llvm::omp::OMPD_for)] = E;
1663 }
1664
1665 /// Set cancel state.
1666 void setHasCancel(bool Has) { HasCancel = Has; }
1667
1668public:
1669 /// Creates directive with a list of \a Clauses.
1670 ///
1671 /// \param C AST context.
1672 /// \param StartLoc Starting location of the directive kind.
1673 /// \param EndLoc Ending Location of the directive.
1674 /// \param CollapsedNum Number of collapsed loops.
1675 /// \param Clauses List of clauses.
1676 /// \param AssociatedStmt Statement, associated with the directive.
1677 /// \param Exprs Helper expressions for CodeGen.
1678 /// \param TaskRedRef Task reduction special reference expression to handle
1679 /// taskgroup descriptor.
1680 /// \param HasCancel true if current directive has inner cancel directive.
1681 ///
1682 static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1683 SourceLocation EndLoc, unsigned CollapsedNum,
1684 ArrayRef<OMPClause *> Clauses,
1685 Stmt *AssociatedStmt, const HelperExprs &Exprs,
1686 Expr *TaskRedRef, bool HasCancel);
1687
1688 /// Creates an empty directive with the place
1689 /// for \a NumClauses clauses.
1690 ///
1691 /// \param C AST context.
1692 /// \param CollapsedNum Number of collapsed nested loops.
1693 /// \param NumClauses Number of clauses.
1694 ///
1695 static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1696 unsigned CollapsedNum, EmptyShell);
1697
1698 /// Returns special task reduction reference expression.
1700 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
1701 getLoopsNumber(), llvm::omp::OMPD_for)]);
1702 }
1704 return const_cast<OMPForDirective *>(this)->getTaskReductionRefExpr();
1705 }
1706
1707 /// Return true if current directive has inner cancel directive.
1708 bool hasCancel() const { return HasCancel; }
1709
1710 static bool classof(const Stmt *T) {
1711 return T->getStmtClass() == OMPForDirectiveClass;
1712 }
1713};
1714
1715/// This represents '#pragma omp for simd' directive.
1716///
1717/// \code
1718/// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
1719/// \endcode
1720/// In this example directive '#pragma omp for simd' has clauses 'private'
1721/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
1722/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
1723///
1725 friend class ASTStmtReader;
1727 /// Build directive with the given start and end location.
1728 ///
1729 /// \param StartLoc Starting location of the directive kind.
1730 /// \param EndLoc Ending location of the directive.
1731 /// \param CollapsedNum Number of collapsed nested loops.
1732 ///
1734 unsigned CollapsedNum)
1735 : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
1736 StartLoc, EndLoc, CollapsedNum) {}
1737
1738 /// Build an empty directive.
1739 ///
1740 /// \param CollapsedNum Number of collapsed nested loops.
1741 ///
1742 explicit OMPForSimdDirective(unsigned CollapsedNum)
1743 : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
1744 SourceLocation(), SourceLocation(), CollapsedNum) {}
1745
1746public:
1747 /// Creates directive with a list of \a Clauses.
1748 ///
1749 /// \param C AST context.
1750 /// \param StartLoc Starting location of the directive kind.
1751 /// \param EndLoc Ending Location of the directive.
1752 /// \param CollapsedNum Number of collapsed loops.
1753 /// \param Clauses List of clauses.
1754 /// \param AssociatedStmt Statement, associated with the directive.
1755 /// \param Exprs Helper expressions for CodeGen.
1756 ///
1757 static OMPForSimdDirective *
1758 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1759 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1760 Stmt *AssociatedStmt, const HelperExprs &Exprs);
1761
1762 /// Creates an empty directive with the place
1763 /// for \a NumClauses clauses.
1764 ///
1765 /// \param C AST context.
1766 /// \param CollapsedNum Number of collapsed nested loops.
1767 /// \param NumClauses Number of clauses.
1768 ///
1769 static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
1770 unsigned NumClauses,
1771 unsigned CollapsedNum, EmptyShell);
1772
1773 static bool classof(const Stmt *T) {
1774 return T->getStmtClass() == OMPForSimdDirectiveClass;
1775 }
1776};
1777
1778/// This represents '#pragma omp sections' directive.
1779///
1780/// \code
1781/// #pragma omp sections private(a,b) reduction(+:c,d)
1782/// \endcode
1783/// In this example directive '#pragma omp sections' has clauses 'private' with
1784/// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
1785/// 'c' and 'd'.
1786///
1788 friend class ASTStmtReader;
1790
1791 /// true if current directive has inner cancel directive.
1792 bool HasCancel = false;
1793
1794 /// Build directive with the given start and end location.
1795 ///
1796 /// \param StartLoc Starting location of the directive kind.
1797 /// \param EndLoc Ending location of the directive.
1798 ///
1800 : OMPExecutableDirective(OMPSectionsDirectiveClass,
1801 llvm::omp::OMPD_sections, StartLoc, EndLoc) {}
1802
1803 /// Build an empty directive.
1804 ///
1805 explicit OMPSectionsDirective()
1806 : OMPExecutableDirective(OMPSectionsDirectiveClass,
1807 llvm::omp::OMPD_sections, SourceLocation(),
1808 SourceLocation()) {}
1809
1810 /// Sets special task reduction descriptor.
1811 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
1812
1813 /// Set cancel state.
1814 void setHasCancel(bool Has) { HasCancel = Has; }
1815
1816public:
1817 /// Creates directive with a list of \a Clauses.
1818 ///
1819 /// \param C AST context.
1820 /// \param StartLoc Starting location of the directive kind.
1821 /// \param EndLoc Ending Location of the directive.
1822 /// \param Clauses List of clauses.
1823 /// \param AssociatedStmt Statement, associated with the directive.
1824 /// \param TaskRedRef Task reduction special reference expression to handle
1825 /// taskgroup descriptor.
1826 /// \param HasCancel true if current directive has inner directive.
1827 ///
1828 static OMPSectionsDirective *
1829 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1830 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
1831 bool HasCancel);
1832
1833 /// Creates an empty directive with the place for \a NumClauses
1834 /// clauses.
1835 ///
1836 /// \param C AST context.
1837 /// \param NumClauses Number of clauses.
1838 ///
1839 static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
1840 unsigned NumClauses, EmptyShell);
1841
1842 /// Returns special task reduction reference expression.
1844 return cast_or_null<Expr>(Data->getChildren()[0]);
1845 }
1847 return const_cast<OMPSectionsDirective *>(this)->getTaskReductionRefExpr();
1848 }
1849
1850 /// Return true if current directive has inner cancel directive.
1851 bool hasCancel() const { return HasCancel; }
1852
1853 static bool classof(const Stmt *T) {
1854 return T->getStmtClass() == OMPSectionsDirectiveClass;
1855 }
1856};
1857
1858/// This represents '#pragma omp section' directive.
1859///
1860/// \code
1861/// #pragma omp section
1862/// \endcode
1863///
1865 friend class ASTStmtReader;
1867
1868 /// true if current directive has inner cancel directive.
1869 bool HasCancel = false;
1870
1871 /// Build directive with the given start and end location.
1872 ///
1873 /// \param StartLoc Starting location of the directive kind.
1874 /// \param EndLoc Ending location of the directive.
1875 ///
1877 : OMPExecutableDirective(OMPSectionDirectiveClass,
1878 llvm::omp::OMPD_section, StartLoc, EndLoc) {}
1879
1880 /// Build an empty directive.
1881 ///
1882 explicit OMPSectionDirective()
1883 : OMPExecutableDirective(OMPSectionDirectiveClass,
1884 llvm::omp::OMPD_section, SourceLocation(),
1885 SourceLocation()) {}
1886
1887public:
1888 /// Creates directive.
1889 ///
1890 /// \param C AST context.
1891 /// \param StartLoc Starting location of the directive kind.
1892 /// \param EndLoc Ending Location of the directive.
1893 /// \param AssociatedStmt Statement, associated with the directive.
1894 /// \param HasCancel true if current directive has inner directive.
1895 ///
1896 static OMPSectionDirective *Create(const ASTContext &C,
1897 SourceLocation StartLoc,
1898 SourceLocation EndLoc,
1899 Stmt *AssociatedStmt, bool HasCancel);
1900
1901 /// Creates an empty directive.
1902 ///
1903 /// \param C AST context.
1904 ///
1905 static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1906
1907 /// Set cancel state.
1908 void setHasCancel(bool Has) { HasCancel = Has; }
1909
1910 /// Return true if current directive has inner cancel directive.
1911 bool hasCancel() const { return HasCancel; }
1912
1913 static bool classof(const Stmt *T) {
1914 return T->getStmtClass() == OMPSectionDirectiveClass;
1915 }
1916};
1917
1918/// This represents '#pragma omp scope' directive.
1919/// \code
1920/// #pragma omp scope private(a,b) nowait
1921/// \endcode
1922/// In this example directive '#pragma omp scope' has clauses 'private' with
1923/// the variables 'a' and 'b' and nowait.
1924///
1926 friend class ASTStmtReader;
1928
1929 /// Build directive with the given start and end location.
1930 ///
1931 /// \param StartLoc Starting location of the directive kind.
1932 /// \param EndLoc Ending location of the directive.
1933 ///
1935 : OMPExecutableDirective(OMPScopeDirectiveClass, llvm::omp::OMPD_scope,
1936 StartLoc, EndLoc) {}
1937
1938 /// Build an empty directive.
1939 ///
1940 explicit OMPScopeDirective()
1941 : OMPExecutableDirective(OMPScopeDirectiveClass, llvm::omp::OMPD_scope,
1943
1944public:
1945 /// Creates directive.
1946 ///
1947 /// \param C AST context.
1948 /// \param StartLoc Starting location of the directive kind.
1949 /// \param EndLoc Ending Location of the directive.
1950 /// \param AssociatedStmt Statement, associated with the directive.
1951 ///
1952 static OMPScopeDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1953 SourceLocation EndLoc,
1954 ArrayRef<OMPClause *> Clauses,
1955 Stmt *AssociatedStmt);
1956
1957 /// Creates an empty directive.
1958 ///
1959 /// \param C AST context.
1960 ///
1961 static OMPScopeDirective *CreateEmpty(const ASTContext &C,
1962 unsigned NumClauses, EmptyShell);
1963
1964 static bool classof(const Stmt *T) {
1965 return T->getStmtClass() == OMPScopeDirectiveClass;
1966 }
1967};
1968
1969/// This represents '#pragma omp single' directive.
1970///
1971/// \code
1972/// #pragma omp single private(a,b) copyprivate(c,d)
1973/// \endcode
1974/// In this example directive '#pragma omp single' has clauses 'private' with
1975/// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
1976///
1978 friend class ASTStmtReader;
1980 /// Build directive with the given start and end location.
1981 ///
1982 /// \param StartLoc Starting location of the directive kind.
1983 /// \param EndLoc Ending location of the directive.
1984 ///
1986 : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
1987 StartLoc, EndLoc) {}
1988
1989 /// Build an empty directive.
1990 ///
1991 explicit OMPSingleDirective()
1992 : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
1994
1995public:
1996 /// Creates directive with a list of \a Clauses.
1997 ///
1998 /// \param C AST context.
1999 /// \param StartLoc Starting location of the directive kind.
2000 /// \param EndLoc Ending Location of the directive.
2001 /// \param Clauses List of clauses.
2002 /// \param AssociatedStmt Statement, associated with the directive.
2003 ///
2004 static OMPSingleDirective *
2005 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2006 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2007
2008 /// Creates an empty directive with the place for \a NumClauses
2009 /// clauses.
2010 ///
2011 /// \param C AST context.
2012 /// \param NumClauses Number of clauses.
2013 ///
2014 static OMPSingleDirective *CreateEmpty(const ASTContext &C,
2015 unsigned NumClauses, EmptyShell);
2016
2017 static bool classof(const Stmt *T) {
2018 return T->getStmtClass() == OMPSingleDirectiveClass;
2019 }
2020};
2021
2022/// This represents '#pragma omp master' directive.
2023///
2024/// \code
2025/// #pragma omp master
2026/// \endcode
2027///
2029 friend class ASTStmtReader;
2031 /// Build directive with the given start and end location.
2032 ///
2033 /// \param StartLoc Starting location of the directive kind.
2034 /// \param EndLoc Ending location of the directive.
2035 ///
2037 : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
2038 StartLoc, EndLoc) {}
2039
2040 /// Build an empty directive.
2041 ///
2042 explicit OMPMasterDirective()
2043 : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
2045
2046public:
2047 /// Creates directive.
2048 ///
2049 /// \param C AST context.
2050 /// \param StartLoc Starting location of the directive kind.
2051 /// \param EndLoc Ending Location of the directive.
2052 /// \param AssociatedStmt Statement, associated with the directive.
2053 ///
2054 static OMPMasterDirective *Create(const ASTContext &C,
2055 SourceLocation StartLoc,
2056 SourceLocation EndLoc,
2057 Stmt *AssociatedStmt);
2058
2059 /// Creates an empty directive.
2060 ///
2061 /// \param C AST context.
2062 ///
2063 static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2064
2065 static bool classof(const Stmt *T) {
2066 return T->getStmtClass() == OMPMasterDirectiveClass;
2067 }
2068};
2069
2070/// This represents '#pragma omp critical' directive.
2071///
2072/// \code
2073/// #pragma omp critical
2074/// \endcode
2075///
2077 friend class ASTStmtReader;
2079 /// Name of the directive.
2080 DeclarationNameInfo DirName;
2081 /// Build directive with the given start and end location.
2082 ///
2083 /// \param Name Name of the directive.
2084 /// \param StartLoc Starting location of the directive kind.
2085 /// \param EndLoc Ending location of the directive.
2086 ///
2088 SourceLocation EndLoc)
2089 : OMPExecutableDirective(OMPCriticalDirectiveClass,
2090 llvm::omp::OMPD_critical, StartLoc, EndLoc),
2091 DirName(Name) {}
2092
2093 /// Build an empty directive.
2094 ///
2095 explicit OMPCriticalDirective()
2096 : OMPExecutableDirective(OMPCriticalDirectiveClass,
2097 llvm::omp::OMPD_critical, SourceLocation(),
2098 SourceLocation()) {}
2099
2100 /// Set name of the directive.
2101 ///
2102 /// \param Name Name of the directive.
2103 ///
2104 void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
2105
2106public:
2107 /// Creates directive.
2108 ///
2109 /// \param C AST context.
2110 /// \param Name Name of the directive.
2111 /// \param StartLoc Starting location of the directive kind.
2112 /// \param EndLoc Ending Location of the directive.
2113 /// \param Clauses List of clauses.
2114 /// \param AssociatedStmt Statement, associated with the directive.
2115 ///
2116 static OMPCriticalDirective *
2117 Create(const ASTContext &C, const DeclarationNameInfo &Name,
2118 SourceLocation StartLoc, SourceLocation EndLoc,
2119 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2120
2121 /// Creates an empty directive.
2122 ///
2123 /// \param C AST context.
2124 /// \param NumClauses Number of clauses.
2125 ///
2126 static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
2127 unsigned NumClauses, EmptyShell);
2128
2129 /// Return name of the directive.
2130 ///
2131 DeclarationNameInfo getDirectiveName() const { return DirName; }
2132
2133 static bool classof(const Stmt *T) {
2134 return T->getStmtClass() == OMPCriticalDirectiveClass;
2135 }
2136};
2137
2138/// This represents '#pragma omp parallel for' directive.
2139///
2140/// \code
2141/// #pragma omp parallel for private(a,b) reduction(+:c,d)
2142/// \endcode
2143/// In this example directive '#pragma omp parallel for' has clauses 'private'
2144/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
2145/// variables 'c' and 'd'.
2146///
2148 friend class ASTStmtReader;
2150
2151 /// true if current region has inner cancel directive.
2152 bool HasCancel = false;
2153
2154 /// Build directive with the given start and end location.
2155 ///
2156 /// \param StartLoc Starting location of the directive kind.
2157 /// \param EndLoc Ending location of the directive.
2158 /// \param CollapsedNum Number of collapsed nested loops.
2159 ///
2161 unsigned CollapsedNum)
2162 : OMPLoopDirective(OMPParallelForDirectiveClass,
2163 llvm::omp::OMPD_parallel_for, StartLoc, EndLoc,
2164 CollapsedNum) {}
2165
2166 /// Build an empty directive.
2167 ///
2168 /// \param CollapsedNum Number of collapsed nested loops.
2169 ///
2170 explicit OMPParallelForDirective(unsigned CollapsedNum)
2171 : OMPLoopDirective(OMPParallelForDirectiveClass,
2172 llvm::omp::OMPD_parallel_for, SourceLocation(),
2173 SourceLocation(), CollapsedNum) {}
2174
2175 /// Sets special task reduction descriptor.
2176 void setTaskReductionRefExpr(Expr *E) {
2177 Data->getChildren()[numLoopChildren(getLoopsNumber(),
2178 llvm::omp::OMPD_parallel_for)] = E;
2179 }
2180
2181 /// Set cancel state.
2182 void setHasCancel(bool Has) { HasCancel = Has; }
2183
2184public:
2185 /// Creates directive with a list of \a Clauses.
2186 ///
2187 /// \param C AST context.
2188 /// \param StartLoc Starting location of the directive kind.
2189 /// \param EndLoc Ending Location of the directive.
2190 /// \param CollapsedNum Number of collapsed loops.
2191 /// \param Clauses List of clauses.
2192 /// \param AssociatedStmt Statement, associated with the directive.
2193 /// \param Exprs Helper expressions for CodeGen.
2194 /// \param TaskRedRef Task reduction special reference expression to handle
2195 /// taskgroup descriptor.
2196 /// \param HasCancel true if current directive has inner cancel directive.
2197 ///
2198 static OMPParallelForDirective *
2199 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2200 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2201 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
2202 bool HasCancel);
2203
2204 /// Creates an empty directive with the place
2205 /// for \a NumClauses clauses.
2206 ///
2207 /// \param C AST context.
2208 /// \param CollapsedNum Number of collapsed nested loops.
2209 /// \param NumClauses Number of clauses.
2210 ///
2211 static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
2212 unsigned NumClauses,
2213 unsigned CollapsedNum,
2214 EmptyShell);
2215
2216 /// Returns special task reduction reference expression.
2218 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
2219 getLoopsNumber(), llvm::omp::OMPD_parallel_for)]);
2220 }
2222 return const_cast<OMPParallelForDirective *>(this)
2224 }
2225
2226 /// Return true if current directive has inner cancel directive.
2227 bool hasCancel() const { return HasCancel; }
2228
2229 static bool classof(const Stmt *T) {
2230 return T->getStmtClass() == OMPParallelForDirectiveClass;
2231 }
2232};
2233
2234/// This represents '#pragma omp parallel for simd' directive.
2235///
2236/// \code
2237/// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
2238/// \endcode
2239/// In this example directive '#pragma omp parallel for simd' has clauses
2240/// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
2241/// and linear step 's', 'reduction' with operator '+' and variables 'c' and
2242/// 'd'.
2243///
2245 friend class ASTStmtReader;
2247 /// Build directive with the given start and end location.
2248 ///
2249 /// \param StartLoc Starting location of the directive kind.
2250 /// \param EndLoc Ending location of the directive.
2251 /// \param CollapsedNum Number of collapsed nested loops.
2252 ///
2254 unsigned CollapsedNum)
2255 : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
2256 llvm::omp::OMPD_parallel_for_simd, StartLoc, EndLoc,
2257 CollapsedNum) {}
2258
2259 /// Build an empty directive.
2260 ///
2261 /// \param CollapsedNum Number of collapsed nested loops.
2262 ///
2263 explicit OMPParallelForSimdDirective(unsigned CollapsedNum)
2264 : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
2265 llvm::omp::OMPD_parallel_for_simd, SourceLocation(),
2266 SourceLocation(), CollapsedNum) {}
2267
2268public:
2269 /// Creates directive with a list of \a Clauses.
2270 ///
2271 /// \param C AST context.
2272 /// \param StartLoc Starting location of the directive kind.
2273 /// \param EndLoc Ending Location of the directive.
2274 /// \param CollapsedNum Number of collapsed loops.
2275 /// \param Clauses List of clauses.
2276 /// \param AssociatedStmt Statement, associated with the directive.
2277 /// \param Exprs Helper expressions for CodeGen.
2278 ///
2279 static OMPParallelForSimdDirective *
2280 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2281 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2282 Stmt *AssociatedStmt, const HelperExprs &Exprs);
2283
2284 /// Creates an empty directive with the place
2285 /// for \a NumClauses clauses.
2286 ///
2287 /// \param C AST context.
2288 /// \param CollapsedNum Number of collapsed nested loops.
2289 /// \param NumClauses Number of clauses.
2290 ///
2291 static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
2292 unsigned NumClauses,
2293 unsigned CollapsedNum,
2294 EmptyShell);
2295
2296 static bool classof(const Stmt *T) {
2297 return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
2298 }
2299};
2300
2301/// This represents '#pragma omp parallel master' directive.
2302///
2303/// \code
2304/// #pragma omp parallel master private(a,b)
2305/// \endcode
2306/// In this example directive '#pragma omp parallel master' has clauses
2307/// 'private' with the variables 'a' and 'b'
2308///
2310 friend class ASTStmtReader;
2312
2314 : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
2315 llvm::omp::OMPD_parallel_master, StartLoc,
2316 EndLoc) {}
2317
2319 : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
2320 llvm::omp::OMPD_parallel_master,
2322
2323 /// Sets special task reduction descriptor.
2324 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2325
2326public:
2327 /// Creates directive with a list of \a Clauses.
2328 ///
2329 /// \param C AST context.
2330 /// \param StartLoc Starting location of the directive kind.
2331 /// \param EndLoc Ending Location of the directive.
2332 /// \param Clauses List of clauses.
2333 /// \param AssociatedStmt Statement, associated with the directive.
2334 /// \param TaskRedRef Task reduction special reference expression to handle
2335 /// taskgroup descriptor.
2336 ///
2337 static OMPParallelMasterDirective *
2338 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2339 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
2340
2341 /// Creates an empty directive with the place for \a NumClauses
2342 /// clauses.
2343 ///
2344 /// \param C AST context.
2345 /// \param NumClauses Number of clauses.
2346 ///
2347 static OMPParallelMasterDirective *
2348 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2349
2350 /// Returns special task reduction reference expression.
2352 return cast_or_null<Expr>(Data->getChildren()[0]);
2353 }
2355 return const_cast<OMPParallelMasterDirective *>(this)
2357 }
2358
2359 static bool classof(const Stmt *T) {
2360 return T->getStmtClass() == OMPParallelMasterDirectiveClass;
2361 }
2362};
2363
2364/// This represents '#pragma omp parallel masked' directive.
2365///
2366/// \code
2367/// #pragma omp parallel masked filter(tid)
2368/// \endcode
2369/// In this example directive '#pragma omp parallel masked' has a clause
2370/// 'filter' with the variable tid
2371///
2373 friend class ASTStmtReader;
2375
2377 : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
2378 llvm::omp::OMPD_parallel_masked, StartLoc,
2379 EndLoc) {}
2380
2382 : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
2383 llvm::omp::OMPD_parallel_masked,
2385
2386 /// Sets special task reduction descriptor.
2387 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2388
2389public:
2390 /// Creates directive with a list of \a Clauses.
2391 ///
2392 /// \param C AST context.
2393 /// \param StartLoc Starting location of the directive kind.
2394 /// \param EndLoc Ending Location of the directive.
2395 /// \param Clauses List of clauses.
2396 /// \param AssociatedStmt Statement, associated with the directive.
2397 /// \param TaskRedRef Task reduction special reference expression to handle
2398 /// taskgroup descriptor.
2399 ///
2400 static OMPParallelMaskedDirective *
2401 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2402 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
2403
2404 /// Creates an empty directive with the place for \a NumClauses
2405 /// clauses.
2406 ///
2407 /// \param C AST context.
2408 /// \param NumClauses Number of clauses.
2409 ///
2410 static OMPParallelMaskedDirective *
2411 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2412
2413 /// Returns special task reduction reference expression.
2415 return cast_or_null<Expr>(Data->getChildren()[0]);
2416 }
2418 return const_cast<OMPParallelMaskedDirective *>(this)
2420 }
2421
2422 static bool classof(const Stmt *T) {
2423 return T->getStmtClass() == OMPParallelMaskedDirectiveClass;
2424 }
2425};
2426
2427/// This represents '#pragma omp parallel sections' directive.
2428///
2429/// \code
2430/// #pragma omp parallel sections private(a,b) reduction(+:c,d)
2431/// \endcode
2432/// In this example directive '#pragma omp parallel sections' has clauses
2433/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
2434/// and variables 'c' and 'd'.
2435///
2437 friend class ASTStmtReader;
2439
2440 /// true if current directive has inner cancel directive.
2441 bool HasCancel = false;
2442
2443 /// Build directive with the given start and end location.
2444 ///
2445 /// \param StartLoc Starting location of the directive kind.
2446 /// \param EndLoc Ending location of the directive.
2447 ///
2449 : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
2450 llvm::omp::OMPD_parallel_sections, StartLoc,
2451 EndLoc) {}
2452
2453 /// Build an empty directive.
2454 ///
2456 : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
2457 llvm::omp::OMPD_parallel_sections,
2459
2460 /// Sets special task reduction descriptor.
2461 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2462
2463 /// Set cancel state.
2464 void setHasCancel(bool Has) { HasCancel = Has; }
2465
2466public:
2467 /// Creates directive with a list of \a Clauses.
2468 ///
2469 /// \param C AST context.
2470 /// \param StartLoc Starting location of the directive kind.
2471 /// \param EndLoc Ending Location of the directive.
2472 /// \param Clauses List of clauses.
2473 /// \param AssociatedStmt Statement, associated with the directive.
2474 /// \param TaskRedRef Task reduction special reference expression to handle
2475 /// taskgroup descriptor.
2476 /// \param HasCancel true if current directive has inner cancel directive.
2477 ///
2478 static OMPParallelSectionsDirective *
2479 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2480 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
2481 bool HasCancel);
2482
2483 /// Creates an empty directive with the place for \a NumClauses
2484 /// clauses.
2485 ///
2486 /// \param C AST context.
2487 /// \param NumClauses Number of clauses.
2488 ///
2489 static OMPParallelSectionsDirective *
2490 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2491
2492 /// Returns special task reduction reference expression.
2494 return cast_or_null<Expr>(Data->getChildren()[0]);
2495 }
2497 return const_cast<OMPParallelSectionsDirective *>(this)
2499 }
2500
2501 /// Return true if current directive has inner cancel directive.
2502 bool hasCancel() const { return HasCancel; }
2503
2504 static bool classof(const Stmt *T) {
2505 return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
2506 }
2507};
2508
2509/// This represents '#pragma omp task' directive.
2510///
2511/// \code
2512/// #pragma omp task private(a,b) final(d)
2513/// \endcode
2514/// In this example directive '#pragma omp task' has clauses 'private' with the
2515/// variables 'a' and 'b' and 'final' with condition 'd'.
2516///
2518 friend class ASTStmtReader;
2520 /// true if this directive has inner cancel directive.
2521 bool HasCancel = false;
2522
2523 /// Build directive with the given start and end location.
2524 ///
2525 /// \param StartLoc Starting location of the directive kind.
2526 /// \param EndLoc Ending location of the directive.
2527 ///
2529 : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
2530 StartLoc, EndLoc) {}
2531
2532 /// Build an empty directive.
2533 ///
2534 explicit OMPTaskDirective()
2535 : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
2537
2538 /// Set cancel state.
2539 void setHasCancel(bool Has) { HasCancel = Has; }
2540
2541public:
2542 /// Creates directive with a list of \a Clauses.
2543 ///
2544 /// \param C AST context.
2545 /// \param StartLoc Starting location of the directive kind.
2546 /// \param EndLoc Ending Location of the directive.
2547 /// \param Clauses List of clauses.
2548 /// \param AssociatedStmt Statement, associated with the directive.
2549 /// \param HasCancel true, if current directive has inner cancel directive.
2550 ///
2551 static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2552 SourceLocation EndLoc,
2553 ArrayRef<OMPClause *> Clauses,
2554 Stmt *AssociatedStmt, bool HasCancel);
2555
2556 /// Creates an empty directive with the place for \a NumClauses
2557 /// clauses.
2558 ///
2559 /// \param C AST context.
2560 /// \param NumClauses Number of clauses.
2561 ///
2562 static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
2563 EmptyShell);
2564
2565 /// Return true if current directive has inner cancel directive.
2566 bool hasCancel() const { return HasCancel; }
2567
2568 static bool classof(const Stmt *T) {
2569 return T->getStmtClass() == OMPTaskDirectiveClass;
2570 }
2571};
2572
2573/// This represents '#pragma omp taskyield' directive.
2574///
2575/// \code
2576/// #pragma omp taskyield
2577/// \endcode
2578///
2580 friend class ASTStmtReader;
2582 /// Build directive with the given start and end location.
2583 ///
2584 /// \param StartLoc Starting location of the directive kind.
2585 /// \param EndLoc Ending location of the directive.
2586 ///
2588 : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
2589 llvm::omp::OMPD_taskyield, StartLoc, EndLoc) {}
2590
2591 /// Build an empty directive.
2592 ///
2593 explicit OMPTaskyieldDirective()
2594 : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
2595 llvm::omp::OMPD_taskyield, SourceLocation(),
2596 SourceLocation()) {}
2597
2598public:
2599 /// Creates directive.
2600 ///
2601 /// \param C AST context.
2602 /// \param StartLoc Starting location of the directive kind.
2603 /// \param EndLoc Ending Location of the directive.
2604 ///
2605 static OMPTaskyieldDirective *
2606 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
2607
2608 /// Creates an empty directive.
2609 ///
2610 /// \param C AST context.
2611 ///
2612 static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2613
2614 static bool classof(const Stmt *T) {
2615 return T->getStmtClass() == OMPTaskyieldDirectiveClass;
2616 }
2617};
2618
2619/// This represents '#pragma omp barrier' directive.
2620///
2621/// \code
2622/// #pragma omp barrier
2623/// \endcode
2624///
2626 friend class ASTStmtReader;
2628 /// Build directive with the given start and end location.
2629 ///
2630 /// \param StartLoc Starting location of the directive kind.
2631 /// \param EndLoc Ending location of the directive.
2632 ///
2634 : OMPExecutableDirective(OMPBarrierDirectiveClass,
2635 llvm::omp::OMPD_barrier, StartLoc, EndLoc) {}
2636
2637 /// Build an empty directive.
2638 ///
2639 explicit OMPBarrierDirective()
2640 : OMPExecutableDirective(OMPBarrierDirectiveClass,
2641 llvm::omp::OMPD_barrier, SourceLocation(),
2642 SourceLocation()) {}
2643
2644public:
2645 /// Creates directive.
2646 ///
2647 /// \param C AST context.
2648 /// \param StartLoc Starting location of the directive kind.
2649 /// \param EndLoc Ending Location of the directive.
2650 ///
2651 static OMPBarrierDirective *
2652 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
2653
2654 /// Creates an empty directive.
2655 ///
2656 /// \param C AST context.
2657 ///
2658 static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2659
2660 static bool classof(const Stmt *T) {
2661 return T->getStmtClass() == OMPBarrierDirectiveClass;
2662 }
2663};
2664
2665/// This represents '#pragma omp taskwait' directive.
2666///
2667/// \code
2668/// #pragma omp taskwait
2669/// \endcode
2670///
2672 friend class ASTStmtReader;
2674 /// Build directive with the given start and end location.
2675 ///
2676 /// \param StartLoc Starting location of the directive kind.
2677 /// \param EndLoc Ending location of the directive.
2678 ///
2680 : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
2681 llvm::omp::OMPD_taskwait, StartLoc, EndLoc) {}
2682
2683 /// Build an empty directive.
2684 ///
2685 explicit OMPTaskwaitDirective()
2686 : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
2687 llvm::omp::OMPD_taskwait, SourceLocation(),
2688 SourceLocation()) {}
2689
2690public:
2691 /// Creates directive.
2692 ///
2693 /// \param C AST context.
2694 /// \param StartLoc Starting location of the directive kind.
2695 /// \param EndLoc Ending Location of the directive.
2696 /// \param Clauses List of clauses.
2697 ///
2698 static OMPTaskwaitDirective *Create(const ASTContext &C,
2699 SourceLocation StartLoc,
2700 SourceLocation EndLoc,
2701 ArrayRef<OMPClause *> Clauses);
2702
2703 /// Creates an empty directive.
2704 ///
2705 /// \param C AST context.
2706 /// \param NumClauses Number of clauses.
2707 ///
2708 static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C,
2709 unsigned NumClauses, EmptyShell);
2710
2711 static bool classof(const Stmt *T) {
2712 return T->getStmtClass() == OMPTaskwaitDirectiveClass;
2713 }
2714};
2715
2716/// This represents '#pragma omp taskgroup' directive.
2717///
2718/// \code
2719/// #pragma omp taskgroup
2720/// \endcode
2721///
2723 friend class ASTStmtReader;
2725 /// Build directive with the given start and end location.
2726 ///
2727 /// \param StartLoc Starting location of the directive kind.
2728 /// \param EndLoc Ending location of the directive.
2729 ///
2731 : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
2732 llvm::omp::OMPD_taskgroup, StartLoc, EndLoc) {}
2733
2734 /// Build an empty directive.
2735 ///
2736 explicit OMPTaskgroupDirective()
2737 : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
2738 llvm::omp::OMPD_taskgroup, SourceLocation(),
2739 SourceLocation()) {}
2740
2741 /// Sets the task_reduction return variable.
2742 void setReductionRef(Expr *RR) { Data->getChildren()[0] = RR; }
2743
2744public:
2745 /// Creates directive.
2746 ///
2747 /// \param C AST context.
2748 /// \param StartLoc Starting location of the directive kind.
2749 /// \param EndLoc Ending Location of the directive.
2750 /// \param Clauses List of clauses.
2751 /// \param AssociatedStmt Statement, associated with the directive.
2752 /// \param ReductionRef Reference to the task_reduction return variable.
2753 ///
2754 static OMPTaskgroupDirective *
2755 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2756 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
2757 Expr *ReductionRef);
2758
2759 /// Creates an empty directive.
2760 ///
2761 /// \param C AST context.
2762 /// \param NumClauses Number of clauses.
2763 ///
2764 static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C,
2765 unsigned NumClauses, EmptyShell);
2766
2767
2768 /// Returns reference to the task_reduction return variable.
2769 const Expr *getReductionRef() const {
2770 return const_cast<OMPTaskgroupDirective *>(this)->getReductionRef();
2771 }
2772 Expr *getReductionRef() { return cast_or_null<Expr>(Data->getChildren()[0]); }
2773
2774 static bool classof(const Stmt *T) {
2775 return T->getStmtClass() == OMPTaskgroupDirectiveClass;
2776 }
2777};
2778
2779/// This represents '#pragma omp flush' directive.
2780///
2781/// \code
2782/// #pragma omp flush(a,b)
2783/// \endcode
2784/// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
2785/// and 'b'.
2786/// 'omp flush' directive does not have clauses but have an optional list of
2787/// variables to flush. This list of variables is stored within some fake clause
2788/// FlushClause.
2790 friend class ASTStmtReader;
2792 /// Build directive with the given start and end location.
2793 ///
2794 /// \param StartLoc Starting location of the directive kind.
2795 /// \param EndLoc Ending location of the directive.
2796 ///
2798 : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
2799 StartLoc, EndLoc) {}
2800
2801 /// Build an empty directive.
2802 ///
2803 explicit OMPFlushDirective()
2804 : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
2806
2807public:
2808 /// Creates directive with a list of \a Clauses.
2809 ///
2810 /// \param C AST context.
2811 /// \param StartLoc Starting location of the directive kind.
2812 /// \param EndLoc Ending Location of the directive.
2813 /// \param Clauses List of clauses (only single OMPFlushClause clause is
2814 /// allowed).
2815 ///
2816 static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2817 SourceLocation EndLoc,
2818 ArrayRef<OMPClause *> Clauses);
2819
2820 /// Creates an empty directive with the place for \a NumClauses
2821 /// clauses.
2822 ///
2823 /// \param C AST context.
2824 /// \param NumClauses Number of clauses.
2825 ///
2826 static OMPFlushDirective *CreateEmpty(const ASTContext &C,
2827 unsigned NumClauses, EmptyShell);
2828
2829 static bool classof(const Stmt *T) {
2830 return T->getStmtClass() == OMPFlushDirectiveClass;
2831 }
2832};
2833
2834/// This represents '#pragma omp depobj' directive.
2835///
2836/// \code
2837/// #pragma omp depobj(a) depend(in:x,y)
2838/// \endcode
2839/// In this example directive '#pragma omp depobj' initializes a depobj object
2840/// 'a' with dependence type 'in' and a list with 'x' and 'y' locators.
2842 friend class ASTStmtReader;
2844
2845 /// Build directive with the given start and end location.
2846 ///
2847 /// \param StartLoc Starting location of the directive kind.
2848 /// \param EndLoc Ending location of the directive.
2849 ///
2851 : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
2852 StartLoc, EndLoc) {}
2853
2854 /// Build an empty directive.
2855 ///
2856 explicit OMPDepobjDirective()
2857 : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
2859
2860public:
2861 /// Creates directive with a list of \a Clauses.
2862 ///
2863 /// \param C AST context.
2864 /// \param StartLoc Starting location of the directive kind.
2865 /// \param EndLoc Ending Location of the directive.
2866 /// \param Clauses List of clauses.
2867 ///
2868 static OMPDepobjDirective *Create(const ASTContext &C,
2869 SourceLocation StartLoc,
2870 SourceLocation EndLoc,
2871 ArrayRef<OMPClause *> Clauses);
2872
2873 /// Creates an empty directive with the place for \a NumClauses
2874 /// clauses.
2875 ///
2876 /// \param C AST context.
2877 /// \param NumClauses Number of clauses.
2878 ///
2879 static OMPDepobjDirective *CreateEmpty(const ASTContext &C,
2880 unsigned NumClauses, EmptyShell);
2881
2882 static bool classof(const Stmt *T) {
2883 return T->getStmtClass() == OMPDepobjDirectiveClass;
2884 }
2885};
2886
2887/// This represents '#pragma omp ordered' directive.
2888///
2889/// \code
2890/// #pragma omp ordered
2891/// \endcode
2892///
2894 friend class ASTStmtReader;
2896 /// Build directive with the given start and end location.
2897 ///
2898 /// \param StartLoc Starting location of the directive kind.
2899 /// \param EndLoc Ending location of the directive.
2900 ///
2902 : OMPExecutableDirective(OMPOrderedDirectiveClass,
2903 llvm::omp::OMPD_ordered, StartLoc, EndLoc) {}
2904
2905 /// Build an empty directive.
2906 ///
2907 explicit OMPOrderedDirective()
2908 : OMPExecutableDirective(OMPOrderedDirectiveClass,
2909 llvm::omp::OMPD_ordered, SourceLocation(),
2910 SourceLocation()) {}
2911
2912public:
2913 /// Creates directive.
2914 ///
2915 /// \param C AST context.
2916 /// \param StartLoc Starting location of the directive kind.
2917 /// \param EndLoc Ending Location of the directive.
2918 /// \param Clauses List of clauses.
2919 /// \param AssociatedStmt Statement, associated with the directive.
2920 ///
2921 static OMPOrderedDirective *
2922 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2923 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2924
2925 /// Creates an empty directive.
2926 ///
2927 /// \param C AST context.
2928 /// \param NumClauses Number of clauses.
2929 /// \param IsStandalone true, if the standalone directive is created.
2930 ///
2931 static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
2932 unsigned NumClauses,
2933 bool IsStandalone, EmptyShell);
2934
2935 static bool classof(const Stmt *T) {
2936 return T->getStmtClass() == OMPOrderedDirectiveClass;
2937 }
2938};
2939
2940/// This represents '#pragma omp atomic' directive.
2941///
2942/// \code
2943/// #pragma omp atomic capture
2944/// \endcode
2945/// In this example directive '#pragma omp atomic' has clause 'capture'.
2946///
2948 friend class ASTStmtReader;
2950
2951 struct FlagTy {
2952 /// Used for 'atomic update' or 'atomic capture' constructs. They may
2953 /// have atomic expressions of forms:
2954 /// \code
2955 /// x = x binop expr;
2956 /// x = expr binop x;
2957 /// \endcode
2958 /// This field is 1 for the first form of the expression and 0 for the
2959 /// second. Required for correct codegen of non-associative operations (like
2960 /// << or >>).
2961 LLVM_PREFERRED_TYPE(bool)
2962 uint8_t IsXLHSInRHSPart : 1;
2963 /// Used for 'atomic update' or 'atomic capture' constructs. They may
2964 /// have atomic expressions of forms:
2965 /// \code
2966 /// v = x; <update x>;
2967 /// <update x>; v = x;
2968 /// \endcode
2969 /// This field is 1 for the first(postfix) form of the expression and 0
2970 /// otherwise.
2971 LLVM_PREFERRED_TYPE(bool)
2972 uint8_t IsPostfixUpdate : 1;
2973 /// 1 if 'v' is updated only when the condition is false (compare capture
2974 /// only).
2975 LLVM_PREFERRED_TYPE(bool)
2976 uint8_t IsFailOnly : 1;
2977 } Flags;
2978
2979 /// Build directive with the given start and end location.
2980 ///
2981 /// \param StartLoc Starting location of the directive kind.
2982 /// \param EndLoc Ending location of the directive.
2983 ///
2985 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
2986 StartLoc, EndLoc) {}
2987
2988 /// Build an empty directive.
2989 ///
2990 explicit OMPAtomicDirective()
2991 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
2992 SourceLocation(), SourceLocation()) {}
2993
2994 enum DataPositionTy : size_t {
2995 POS_X = 0,
2996 POS_V,
2997 POS_E,
2998 POS_UpdateExpr,
2999 POS_D,
3000 POS_Cond,
3001 POS_R,
3002 };
3003
3004 /// Set 'x' part of the associated expression/statement.
3005 void setX(Expr *X) { Data->getChildren()[DataPositionTy::POS_X] = X; }
3006 /// Set helper expression of the form
3007 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
3008 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3009 void setUpdateExpr(Expr *UE) {
3010 Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE;
3011 }
3012 /// Set 'v' part of the associated expression/statement.
3013 void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; }
3014 /// Set 'r' part of the associated expression/statement.
3015 void setR(Expr *R) { Data->getChildren()[DataPositionTy::POS_R] = R; }
3016 /// Set 'expr' part of the associated expression/statement.
3017 void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; }
3018 /// Set 'd' part of the associated expression/statement.
3019 void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; }
3020 /// Set conditional expression in `atomic compare`.
3021 void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; }
3022
3023public:
3025 /// 'x' part of the associated expression/statement.
3026 Expr *X = nullptr;
3027 /// 'v' part of the associated expression/statement.
3028 Expr *V = nullptr;
3029 // 'r' part of the associated expression/statement.
3030 Expr *R = nullptr;
3031 /// 'expr' part of the associated expression/statement.
3032 Expr *E = nullptr;
3033 /// UE Helper expression of the form:
3034 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
3035 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3036 Expr *UE = nullptr;
3037 /// 'd' part of the associated expression/statement.
3038 Expr *D = nullptr;
3039 /// Conditional expression in `atomic compare` construct.
3040 Expr *Cond = nullptr;
3041 /// True if UE has the first form and false if the second.
3043 /// True if original value of 'x' must be stored in 'v', not an updated one.
3045 /// True if 'v' is updated only when the condition is false (compare capture
3046 /// only).
3048 };
3049
3050 /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
3051 /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
3052 /// detailed description of 'x', 'v' and 'expr').
3053 ///
3054 /// \param C AST context.
3055 /// \param StartLoc Starting location of the directive kind.
3056 /// \param EndLoc Ending Location of the directive.
3057 /// \param Clauses List of clauses.
3058 /// \param AssociatedStmt Statement, associated with the directive.
3059 /// \param Exprs Associated expressions or statements.
3060 static OMPAtomicDirective *Create(const ASTContext &C,
3061 SourceLocation StartLoc,
3062 SourceLocation EndLoc,
3063 ArrayRef<OMPClause *> Clauses,
3064 Stmt *AssociatedStmt, Expressions Exprs);
3065
3066 /// Creates an empty directive with the place for \a NumClauses
3067 /// clauses.
3068 ///
3069 /// \param C AST context.
3070 /// \param NumClauses Number of clauses.
3071 ///
3073 unsigned NumClauses, EmptyShell);
3074
3075 /// Get 'x' part of the associated expression/statement.
3077 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
3078 }
3079 const Expr *getX() const {
3080 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
3081 }
3082 /// Get helper expression of the form
3083 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
3084 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3086 return cast_or_null<Expr>(
3087 Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
3088 }
3089 const Expr *getUpdateExpr() const {
3090 return cast_or_null<Expr>(
3091 Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
3092 }
3093 /// Return true if helper update expression has form
3094 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
3095 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3096 bool isXLHSInRHSPart() const { return Flags.IsXLHSInRHSPart; }
3097 /// Return true if 'v' expression must be updated to original value of
3098 /// 'x', false if 'v' must be updated to the new value of 'x'.
3099 bool isPostfixUpdate() const { return Flags.IsPostfixUpdate; }
3100 /// Return true if 'v' is updated only when the condition is evaluated false
3101 /// (compare capture only).
3102 bool isFailOnly() const { return Flags.IsFailOnly; }
3103 /// Get 'v' part of the associated expression/statement.
3105 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
3106 }
3107 const Expr *getV() const {
3108 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
3109 }
3110 /// Get 'r' part of the associated expression/statement.
3112 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
3113 }
3114 const Expr *getR() const {
3115 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
3116 }
3117 /// Get 'expr' part of the associated expression/statement.
3119 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
3120 }
3121 const Expr *getExpr() const {
3122 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
3123 }
3124 /// Get 'd' part of the associated expression/statement.
3126 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
3127 }
3128 Expr *getD() const {
3129 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
3130 }
3131 /// Get the 'cond' part of the source atomic expression.
3133 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
3134 }
3136 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
3137 }
3138
3139 static bool classof(const Stmt *T) {
3140 return T->getStmtClass() == OMPAtomicDirectiveClass;
3141 }
3142};
3143
3144/// This represents '#pragma omp target' directive.
3145///
3146/// \code
3147/// #pragma omp target if(a)
3148/// \endcode
3149/// In this example directive '#pragma omp target' has clause 'if' with
3150/// condition 'a'.
3151///
3153 friend class ASTStmtReader;
3155 /// Build directive with the given start and end location.
3156 ///
3157 /// \param StartLoc Starting location of the directive kind.
3158 /// \param EndLoc Ending location of the directive.
3159 ///
3161 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
3162 StartLoc, EndLoc) {}
3163
3164 /// Build an empty directive.
3165 ///
3166 explicit OMPTargetDirective()
3167 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
3169
3170public:
3171 /// Creates directive with a list of \a Clauses.
3172 ///
3173 /// \param C AST context.
3174 /// \param StartLoc Starting location of the directive kind.
3175 /// \param EndLoc Ending Location of the directive.
3176 /// \param Clauses List of clauses.
3177 /// \param AssociatedStmt Statement, associated with the directive.
3178 ///
3179 static OMPTargetDirective *
3180 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3181 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3182
3183 /// Creates an empty directive with the place for \a NumClauses
3184 /// clauses.
3185 ///
3186 /// \param C AST context.
3187 /// \param NumClauses Number of clauses.
3188 ///
3189 static OMPTargetDirective *CreateEmpty(const ASTContext &C,
3190 unsigned NumClauses, EmptyShell);
3191
3192 static bool classof(const Stmt *T) {
3193 return T->getStmtClass() == OMPTargetDirectiveClass;
3194 }
3195};
3196
3197/// This represents '#pragma omp target data' directive.
3198///
3199/// \code
3200/// #pragma omp target data device(0) if(a) map(b[:])
3201/// \endcode
3202/// In this example directive '#pragma omp target data' has clauses 'device'
3203/// with the value '0', 'if' with condition 'a' and 'map' with array
3204/// section 'b[:]'.
3205///
3207 friend class ASTStmtReader;
3209 /// Build directive with the given start and end location.
3210 ///
3211 /// \param StartLoc Starting location of the directive kind.
3212 /// \param EndLoc Ending Location of the directive.
3213 ///
3215 : OMPExecutableDirective(OMPTargetDataDirectiveClass,
3216 llvm::omp::OMPD_target_data, StartLoc, EndLoc) {}
3217
3218 /// Build an empty directive.
3219 ///
3220 explicit OMPTargetDataDirective()
3221 : OMPExecutableDirective(OMPTargetDataDirectiveClass,
3222 llvm::omp::OMPD_target_data, SourceLocation(),
3223 SourceLocation()) {}
3224
3225public:
3226 /// Creates directive with a list of \a Clauses.
3227 ///
3228 /// \param C AST context.
3229 /// \param StartLoc Starting location of the directive kind.
3230 /// \param EndLoc Ending Location of the directive.
3231 /// \param Clauses List of clauses.
3232 /// \param AssociatedStmt Statement, associated with the directive.
3233 ///
3234 static OMPTargetDataDirective *
3235 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3236 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3237
3238 /// Creates an empty directive with the place for \a N clauses.
3239 ///
3240 /// \param C AST context.
3241 /// \param N The number of clauses.
3242 ///
3243 static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
3244 EmptyShell);
3245
3246 static bool classof(const Stmt *T) {
3247 return T->getStmtClass() == OMPTargetDataDirectiveClass;
3248 }
3249};
3250
3251/// This represents '#pragma omp target enter data' directive.
3252///
3253/// \code
3254/// #pragma omp target enter data device(0) if(a) map(b[:])
3255/// \endcode
3256/// In this example directive '#pragma omp target enter data' has clauses
3257/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
3258/// section 'b[:]'.
3259///
3261 friend class ASTStmtReader;
3263 /// Build directive with the given start and end location.
3264 ///
3265 /// \param StartLoc Starting location of the directive kind.
3266 /// \param EndLoc Ending Location of the directive.
3267 ///
3269 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3270 llvm::omp::OMPD_target_enter_data, StartLoc,
3271 EndLoc) {}
3272
3273 /// Build an empty directive.
3274 ///
3276 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3277 llvm::omp::OMPD_target_enter_data,
3279
3280public:
3281 /// Creates directive with a list of \a Clauses.
3282 ///
3283 /// \param C AST context.
3284 /// \param StartLoc Starting location of the directive kind.
3285 /// \param EndLoc Ending Location of the directive.
3286 /// \param Clauses List of clauses.
3287 /// \param AssociatedStmt Statement, associated with the directive.
3288 ///
3289 static OMPTargetEnterDataDirective *
3290 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3291 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3292
3293 /// Creates an empty directive with the place for \a N clauses.
3294 ///
3295 /// \param C AST context.
3296 /// \param N The number of clauses.
3297 ///
3298 static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C,
3299 unsigned N, EmptyShell);
3300
3301 static bool classof(const Stmt *T) {
3302 return T->getStmtClass() == OMPTargetEnterDataDirectiveClass;
3303 }
3304};
3305
3306/// This represents '#pragma omp target exit data' directive.
3307///
3308/// \code
3309/// #pragma omp target exit data device(0) if(a) map(b[:])
3310/// \endcode
3311/// In this example directive '#pragma omp target exit data' has clauses
3312/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
3313/// section 'b[:]'.
3314///
3316 friend class ASTStmtReader;
3318 /// Build directive with the given start and end location.
3319 ///
3320 /// \param StartLoc Starting location of the directive kind.
3321 /// \param EndLoc Ending Location of the directive.
3322 ///
3324 : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3325 llvm::omp::OMPD_target_exit_data, StartLoc,
3326 EndLoc) {}
3327
3328 /// Build an empty directive.
3329 ///
3331 : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3332 llvm::omp::OMPD_target_exit_data,
3334
3335public:
3336 /// Creates directive with a list of \a Clauses.
3337 ///
3338 /// \param C AST context.
3339 /// \param StartLoc Starting location of the directive kind.
3340 /// \param EndLoc Ending Location of the directive.
3341 /// \param Clauses List of clauses.
3342 /// \param AssociatedStmt Statement, associated with the directive.
3343 ///
3344 static OMPTargetExitDataDirective *
3345 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3346 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3347
3348 /// Creates an empty directive with the place for \a N clauses.
3349 ///
3350 /// \param C AST context.
3351 /// \param N The number of clauses.
3352 ///
3353 static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
3354 unsigned N, EmptyShell);
3355
3356 static bool classof(const Stmt *T) {
3357 return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
3358 }
3359};
3360
3361/// This represents '#pragma omp target parallel' directive.
3362///
3363/// \code
3364/// #pragma omp target parallel if(a)
3365/// \endcode
3366/// In this example directive '#pragma omp target parallel' has clause 'if' with
3367/// condition 'a'.
3368///
3370 friend class ASTStmtReader;
3372 /// true if the construct has inner cancel directive.
3373 bool HasCancel = false;
3374
3375 /// Build directive with the given start and end location.
3376 ///
3377 /// \param StartLoc Starting location of the directive kind.
3378 /// \param EndLoc Ending location of the directive.
3379 ///
3381 : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3382 llvm::omp::OMPD_target_parallel, StartLoc,
3383 EndLoc) {}
3384
3385 /// Build an empty directive.
3386 ///
3388 : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3389 llvm::omp::OMPD_target_parallel,
3391
3392 /// Sets special task reduction descriptor.
3393 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
3394 /// Set cancel state.
3395 void setHasCancel(bool Has) { HasCancel = Has; }
3396
3397public:
3398 /// Creates directive with a list of \a Clauses.
3399 ///
3400 /// \param C AST context.
3401 /// \param StartLoc Starting location of the directive kind.
3402 /// \param EndLoc Ending Location of the directive.
3403 /// \param Clauses List of clauses.
3404 /// \param AssociatedStmt Statement, associated with the directive.
3405 /// \param TaskRedRef Task reduction special reference expression to handle
3406 /// taskgroup descriptor.
3407 /// \param HasCancel true if this directive has inner cancel directive.
3408 ///
3409 static OMPTargetParallelDirective *
3410 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3411 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
3412 bool HasCancel);
3413
3414 /// Creates an empty directive with the place for \a NumClauses
3415 /// clauses.
3416 ///
3417 /// \param C AST context.
3418 /// \param NumClauses Number of clauses.
3419 ///
3420 static OMPTargetParallelDirective *
3421 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
3422
3423 /// Returns special task reduction reference expression.
3425 return cast_or_null<Expr>(Data->getChildren()[0]);
3426 }
3428 return const_cast<OMPTargetParallelDirective *>(this)
3430 }
3431
3432 /// Return true if current directive has inner cancel directive.
3433 bool hasCancel() const { return HasCancel; }
3434
3435 static bool classof(const Stmt *T) {
3436 return T->getStmtClass() == OMPTargetParallelDirectiveClass;
3437 }
3438};
3439
3440/// This represents '#pragma omp target parallel for' directive.
3441///
3442/// \code
3443/// #pragma omp target parallel for private(a,b) reduction(+:c,d)
3444/// \endcode
3445/// In this example directive '#pragma omp target parallel for' has clauses
3446/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
3447/// and variables 'c' and 'd'.
3448///
3450 friend class ASTStmtReader;
3452
3453 /// true if current region has inner cancel directive.
3454 bool HasCancel = false;
3455
3456 /// Build directive with the given start and end location.
3457 ///
3458 /// \param StartLoc Starting location of the directive kind.
3459 /// \param EndLoc Ending location of the directive.
3460 /// \param CollapsedNum Number of collapsed nested loops.
3461 ///
3463 unsigned CollapsedNum)
3464 : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3465 llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc,
3466 CollapsedNum) {}
3467
3468 /// Build an empty directive.
3469 ///
3470 /// \param CollapsedNum Number of collapsed nested loops.
3471 ///
3472 explicit OMPTargetParallelForDirective(unsigned CollapsedNum)
3473 : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3474 llvm::omp::OMPD_target_parallel_for, SourceLocation(),
3475 SourceLocation(), CollapsedNum) {}
3476
3477 /// Sets special task reduction descriptor.
3478 void setTaskReductionRefExpr(Expr *E) {
3479 Data->getChildren()[numLoopChildren(
3480 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E;
3481 }
3482
3483 /// Set cancel state.
3484 void setHasCancel(bool Has) { HasCancel = Has; }
3485
3486public:
3487 /// Creates directive with a list of \a Clauses.
3488 ///
3489 /// \param C AST context.
3490 /// \param StartLoc Starting location of the directive kind.
3491 /// \param EndLoc Ending Location of the directive.
3492 /// \param CollapsedNum Number of collapsed loops.
3493 /// \param Clauses List of clauses.
3494 /// \param AssociatedStmt Statement, associated with the directive.
3495 /// \param Exprs Helper expressions for CodeGen.
3496 /// \param TaskRedRef Task reduction special reference expression to handle
3497 /// taskgroup descriptor.
3498 /// \param HasCancel true if current directive has inner cancel directive.
3499 ///
3500 static OMPTargetParallelForDirective *
3501 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3502 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3503 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
3504 bool HasCancel);
3505
3506 /// Creates an empty directive with the place
3507 /// for \a NumClauses clauses.
3508 ///
3509 /// \param C AST context.
3510 /// \param CollapsedNum Number of collapsed nested loops.
3511 /// \param NumClauses Number of clauses.
3512 ///
3513 static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C,
3514 unsigned NumClauses,
3515 unsigned CollapsedNum,
3516 EmptyShell);
3517
3518 /// Returns special task reduction reference expression.
3520 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
3521 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]);
3522 }
3524 return const_cast<OMPTargetParallelForDirective *>(this)
3526 }
3527
3528 /// Return true if current directive has inner cancel directive.
3529 bool hasCancel() const { return HasCancel; }
3530
3531 static bool classof(const Stmt *T) {
3532 return T->getStmtClass() == OMPTargetParallelForDirectiveClass;
3533 }
3534};
3535
3536/// This represents '#pragma omp teams' directive.
3537///
3538/// \code
3539/// #pragma omp teams if(a)
3540/// \endcode
3541/// In this example directive '#pragma omp teams' has clause 'if' with
3542/// condition 'a'.
3543///
3545 friend class ASTStmtReader;
3547 /// Build directive with the given start and end location.
3548 ///
3549 /// \param StartLoc Starting location of the directive kind.
3550 /// \param EndLoc Ending location of the directive.
3551 ///
3553 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3554 StartLoc, EndLoc) {}
3555
3556 /// Build an empty directive.
3557 ///
3558 explicit OMPTeamsDirective()
3559 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3561
3562public:
3563 /// Creates directive with a list of \a Clauses.
3564 ///
3565 /// \param C AST context.
3566 /// \param StartLoc Starting location of the directive kind.
3567 /// \param EndLoc Ending Location of the directive.
3568 /// \param Clauses List of clauses.
3569 /// \param AssociatedStmt Statement, associated with the directive.
3570 ///
3571 static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
3572 SourceLocation EndLoc,
3573 ArrayRef<OMPClause *> Clauses,
3574 Stmt *AssociatedStmt);
3575
3576 /// Creates an empty directive with the place for \a NumClauses
3577 /// clauses.
3578 ///
3579 /// \param C AST context.
3580 /// \param NumClauses Number of clauses.
3581 ///
3582 static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
3583 unsigned NumClauses, EmptyShell);
3584
3585 static bool classof(const Stmt *T) {
3586 return T->getStmtClass() == OMPTeamsDirectiveClass;
3587 }
3588};
3589
3590/// This represents '#pragma omp cancellation point' directive.
3591///
3592/// \code
3593/// #pragma omp cancellation point for
3594/// \endcode
3595///
3596/// In this example a cancellation point is created for innermost 'for' region.
3598 friend class ASTStmtReader;
3600 OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
3601 /// Build directive with the given start and end location.
3602 ///
3603 /// \param StartLoc Starting location of the directive kind.
3604 /// \param EndLoc Ending location of the directive.
3605 /// statements and child expressions.
3606 ///
3608 : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3609 llvm::omp::OMPD_cancellation_point, StartLoc,
3610 EndLoc) {}
3611
3612 /// Build an empty directive.
3614 : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3615 llvm::omp::OMPD_cancellation_point,
3617
3618 /// Set cancel region for current cancellation point.
3619 /// \param CR Cancellation region.
3620 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
3621
3622public:
3623 /// Creates directive.
3624 ///
3625 /// \param C AST context.
3626 /// \param StartLoc Starting location of the directive kind.
3627 /// \param EndLoc Ending Location of the directive.
3628 ///
3629 static OMPCancellationPointDirective *
3630 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3631 OpenMPDirectiveKind CancelRegion);
3632
3633 /// Creates an empty directive.
3634 ///
3635 /// \param C AST context.
3636 ///
3637 static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
3638 EmptyShell);
3639
3640 /// Get cancellation region for the current cancellation point.
3641 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
3642
3643 static bool classof(const Stmt *T) {
3644 return T->getStmtClass() == OMPCancellationPointDirectiveClass;
3645 }
3646};
3647
3648/// This represents '#pragma omp cancel' directive.
3649///
3650/// \code
3651/// #pragma omp cancel for
3652/// \endcode
3653///
3654/// In this example a cancel is created for innermost 'for' region.
3656 friend class ASTStmtReader;
3658 OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
3659 /// Build directive with the given start and end location.
3660 ///
3661 /// \param StartLoc Starting location of the directive kind.
3662 /// \param EndLoc Ending location of the directive.
3663 ///
3665 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3666 StartLoc, EndLoc) {}
3667
3668 /// Build an empty directive.
3669 ///
3670 explicit OMPCancelDirective()
3671 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3673
3674 /// Set cancel region for current cancellation point.
3675 /// \param CR Cancellation region.
3676 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
3677
3678public:
3679 /// Creates directive.
3680 ///
3681 /// \param C AST context.
3682 /// \param StartLoc Starting location of the directive kind.
3683 /// \param EndLoc Ending Location of the directive.
3684 /// \param Clauses List of clauses.
3685 ///
3686 static OMPCancelDirective *
3687 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3688 ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
3689
3690 /// Creates an empty directive.
3691 ///
3692 /// \param C AST context.
3693 /// \param NumClauses Number of clauses.
3694 ///
3695 static OMPCancelDirective *CreateEmpty(const ASTContext &C,
3696 unsigned NumClauses, EmptyShell);
3697
3698 /// Get cancellation region for the current cancellation point.
3699 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
3700
3701 static bool classof(const Stmt *T) {
3702 return T->getStmtClass() == OMPCancelDirectiveClass;
3703 }
3704};
3705
3706/// This represents '#pragma omp taskloop' directive.
3707///
3708/// \code
3709/// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
3710/// \endcode
3711/// In this example directive '#pragma omp taskloop' has clauses 'private'
3712/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
3713/// 'num_tasks' with expression 'num'.
3714///
3716 friend class ASTStmtReader;
3718 /// true if the construct has inner cancel directive.
3719 bool HasCancel = false;
3720
3721 /// Build directive with the given start and end location.
3722 ///
3723 /// \param StartLoc Starting location of the directive kind.
3724 /// \param EndLoc Ending location of the directive.
3725 /// \param CollapsedNum Number of collapsed nested loops.
3726 ///
3728 unsigned CollapsedNum)
3729 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3730 StartLoc, EndLoc, CollapsedNum) {}
3731
3732 /// Build an empty directive.
3733 ///
3734 /// \param CollapsedNum Number of collapsed nested loops.
3735 ///
3736 explicit OMPTaskLoopDirective(unsigned CollapsedNum)
3737 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3738 SourceLocation(), SourceLocation(), CollapsedNum) {}
3739
3740 /// Set cancel state.
3741 void setHasCancel(bool Has) { HasCancel = Has; }
3742
3743public:
3744 /// Creates directive with a list of \a Clauses.
3745 ///
3746 /// \param C AST context.
3747 /// \param StartLoc Starting location of the directive kind.
3748 /// \param EndLoc Ending Location of the directive.
3749 /// \param CollapsedNum Number of collapsed loops.
3750 /// \param Clauses List of clauses.
3751 /// \param AssociatedStmt Statement, associated with the directive.
3752 /// \param Exprs Helper expressions for CodeGen.
3753 /// \param HasCancel true if this directive has inner cancel directive.
3754 ///
3755 static OMPTaskLoopDirective *
3756 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3757 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3758 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3759
3760 /// Creates an empty directive with the place
3761 /// for \a NumClauses clauses.
3762 ///
3763 /// \param C AST context.
3764 /// \param CollapsedNum Number of collapsed nested loops.
3765 /// \param NumClauses Number of clauses.
3766 ///
3767 static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
3768 unsigned NumClauses,
3769 unsigned CollapsedNum, EmptyShell);
3770
3771 /// Return true if current directive has inner cancel directive.
3772 bool hasCancel() const { return HasCancel; }
3773
3774 static bool classof(const Stmt *T) {
3775 return T->getStmtClass() == OMPTaskLoopDirectiveClass;
3776 }
3777};
3778
3779/// This represents '#pragma omp taskloop simd' directive.
3780///
3781/// \code
3782/// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
3783/// \endcode
3784/// In this example directive '#pragma omp taskloop simd' has clauses 'private'
3785/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
3786/// 'num_tasks' with expression 'num'.
3787///
3789 friend class ASTStmtReader;
3791 /// Build directive with the given start and end location.
3792 ///
3793 /// \param StartLoc Starting location of the directive kind.
3794 /// \param EndLoc Ending location of the directive.
3795 /// \param CollapsedNum Number of collapsed nested loops.
3796 ///
3798 unsigned CollapsedNum)
3799 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3800 llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc,
3801 CollapsedNum) {}
3802
3803 /// Build an empty directive.
3804 ///
3805 /// \param CollapsedNum Number of collapsed nested loops.
3806 ///
3807 explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum)
3808 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3809 llvm::omp::OMPD_taskloop_simd, SourceLocation(),
3810 SourceLocation(), CollapsedNum) {}
3811
3812public:
3813 /// Creates directive with a list of \a Clauses.
3814 ///
3815 /// \param C AST context.
3816 /// \param StartLoc Starting location of the directive kind.
3817 /// \param EndLoc Ending Location of the directive.
3818 /// \param CollapsedNum Number of collapsed loops.
3819 /// \param Clauses List of clauses.
3820 /// \param AssociatedStmt Statement, associated with the directive.
3821 /// \param Exprs Helper expressions for CodeGen.
3822 ///
3823 static OMPTaskLoopSimdDirective *
3824 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3825 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3826 Stmt *AssociatedStmt, const HelperExprs &Exprs);
3827
3828 /// Creates an empty directive with the place
3829 /// for \a NumClauses clauses.
3830 ///
3831 /// \param C AST context.
3832 /// \param CollapsedNum Number of collapsed nested loops.
3833 /// \param NumClauses Number of clauses.
3834 ///
3835 static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
3836 unsigned NumClauses,
3837 unsigned CollapsedNum,
3838 EmptyShell);
3839
3840 static bool classof(const Stmt *T) {
3841 return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
3842 }
3843};
3844
3845/// This represents '#pragma omp master taskloop' directive.
3846///
3847/// \code
3848/// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num)
3849/// \endcode
3850/// In this example directive '#pragma omp master taskloop' has clauses
3851/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3852/// and 'num_tasks' with expression 'num'.
3853///
3855 friend class ASTStmtReader;
3857 /// true if the construct has inner cancel directive.
3858 bool HasCancel = false;
3859
3860 /// Build directive with the given start and end location.
3861 ///
3862 /// \param StartLoc Starting location of the directive kind.
3863 /// \param EndLoc Ending location of the directive.
3864 /// \param CollapsedNum Number of collapsed nested loops.
3865 ///
3867 unsigned CollapsedNum)
3868 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3869 llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc,
3870 CollapsedNum) {}
3871
3872 /// Build an empty directive.
3873 ///
3874 /// \param CollapsedNum Number of collapsed nested loops.
3875 ///
3876 explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum)
3877 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3878 llvm::omp::OMPD_master_taskloop, SourceLocation(),
3879 SourceLocation(), CollapsedNum) {}
3880
3881 /// Set cancel state.
3882 void setHasCancel(bool Has) { HasCancel = Has; }
3883
3884public:
3885 /// Creates directive with a list of \a Clauses.
3886 ///
3887 /// \param C AST context.
3888 /// \param StartLoc Starting location of the directive kind.
3889 /// \param EndLoc Ending Location of the directive.
3890 /// \param CollapsedNum Number of collapsed loops.
3891 /// \param Clauses List of clauses.
3892 /// \param AssociatedStmt Statement, associated with the directive.
3893 /// \param Exprs Helper expressions for CodeGen.
3894 /// \param HasCancel true if this directive has inner cancel directive.
3895 ///
3896 static OMPMasterTaskLoopDirective *
3897 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3898 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3899 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3900
3901 /// Creates an empty directive with the place
3902 /// for \a NumClauses clauses.
3903 ///
3904 /// \param C AST context.
3905 /// \param CollapsedNum Number of collapsed nested loops.
3906 /// \param NumClauses Number of clauses.
3907 ///
3908 static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
3909 unsigned NumClauses,
3910 unsigned CollapsedNum,
3911 EmptyShell);
3912
3913 /// Return true if current directive has inner cancel directive.
3914 bool hasCancel() const { return HasCancel; }
3915
3916 static bool classof(const Stmt *T) {
3917 return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass;
3918 }
3919};
3920
3921/// This represents '#pragma omp masked taskloop' directive.
3922///
3923/// \code
3924/// #pragma omp masked taskloop private(a,b) grainsize(val) num_tasks(num)
3925/// \endcode
3926/// In this example directive '#pragma omp masked taskloop' has clauses
3927/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3928/// and 'num_tasks' with expression 'num'.
3929///
3931 friend class ASTStmtReader;
3933 /// true if the construct has inner cancel directive.
3934 bool HasCancel = false;
3935
3936 /// Build directive with the given start and end location.
3937 ///
3938 /// \param StartLoc Starting location of the directive kind.
3939 /// \param EndLoc Ending location of the directive.
3940 /// \param CollapsedNum Number of collapsed nested loops.
3941 ///
3943 unsigned CollapsedNum)
3944 : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
3945 llvm::omp::OMPD_masked_taskloop, StartLoc, EndLoc,
3946 CollapsedNum) {}
3947
3948 /// Build an empty directive.
3949 ///
3950 /// \param CollapsedNum Number of collapsed nested loops.
3951 ///
3952 explicit OMPMaskedTaskLoopDirective(unsigned CollapsedNum)
3953 : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
3954 llvm::omp::OMPD_masked_taskloop, SourceLocation(),
3955 SourceLocation(), CollapsedNum) {}
3956
3957 /// Set cancel state.
3958 void setHasCancel(bool Has) { HasCancel = Has; }
3959
3960public:
3961 /// Creates directive with a list of \a Clauses.
3962 ///
3963 /// \param C AST context.
3964 /// \param StartLoc Starting location of the directive kind.
3965 /// \param EndLoc Ending Location of the directive.
3966 /// \param CollapsedNum Number of collapsed loops.
3967 /// \param Clauses List of clauses.
3968 /// \param AssociatedStmt Statement, associated with the directive.
3969 /// \param Exprs Helper expressions for CodeGen.
3970 /// \param HasCancel true if this directive has inner cancel directive.
3971 ///
3972 static OMPMaskedTaskLoopDirective *
3973 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3974 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3975 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3976
3977 /// Creates an empty directive with the place
3978 /// for \a NumClauses clauses.
3979 ///
3980 /// \param C AST context.
3981 /// \param CollapsedNum Number of collapsed nested loops.
3982 /// \param NumClauses Number of clauses.
3983 ///
3984 static OMPMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
3985 unsigned NumClauses,
3986 unsigned CollapsedNum,
3987 EmptyShell);
3988
3989 /// Return true if current directive has inner cancel directive.
3990 bool hasCancel() const { return HasCancel; }
3991
3992 static bool classof(const Stmt *T) {
3993 return T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass;
3994 }
3995};
3996
3997/// This represents '#pragma omp master taskloop simd' directive.
3998///
3999/// \code
4000/// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num)
4001/// \endcode
4002/// In this example directive '#pragma omp master taskloop simd' has clauses
4003/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4004/// and 'num_tasks' with expression 'num'.
4005///
4007 friend class ASTStmtReader;
4009 /// Build directive with the given start and end location.
4010 ///
4011 /// \param StartLoc Starting location of the directive kind.
4012 /// \param EndLoc Ending location of the directive.
4013 /// \param CollapsedNum Number of collapsed nested loops.
4014 ///
4016 unsigned CollapsedNum)
4017 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
4018 llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc,
4019 CollapsedNum) {}
4020
4021 /// Build an empty directive.
4022 ///
4023 /// \param CollapsedNum Number of collapsed nested loops.
4024 ///
4025 explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum)
4026 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
4027 llvm::omp::OMPD_master_taskloop_simd, SourceLocation(),
4028 SourceLocation(), CollapsedNum) {}
4029
4030public:
4031 /// Creates directive with a list of \p Clauses.
4032 ///
4033 /// \param C AST context.
4034 /// \param StartLoc Starting location of the directive kind.
4035 /// \param EndLoc Ending Location of the directive.
4036 /// \param CollapsedNum Number of collapsed loops.
4037 /// \param Clauses List of clauses.
4038 /// \param AssociatedStmt Statement, associated with the directive.
4039 /// \param Exprs Helper expressions for CodeGen.
4040 ///
4041 static OMPMasterTaskLoopSimdDirective *
4042 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4043 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4044 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4045
4046 /// Creates an empty directive with the place for \p NumClauses clauses.
4047 ///
4048 /// \param C AST context.
4049 /// \param CollapsedNum Number of collapsed nested loops.
4050 /// \param NumClauses Number of clauses.
4051 ///
4052 static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
4053 unsigned NumClauses,
4054 unsigned CollapsedNum,
4055 EmptyShell);
4056
4057 static bool classof(const Stmt *T) {
4058 return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass;
4059 }
4060};
4061
4062/// This represents '#pragma omp masked taskloop simd' directive.
4063///
4064/// \code
4065/// #pragma omp masked taskloop simd private(a,b) grainsize(val) num_tasks(num)
4066/// \endcode
4067/// In this example directive '#pragma omp masked taskloop simd' has clauses
4068/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4069/// and 'num_tasks' with expression 'num'.
4070///
4072 friend class ASTStmtReader;
4074 /// Build directive with the given start and end location.
4075 ///
4076 /// \param StartLoc Starting location of the directive kind.
4077 /// \param EndLoc Ending location of the directive.
4078 /// \param CollapsedNum Number of collapsed nested loops.
4079 ///
4081 unsigned CollapsedNum)
4082 : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
4083 llvm::omp::OMPD_masked_taskloop_simd, StartLoc, EndLoc,
4084 CollapsedNum) {}
4085
4086 /// Build an empty directive.
4087 ///
4088 /// \param CollapsedNum Number of collapsed nested loops.
4089 ///
4090 explicit OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
4091 : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
4092 llvm::omp::OMPD_masked_taskloop_simd, SourceLocation(),
4093 SourceLocation(), CollapsedNum) {}
4094
4095public:
4096 /// Creates directive with a list of \p Clauses.
4097 ///
4098 /// \param C AST context.
4099 /// \param StartLoc Starting location of the directive kind.
4100 /// \param EndLoc Ending Location of the directive.
4101 /// \param CollapsedNum Number of collapsed loops.
4102 /// \param Clauses List of clauses.
4103 /// \param AssociatedStmt Statement, associated with the directive.
4104 /// \param Exprs Helper expressions for CodeGen.
4105 ///
4106 static OMPMaskedTaskLoopSimdDirective *
4107 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4108 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4109 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4110
4111 /// Creates an empty directive with the place for \p NumClauses clauses.
4112 ///
4113 /// \param C AST context.
4114 /// \param CollapsedNum Number of collapsed nested loops.
4115 /// \param NumClauses Number of clauses.
4116 ///
4117 static OMPMaskedTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
4118 unsigned NumClauses,
4119 unsigned CollapsedNum,
4120 EmptyShell);
4121
4122 static bool classof(const Stmt *T) {
4123 return T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass;
4124 }
4125};
4126
4127/// This represents '#pragma omp parallel master taskloop' directive.
4128///
4129/// \code
4130/// #pragma omp parallel master taskloop private(a,b) grainsize(val)
4131/// num_tasks(num)
4132/// \endcode
4133/// In this example directive '#pragma omp parallel master taskloop' has clauses
4134/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4135/// and 'num_tasks' with expression 'num'.
4136///
4138 friend class ASTStmtReader;
4140 /// true if the construct has inner cancel directive.
4141 bool HasCancel = false;
4142
4143 /// Build directive with the given start and end location.
4144 ///
4145 /// \param StartLoc Starting location of the directive kind.
4146 /// \param EndLoc Ending location of the directive.
4147 /// \param CollapsedNum Number of collapsed nested loops.
4148 ///
4150 SourceLocation EndLoc,
4151 unsigned CollapsedNum)
4152 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
4153 llvm::omp::OMPD_parallel_master_taskloop, StartLoc,
4154 EndLoc, CollapsedNum) {}
4155
4156 /// Build an empty directive.
4157 ///
4158 /// \param CollapsedNum Number of collapsed nested loops.
4159 ///
4160 explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum)
4161 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
4162 llvm::omp::OMPD_parallel_master_taskloop,
4163 SourceLocation(), SourceLocation(), CollapsedNum) {}
4164
4165 /// Set cancel state.
4166 void setHasCancel(bool Has) { HasCancel = Has; }
4167
4168public:
4169 /// Creates directive with a list of \a Clauses.
4170 ///
4171 /// \param C AST context.
4172 /// \param StartLoc Starting location of the directive kind.
4173 /// \param EndLoc Ending Location of the directive.
4174 /// \param CollapsedNum Number of collapsed loops.
4175 /// \param Clauses List of clauses.
4176 /// \param AssociatedStmt Statement, associated with the directive.
4177 /// \param Exprs Helper expressions for CodeGen.
4178 /// \param HasCancel true if this directive has inner cancel directive.
4179 ///
4180 static OMPParallelMasterTaskLoopDirective *
4181 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4182 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4183 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
4184
4185 /// Creates an empty directive with the place
4186 /// for \a NumClauses clauses.
4187 ///
4188 /// \param C AST context.
4189 /// \param CollapsedNum Number of collapsed nested loops.
4190 /// \param NumClauses Number of clauses.
4191 ///
4192 static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
4193 unsigned NumClauses,
4194 unsigned CollapsedNum,
4195 EmptyShell);
4196
4197 /// Return true if current directive has inner cancel directive.
4198 bool hasCancel() const { return HasCancel; }
4199
4200 static bool classof(const Stmt *T) {
4201 return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass;
4202 }
4203};
4204
4205/// This represents '#pragma omp parallel masked taskloop' directive.
4206///
4207/// \code
4208/// #pragma omp parallel masked taskloop private(a,b) grainsize(val)
4209/// num_tasks(num)
4210/// \endcode
4211/// In this example directive '#pragma omp parallel masked taskloop' has clauses
4212/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4213/// and 'num_tasks' with expression 'num'.
4214///
4216 friend class ASTStmtReader;
4218 /// true if the construct has inner cancel directive.
4219 bool HasCancel = false;
4220
4221 /// Build directive with the given start and end location.
4222 ///
4223 /// \param StartLoc Starting location of the directive kind.
4224 /// \param EndLoc Ending location of the directive.
4225 /// \param CollapsedNum Number of collapsed nested loops.
4226 ///
4228 SourceLocation EndLoc,
4229 unsigned CollapsedNum)
4230 : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
4231 llvm::omp::OMPD_parallel_masked_taskloop, StartLoc,
4232 EndLoc, CollapsedNum) {}
4233
4234 /// Build an empty directive.
4235 ///
4236 /// \param CollapsedNum Number of collapsed nested loops.
4237 ///
4238 explicit OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum)
4239 : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
4240 llvm::omp::OMPD_parallel_masked_taskloop,
4241 SourceLocation(), SourceLocation(), CollapsedNum) {}
4242
4243 /// Set cancel state.
4244 void setHasCancel(bool Has) { HasCancel = Has; }
4245
4246public:
4247 /// Creates directive with a list of \a Clauses.
4248 ///
4249 /// \param C AST context.
4250 /// \param StartLoc Starting location of the directive kind.
4251 /// \param EndLoc Ending Location of the directive.
4252 /// \param CollapsedNum Number of collapsed loops.
4253 /// \param Clauses List of clauses.
4254 /// \param AssociatedStmt Statement, associated with the directive.
4255 /// \param Exprs Helper expressions for CodeGen.
4256 /// \param HasCancel true if this directive has inner cancel directive.
4257 ///
4258 static OMPParallelMaskedTaskLoopDirective *
4259 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4260 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4261 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
4262
4263 /// Creates an empty directive with the place
4264 /// for \a NumClauses clauses.
4265 ///
4266 /// \param C AST context.
4267 /// \param CollapsedNum Number of collapsed nested loops.
4268 /// \param NumClauses Number of clauses.
4269 ///
4270 static OMPParallelMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
4271 unsigned NumClauses,
4272 unsigned CollapsedNum,
4273 EmptyShell);
4274
4275 /// Return true if current directive has inner cancel directive.
4276 bool hasCancel() const { return HasCancel; }
4277
4278 static bool classof(const Stmt *T) {
4279 return T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass;
4280 }
4281};
4282
4283/// This represents '#pragma omp parallel master taskloop simd' directive.
4284///
4285/// \code
4286/// #pragma omp parallel master taskloop simd private(a,b) grainsize(val)
4287/// num_tasks(num)
4288/// \endcode
4289/// In this example directive '#pragma omp parallel master taskloop simd' has
4290/// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
4291/// expression 'val' and 'num_tasks' with expression 'num'.
4292///
4294 friend class ASTStmtReader;
4296 /// Build directive with the given start and end location.
4297 ///
4298 /// \param StartLoc Starting location of the directive kind.
4299 /// \param EndLoc Ending location of the directive.
4300 /// \param CollapsedNum Number of collapsed nested loops.
4301 ///
4303 SourceLocation EndLoc,
4304 unsigned CollapsedNum)
4305 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
4306 llvm::omp::OMPD_parallel_master_taskloop_simd,
4307 StartLoc, EndLoc, CollapsedNum) {}
4308
4309 /// Build an empty directive.
4310 ///
4311 /// \param CollapsedNum Number of collapsed nested loops.
4312 ///
4313 explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum)
4314 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
4315 llvm::omp::OMPD_parallel_master_taskloop_simd,
4316 SourceLocation(), SourceLocation(), CollapsedNum) {}
4317
4318public:
4319 /// Creates directive with a list of \p Clauses.
4320 ///
4321 /// \param C AST context.
4322 /// \param StartLoc Starting location of the directive kind.
4323 /// \param EndLoc Ending Location of the directive.
4324 /// \param CollapsedNum Number of collapsed loops.
4325 /// \param Clauses List of clauses.
4326 /// \param AssociatedStmt Statement, associated with the directive.
4327 /// \param Exprs Helper expressions for CodeGen.
4328 ///
4329 static OMPParallelMasterTaskLoopSimdDirective *
4330 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4331 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4332 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4333
4334 /// Creates an empty directive with the place
4335 /// for \a NumClauses clauses.
4336 ///
4337 /// \param C AST context.
4338 /// \param CollapsedNum Number of collapsed nested loops.
4339 /// \param NumClauses Number of clauses.
4340 ///
4341 static OMPParallelMasterTaskLoopSimdDirective *
4342 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4343 EmptyShell);
4344
4345 static bool classof(const Stmt *T) {
4346 return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass;
4347 }
4348};
4349
4350/// This represents '#pragma omp parallel masked taskloop simd' directive.
4351///
4352/// \code
4353/// #pragma omp parallel masked taskloop simd private(a,b) grainsize(val)
4354/// num_tasks(num)
4355/// \endcode
4356/// In this example directive '#pragma omp parallel masked taskloop simd' has
4357/// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
4358/// expression 'val' and 'num_tasks' with expression 'num'.
4359///
4361 friend class ASTStmtReader;
4363 /// Build directive with the given start and end location.
4364 ///
4365 /// \param StartLoc Starting location of the directive kind.
4366 /// \param EndLoc Ending location of the directive.
4367 /// \param CollapsedNum Number of collapsed nested loops.
4368 ///
4370 SourceLocation EndLoc,
4371 unsigned CollapsedNum)
4372 : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
4373 llvm::omp::OMPD_parallel_masked_taskloop_simd,
4374 StartLoc, EndLoc, CollapsedNum) {}
4375
4376 /// Build an empty directive.
4377 ///
4378 /// \param CollapsedNum Number of collapsed nested loops.
4379 ///
4380 explicit OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
4381 : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
4382 llvm::omp::OMPD_parallel_masked_taskloop_simd,
4383 SourceLocation(), SourceLocation(), CollapsedNum) {}
4384
4385public:
4386 /// Creates directive with a list of \p Clauses.
4387 ///
4388 /// \param C AST context.
4389 /// \param StartLoc Starting location of the directive kind.
4390 /// \param EndLoc Ending Location of the directive.
4391 /// \param CollapsedNum Number of collapsed loops.
4392 /// \param Clauses List of clauses.
4393 /// \param AssociatedStmt Statement, associated with the directive.
4394 /// \param Exprs Helper expressions for CodeGen.
4395 ///
4396 static OMPParallelMaskedTaskLoopSimdDirective *
4397 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4398 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4399 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4400
4401 /// Creates an empty directive with the place
4402 /// for \a NumClauses clauses.
4403 ///
4404 /// \param C AST context.
4405 /// \param CollapsedNum Number of collapsed nested loops.
4406 /// \param NumClauses Number of clauses.
4407 ///
4408 static OMPParallelMaskedTaskLoopSimdDirective *
4409 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4410 EmptyShell);
4411
4412 static bool classof(const Stmt *T) {
4413 return T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass;
4414 }
4415};
4416
4417/// This represents '#pragma omp distribute' directive.
4418///
4419/// \code
4420/// #pragma omp distribute private(a,b)
4421/// \endcode
4422/// In this example directive '#pragma omp distribute' has clauses 'private'
4423/// with the variables 'a' and 'b'
4424///
4426 friend class ASTStmtReader;
4428
4429 /// Build directive with the given start and end location.
4430 ///
4431 /// \param StartLoc Starting location of the directive kind.
4432 /// \param EndLoc Ending location of the directive.
4433 /// \param CollapsedNum Number of collapsed nested loops.
4434 ///
4436 unsigned CollapsedNum)
4437 : OMPLoopDirective(OMPDistributeDirectiveClass,
4438 llvm::omp::OMPD_distribute, StartLoc, EndLoc,
4439 CollapsedNum) {}
4440
4441 /// Build an empty directive.
4442 ///
4443 /// \param CollapsedNum Number of collapsed nested loops.
4444 ///
4445 explicit OMPDistributeDirective(unsigned CollapsedNum)
4446 : OMPLoopDirective(OMPDistributeDirectiveClass,
4447 llvm::omp::OMPD_distribute, SourceLocation(),
4448 SourceLocation(), CollapsedNum) {}
4449
4450public:
4451 /// Creates directive with a list of \a Clauses.
4452 ///
4453 /// \param C AST context.
4454 /// \param StartLoc Starting location of the directive kind.
4455 /// \param EndLoc Ending Location of the directive.
4456 /// \param CollapsedNum Number of collapsed loops.
4457 /// \param Clauses List of clauses.
4458 /// \param AssociatedStmt Statement, associated with the directive.
4459 /// \param Exprs Helper expressions for CodeGen.
4460 ///
4461 static OMPDistributeDirective *
4462 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4463 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4464 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4465
4466 /// Creates an empty directive with the place
4467 /// for \a NumClauses clauses.
4468 ///
4469 /// \param C AST context.
4470 /// \param CollapsedNum Number of collapsed nested loops.
4471 /// \param NumClauses Number of clauses.
4472 ///
4473 static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
4474 unsigned NumClauses,
4475 unsigned CollapsedNum, EmptyShell);
4476
4477 static bool classof(const Stmt *T) {
4478 return T->getStmtClass() == OMPDistributeDirectiveClass;
4479 }
4480};
4481
4482/// This represents '#pragma omp target update' directive.
4483///
4484/// \code
4485/// #pragma omp target update to(a) from(b) device(1)
4486/// \endcode
4487/// In this example directive '#pragma omp target update' has clause 'to' with
4488/// argument 'a', clause 'from' with argument 'b' and clause 'device' with
4489/// argument '1'.
4490///
4492 friend class ASTStmtReader;
4494 /// Build directive with the given start and end location.
4495 ///
4496 /// \param StartLoc Starting location of the directive kind.
4497 /// \param EndLoc Ending Location of the directive.
4498 ///
4500 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
4501 llvm::omp::OMPD_target_update, StartLoc,
4502 EndLoc) {}
4503
4504 /// Build an empty directive.
4505 ///
4506 explicit OMPTargetUpdateDirective()
4507 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
4508 llvm::omp::OMPD_target_update, SourceLocation(),
4509 SourceLocation()) {}
4510
4511public:
4512 /// Creates directive with a list of \a Clauses.
4513 ///
4514 /// \param C AST context.
4515 /// \param StartLoc Starting location of the directive kind.
4516 /// \param EndLoc Ending Location of the directive.
4517 /// \param Clauses List of clauses.
4518 /// \param AssociatedStmt Statement, associated with the directive.
4519 ///
4520 static OMPTargetUpdateDirective *
4521 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4522 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
4523
4524 /// Creates an empty directive with the place for \a NumClauses
4525 /// clauses.
4526 ///
4527 /// \param C AST context.
4528 /// \param NumClauses The number of clauses.
4529 ///
4530 static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C,
4531 unsigned NumClauses, EmptyShell);
4532
4533 static bool classof(const Stmt *T) {
4534 return T->getStmtClass() == OMPTargetUpdateDirectiveClass;
4535 }
4536};
4537
4538/// This represents '#pragma omp distribute parallel for' composite
4539/// directive.
4540///
4541/// \code
4542/// #pragma omp distribute parallel for private(a,b)
4543/// \endcode
4544/// In this example directive '#pragma omp distribute parallel for' has clause
4545/// 'private' with the variables 'a' and 'b'
4546///
4548 friend class ASTStmtReader;
4550 /// true if the construct has inner cancel directive.
4551 bool HasCancel = false;
4552
4553 /// Build directive with the given start and end location.
4554 ///
4555 /// \param StartLoc Starting location of the directive kind.
4556 /// \param EndLoc Ending location of the directive.
4557 /// \param CollapsedNum Number of collapsed nested loops.
4558 ///
4560 SourceLocation EndLoc,
4561 unsigned CollapsedNum)
4562 : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4563 llvm::omp::OMPD_distribute_parallel_for, StartLoc,
4564 EndLoc, CollapsedNum) {}
4565
4566 /// Build an empty directive.
4567 ///
4568 /// \param CollapsedNum Number of collapsed nested loops.
4569 ///
4570 explicit OMPDistributeParallelForDirective(unsigned CollapsedNum)
4571 : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4572 llvm::omp::OMPD_distribute_parallel_for,
4573 SourceLocation(), SourceLocation(), CollapsedNum) {}
4574
4575 /// Sets special task reduction descriptor.
4576 void setTaskReductionRefExpr(Expr *E) {
4577 Data->getChildren()[numLoopChildren(
4578 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E;
4579 }
4580
4581 /// Set cancel state.
4582 void setHasCancel(bool Has) { HasCancel = Has; }
4583
4584public:
4585 /// Creates directive with a list of \a Clauses.
4586 ///
4587 /// \param C AST context.
4588 /// \param StartLoc Starting location of the directive kind.
4589 /// \param EndLoc Ending Location of the directive.
4590 /// \param CollapsedNum Number of collapsed loops.
4591 /// \param Clauses List of clauses.
4592 /// \param AssociatedStmt Statement, associated with the directive.
4593 /// \param Exprs Helper expressions for CodeGen.
4594 /// \param TaskRedRef Task reduction special reference expression to handle
4595 /// taskgroup descriptor.
4596 /// \param HasCancel true if this directive has inner cancel directive.
4597 ///
4598 static OMPDistributeParallelForDirective *
4599 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4600 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4601 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
4602 bool HasCancel);
4603
4604 /// Creates an empty directive with the place
4605 /// for \a NumClauses clauses.
4606 ///
4607 /// \param C AST context.
4608 /// \param CollapsedNum Number of collapsed nested loops.
4609 /// \param NumClauses Number of clauses.
4610 ///
4611 static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C,
4612 unsigned NumClauses,
4613 unsigned CollapsedNum,
4614 EmptyShell);
4615
4616 /// Returns special task reduction reference expression.
4618 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
4619 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]);
4620 }
4622 return const_cast<OMPDistributeParallelForDirective *>(this)
4624 }
4625
4626 /// Return true if current directive has inner cancel directive.
4627 bool hasCancel() const { return HasCancel; }
4628
4629 static bool classof(const Stmt *T) {
4630 return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
4631 }
4632};
4633
4634/// This represents '#pragma omp distribute parallel for simd' composite
4635/// directive.
4636///
4637/// \code
4638/// #pragma omp distribute parallel for simd private(x)
4639/// \endcode
4640/// In this example directive '#pragma omp distribute parallel for simd' has
4641/// clause 'private' with the variables 'x'
4642///
4644 friend class ASTStmtReader;
4646
4647 /// Build directive with the given start and end location.
4648 ///
4649 /// \param StartLoc Starting location of the directive kind.
4650 /// \param EndLoc Ending location of the directive.
4651 /// \param CollapsedNum Number of collapsed nested loops.
4652 ///
4654 SourceLocation EndLoc,
4655 unsigned CollapsedNum)
4656 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4657 llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc,
4658 EndLoc, CollapsedNum) {}
4659
4660 /// Build an empty directive.
4661 ///
4662 /// \param CollapsedNum Number of collapsed nested loops.
4663 ///
4664 explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum)
4665 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4666 llvm::omp::OMPD_distribute_parallel_for_simd,
4667 SourceLocation(), SourceLocation(), CollapsedNum) {}
4668
4669public:
4670 /// Creates directive with a list of \a Clauses.
4671 ///
4672 /// \param C AST context.
4673 /// \param StartLoc Starting location of the directive kind.
4674 /// \param EndLoc Ending Location of the directive.
4675 /// \param CollapsedNum Number of collapsed loops.
4676 /// \param Clauses List of clauses.
4677 /// \param AssociatedStmt Statement, associated with the directive.
4678 /// \param Exprs Helper expressions for CodeGen.
4679 ///
4680 static OMPDistributeParallelForSimdDirective *Create(
4681 const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4682 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4683 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4684
4685 /// Creates an empty directive with the place for \a NumClauses clauses.
4686 ///
4687 /// \param C AST context.
4688 /// \param CollapsedNum Number of collapsed nested loops.
4689 /// \param NumClauses Number of clauses.
4690 ///
4691 static OMPDistributeParallelForSimdDirective *CreateEmpty(
4692 const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4693 EmptyShell);
4694
4695 static bool classof(const Stmt *T) {
4696 return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass;
4697 }
4698};
4699
4700/// This represents '#pragma omp distribute simd' composite directive.
4701///
4702/// \code
4703/// #pragma omp distribute simd private(x)
4704/// \endcode
4705/// In this example directive '#pragma omp distribute simd' has clause
4706/// 'private' with the variables 'x'
4707///
4709 friend class ASTStmtReader;
4711
4712 /// Build directive with the given start and end location.
4713 ///
4714 /// \param StartLoc Starting location of the directive kind.
4715 /// \param EndLoc Ending location of the directive.
4716 /// \param CollapsedNum Number of collapsed nested loops.
4717 ///
4719 unsigned CollapsedNum)
4720 : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4721 llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc,
4722 CollapsedNum) {}
4723
4724 /// Build an empty directive.
4725 ///
4726 /// \param CollapsedNum Number of collapsed nested loops.
4727 ///
4728 explicit OMPDistributeSimdDirective(unsigned CollapsedNum)
4729 : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4730 llvm::omp::OMPD_distribute_simd, SourceLocation(),
4731 SourceLocation(), CollapsedNum) {}
4732
4733public:
4734 /// Creates directive with a list of \a Clauses.
4735 ///
4736 /// \param C AST context.
4737 /// \param StartLoc Starting location of the directive kind.
4738 /// \param EndLoc Ending Location of the directive.
4739 /// \param CollapsedNum Number of collapsed loops.
4740 /// \param Clauses List of clauses.
4741 /// \param AssociatedStmt Statement, associated with the directive.
4742 /// \param Exprs Helper expressions for CodeGen.
4743 ///
4744 static OMPDistributeSimdDirective *
4745 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4746 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4747 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4748
4749 /// Creates an empty directive with the place for \a NumClauses clauses.
4750 ///
4751 /// \param C AST context.
4752 /// \param CollapsedNum Number of collapsed nested loops.
4753 /// \param NumClauses Number of clauses.
4754 ///
4755 static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C,
4756 unsigned NumClauses,
4757 unsigned CollapsedNum,
4758 EmptyShell);
4759
4760 static bool classof(const Stmt *T) {
4761 return T->getStmtClass() == OMPDistributeSimdDirectiveClass;
4762 }
4763};
4764
4765/// This represents '#pragma omp target parallel for simd' directive.
4766///
4767/// \code
4768/// #pragma omp target parallel for simd private(a) map(b) safelen(c)
4769/// \endcode
4770/// In this example directive '#pragma omp target parallel for simd' has clauses
4771/// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen'
4772/// with the variable 'c'.
4773///
4775 friend class ASTStmtReader;
4777
4778 /// Build directive with the given start and end location.
4779 ///
4780 /// \param StartLoc Starting location of the directive kind.
4781 /// \param EndLoc Ending location of the directive.
4782 /// \param CollapsedNum Number of collapsed nested loops.
4783 ///
4785 SourceLocation EndLoc,
4786 unsigned CollapsedNum)
4787 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4788 llvm::omp::OMPD_target_parallel_for_simd, StartLoc,
4789 EndLoc, CollapsedNum) {}
4790
4791 /// Build an empty directive.
4792 ///
4793 /// \param CollapsedNum Number of collapsed nested loops.
4794 ///
4795 explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum)
4796 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4797 llvm::omp::OMPD_target_parallel_for_simd,
4798 SourceLocation(), SourceLocation(), CollapsedNum) {}
4799
4800public:
4801 /// Creates directive with a list of \a Clauses.
4802 ///
4803 /// \param C AST context.
4804 /// \param StartLoc Starting location of the directive kind.
4805 /// \param EndLoc Ending Location of the directive.
4806 /// \param CollapsedNum Number of collapsed loops.
4807 /// \param Clauses List of clauses.
4808 /// \param AssociatedStmt Statement, associated with the directive.
4809 /// \param Exprs Helper expressions for CodeGen.
4810 ///