clang 17.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() { return NumGeneratedLoops; }
983
984 /// Get the de-sugared statements after the loop transformation.
985 ///
986 /// Might be nullptr if either the directive generates no loops and is handled
987 /// directly in CodeGen, or resolving a template-dependence context is
988 /// required.
989 Stmt *getTransformedStmt() const;
990
991 /// Return preinits statement.
992 Stmt *getPreInits() const;
993
994 static bool classof(const Stmt *T) {
995 return T->getStmtClass() == OMPTileDirectiveClass ||
996 T->getStmtClass() == OMPUnrollDirectiveClass;
997 }
998};
999
1000/// This is a common base class for loop directives ('omp simd', 'omp
1001/// for', 'omp for simd' etc.). It is responsible for the loop code generation.
1002///
1004 friend class ASTStmtReader;
1005
1006 /// Offsets to the stored exprs.
1007 /// This enumeration contains offsets to all the pointers to children
1008 /// expressions stored in OMPLoopDirective.
1009 /// The first 9 children are necessary for all the loop directives,
1010 /// the next 8 are specific to the worksharing ones, and the next 11 are
1011 /// used for combined constructs containing two pragmas associated to loops.
1012 /// After the fixed children, three arrays of length NumAssociatedLoops are
1013 /// allocated: loop counters, their updates and final values.
1014 /// PrevLowerBound and PrevUpperBound are used to communicate blocking
1015 /// information in composite constructs which require loop blocking
1016 /// DistInc is used to generate the increment expression for the distribute
1017 /// loop when combined with a further nested loop
1018 /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the
1019 /// for loop when combined with a previous distribute loop in the same pragma
1020 /// (e.g. 'distribute parallel for')
1021 ///
1022 enum {
1023 IterationVariableOffset = 0,
1024 LastIterationOffset = 1,
1025 CalcLastIterationOffset = 2,
1026 PreConditionOffset = 3,
1027 CondOffset = 4,
1028 InitOffset = 5,
1029 IncOffset = 6,
1030 PreInitsOffset = 7,
1031 // The '...End' enumerators do not correspond to child expressions - they
1032 // specify the offset to the end (and start of the following counters/
1033 // updates/finals/dependent_counters/dependent_inits/finals_conditions
1034 // arrays).
1035 DefaultEnd = 8,
1036 // The following 8 exprs are used by worksharing and distribute loops only.
1037 IsLastIterVariableOffset = 8,
1038 LowerBoundVariableOffset = 9,
1039 UpperBoundVariableOffset = 10,
1040 StrideVariableOffset = 11,
1041 EnsureUpperBoundOffset = 12,
1042 NextLowerBoundOffset = 13,
1043 NextUpperBoundOffset = 14,
1044 NumIterationsOffset = 15,
1045 // Offset to the end for worksharing loop directives.
1046 WorksharingEnd = 16,
1047 PrevLowerBoundVariableOffset = 16,
1048 PrevUpperBoundVariableOffset = 17,
1049 DistIncOffset = 18,
1050 PrevEnsureUpperBoundOffset = 19,
1051 CombinedLowerBoundVariableOffset = 20,
1052 CombinedUpperBoundVariableOffset = 21,
1053 CombinedEnsureUpperBoundOffset = 22,
1054 CombinedInitOffset = 23,
1055 CombinedConditionOffset = 24,
1056 CombinedNextLowerBoundOffset = 25,
1057 CombinedNextUpperBoundOffset = 26,
1058 CombinedDistConditionOffset = 27,
1059 CombinedParForInDistConditionOffset = 28,
1060 // Offset to the end (and start of the following
1061 // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions
1062 // arrays) for combined distribute loop directives.
1063 CombinedDistributeEnd = 29,
1064 };
1065
1066 /// Get the counters storage.
1067 MutableArrayRef<Expr *> getCounters() {
1068 auto **Storage = reinterpret_cast<Expr **>(
1070 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1071 }
1072
1073 /// Get the private counters storage.
1074 MutableArrayRef<Expr *> getPrivateCounters() {
1075 auto **Storage = reinterpret_cast<Expr **>(
1077 getLoopsNumber()]);
1078 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1079 }
1080
1081 /// Get the updates storage.
1082 MutableArrayRef<Expr *> getInits() {
1083 auto **Storage = reinterpret_cast<Expr **>(
1085 2 * getLoopsNumber()]);
1086 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1087 }
1088
1089 /// Get the updates storage.
1090 MutableArrayRef<Expr *> getUpdates() {
1091 auto **Storage = reinterpret_cast<Expr **>(
1093 3 * getLoopsNumber()]);
1094 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1095 }
1096
1097 /// Get the final counter updates storage.
1098 MutableArrayRef<Expr *> getFinals() {
1099 auto **Storage = reinterpret_cast<Expr **>(
1101 4 * getLoopsNumber()]);
1102 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1103 }
1104
1105 /// Get the dependent counters storage.
1106 MutableArrayRef<Expr *> getDependentCounters() {
1107 auto **Storage = reinterpret_cast<Expr **>(
1109 5 * getLoopsNumber()]);
1110 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1111 }
1112
1113 /// Get the dependent inits storage.
1114 MutableArrayRef<Expr *> getDependentInits() {
1115 auto **Storage = reinterpret_cast<Expr **>(
1117 6 * getLoopsNumber()]);
1118 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1119 }
1120
1121 /// Get the finals conditions storage.
1122 MutableArrayRef<Expr *> getFinalsConditions() {
1123 auto **Storage = reinterpret_cast<Expr **>(
1125 7 * getLoopsNumber()]);
1126 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1127 }
1128
1129protected:
1130 /// Build instance of loop directive of class \a Kind.
1131 ///
1132 /// \param SC Statement class.
1133 /// \param Kind Kind of OpenMP directive.
1134 /// \param StartLoc Starting location of the directive (directive keyword).
1135 /// \param EndLoc Ending location of the directive.
1136 /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
1137 ///
1139 SourceLocation StartLoc, SourceLocation EndLoc,
1140 unsigned CollapsedNum)
1141 : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, CollapsedNum) {}
1142
1143 /// Offset to the start of children expression arrays.
1144 static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
1146 return CombinedDistributeEnd;
1149 return WorksharingEnd;
1150 return DefaultEnd;
1151 }
1152
1153 /// Children number.
1154 static unsigned numLoopChildren(unsigned CollapsedNum,
1155 OpenMPDirectiveKind Kind) {
1156 return getArraysOffset(Kind) +
1157 8 * CollapsedNum; // Counters, PrivateCounters, Inits,
1158 // Updates, Finals, DependentCounters,
1159 // DependentInits, FinalsConditions.
1160 }
1161
1163 Data->getChildren()[IterationVariableOffset] = IV;
1164 }
1166 Data->getChildren()[LastIterationOffset] = LI;
1167 }
1169 Data->getChildren()[CalcLastIterationOffset] = CLI;
1170 }
1171 void setPreCond(Expr *PC) { Data->getChildren()[PreConditionOffset] = PC; }
1172 void setCond(Expr *Cond) { Data->getChildren()[CondOffset] = Cond; }
1173 void setInit(Expr *Init) { Data->getChildren()[InitOffset] = Init; }
1174 void setInc(Expr *Inc) { Data->getChildren()[IncOffset] = Inc; }
1175 void setPreInits(Stmt *PreInits) {
1176 Data->getChildren()[PreInitsOffset] = PreInits;
1177 }
1183 "expected worksharing loop directive");
1184 Data->getChildren()[IsLastIterVariableOffset] = IL;
1185 }
1191 "expected worksharing loop directive");
1192 Data->getChildren()[LowerBoundVariableOffset] = LB;
1193 }
1199 "expected worksharing loop directive");
1200 Data->getChildren()[UpperBoundVariableOffset] = UB;
1201 }
1207 "expected worksharing loop directive");
1208 Data->getChildren()[StrideVariableOffset] = ST;
1209 }
1215 "expected worksharing loop directive");
1216 Data->getChildren()[EnsureUpperBoundOffset] = EUB;
1217 }
1223 "expected worksharing loop directive");
1224 Data->getChildren()[NextLowerBoundOffset] = NLB;
1225 }
1231 "expected worksharing loop directive");
1232 Data->getChildren()[NextUpperBoundOffset] = NUB;
1233 }
1239 "expected worksharing loop directive");
1240 Data->getChildren()[NumIterationsOffset] = NI;
1241 }
1244 "expected loop bound sharing directive");
1245 Data->getChildren()[PrevLowerBoundVariableOffset] = PrevLB;
1246 }
1249 "expected loop bound sharing directive");
1250 Data->getChildren()[PrevUpperBoundVariableOffset] = PrevUB;
1251 }
1252 void setDistInc(Expr *DistInc) {
1254 "expected loop bound sharing directive");
1255 Data->getChildren()[DistIncOffset] = DistInc;
1256 }
1259 "expected loop bound sharing directive");
1260 Data->getChildren()[PrevEnsureUpperBoundOffset] = PrevEUB;
1261 }
1264 "expected loop bound sharing directive");
1265 Data->getChildren()[CombinedLowerBoundVariableOffset] = CombLB;
1266 }
1269 "expected loop bound sharing directive");
1270 Data->getChildren()[CombinedUpperBoundVariableOffset] = CombUB;
1271 }
1274 "expected loop bound sharing directive");
1275 Data->getChildren()[CombinedEnsureUpperBoundOffset] = CombEUB;
1276 }
1277 void setCombinedInit(Expr *CombInit) {
1279 "expected loop bound sharing directive");
1280 Data->getChildren()[CombinedInitOffset] = CombInit;
1281 }
1282 void setCombinedCond(Expr *CombCond) {
1284 "expected loop bound sharing directive");
1285 Data->getChildren()[CombinedConditionOffset] = CombCond;
1286 }
1289 "expected loop bound sharing directive");
1290 Data->getChildren()[CombinedNextLowerBoundOffset] = CombNLB;
1291 }
1294 "expected loop bound sharing directive");
1295 Data->getChildren()[CombinedNextUpperBoundOffset] = CombNUB;
1296 }
1297 void setCombinedDistCond(Expr *CombDistCond) {
1299 "expected loop bound distribute sharing directive");
1300 Data->getChildren()[CombinedDistConditionOffset] = CombDistCond;
1301 }
1302 void setCombinedParForInDistCond(Expr *CombParForInDistCond) {
1304 "expected loop bound distribute sharing directive");
1305 Data->getChildren()[CombinedParForInDistConditionOffset] =
1306 CombParForInDistCond;
1307 }
1310 void setInits(ArrayRef<Expr *> A);
1316
1317public:
1319 return cast<Expr>(Data->getChildren()[IterationVariableOffset]);
1320 }
1322 return cast<Expr>(Data->getChildren()[LastIterationOffset]);
1323 }
1325 return cast<Expr>(Data->getChildren()[CalcLastIterationOffset]);
1326 }
1327 Expr *getPreCond() const {
1328 return cast<Expr>(Data->getChildren()[PreConditionOffset]);
1329 }
1330 Expr *getCond() const { return cast<Expr>(Data->getChildren()[CondOffset]); }
1331 Expr *getInit() const { return cast<Expr>(Data->getChildren()[InitOffset]); }
1332 Expr *getInc() const { return cast<Expr>(Data->getChildren()[IncOffset]); }
1333 const Stmt *getPreInits() const {
1334 return Data->getChildren()[PreInitsOffset];
1335 }
1336 Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; }
1342 "expected worksharing loop directive");
1343 return cast<Expr>(Data->getChildren()[IsLastIterVariableOffset]);
1344 }
1350 "expected worksharing loop directive");
1351 return cast<Expr>(Data->getChildren()[LowerBoundVariableOffset]);
1352 }
1358 "expected worksharing loop directive");
1359 return cast<Expr>(Data->getChildren()[UpperBoundVariableOffset]);
1360 }
1366 "expected worksharing loop directive");
1367 return cast<Expr>(Data->getChildren()[StrideVariableOffset]);
1368 }
1374 "expected worksharing loop directive");
1375 return cast<Expr>(Data->getChildren()[EnsureUpperBoundOffset]);
1376 }
1382 "expected worksharing loop directive");
1383 return cast<Expr>(Data->getChildren()[NextLowerBoundOffset]);
1384 }
1390 "expected worksharing loop directive");
1391 return cast<Expr>(Data->getChildren()[NextUpperBoundOffset]);
1392 }
1398 "expected worksharing loop directive");
1399 return cast<Expr>(Data->getChildren()[NumIterationsOffset]);
1400 }
1403 "expected loop bound sharing directive");
1404 return cast<Expr>(Data->getChildren()[PrevLowerBoundVariableOffset]);
1405 }
1408 "expected loop bound sharing directive");
1409 return cast<Expr>(Data->getChildren()[PrevUpperBoundVariableOffset]);
1410 }
1411 Expr *getDistInc() const {
1413 "expected loop bound sharing directive");
1414 return cast<Expr>(Data->getChildren()[DistIncOffset]);
1415 }
1418 "expected loop bound sharing directive");
1419 return cast<Expr>(Data->getChildren()[PrevEnsureUpperBoundOffset]);
1420 }
1423 "expected loop bound sharing directive");
1424 return cast<Expr>(Data->getChildren()[CombinedLowerBoundVariableOffset]);
1425 }
1428 "expected loop bound sharing directive");
1429 return cast<Expr>(Data->getChildren()[CombinedUpperBoundVariableOffset]);
1430 }
1433 "expected loop bound sharing directive");
1434 return cast<Expr>(Data->getChildren()[CombinedEnsureUpperBoundOffset]);
1435 }
1438 "expected loop bound sharing directive");
1439 return cast<Expr>(Data->getChildren()[CombinedInitOffset]);
1440 }
1443 "expected loop bound sharing directive");
1444 return cast<Expr>(Data->getChildren()[CombinedConditionOffset]);
1445 }
1448 "expected loop bound sharing directive");
1449 return cast<Expr>(Data->getChildren()[CombinedNextLowerBoundOffset]);
1450 }
1453 "expected loop bound sharing directive");
1454 return cast<Expr>(Data->getChildren()[CombinedNextUpperBoundOffset]);
1455 }
1458 "expected loop bound distribute sharing directive");
1459 return cast<Expr>(Data->getChildren()[CombinedDistConditionOffset]);
1460 }
1463 "expected loop bound distribute sharing directive");
1464 return cast<Expr>(Data->getChildren()[CombinedParForInDistConditionOffset]);
1465 }
1466 Stmt *getBody();
1467 const Stmt *getBody() const {
1468 return const_cast<OMPLoopDirective *>(this)->getBody();
1469 }
1470
1471 ArrayRef<Expr *> counters() { return getCounters(); }
1472
1474 return const_cast<OMPLoopDirective *>(this)->getCounters();
1475 }
1476
1477 ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
1478
1480 return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
1481 }
1482
1483 ArrayRef<Expr *> inits() { return getInits(); }
1484
1486 return const_cast<OMPLoopDirective *>(this)->getInits();
1487 }
1488
1489 ArrayRef<Expr *> updates() { return getUpdates(); }
1490
1492 return const_cast<OMPLoopDirective *>(this)->getUpdates();
1493 }
1494
1495 ArrayRef<Expr *> finals() { return getFinals(); }
1496
1498 return const_cast<OMPLoopDirective *>(this)->getFinals();
1499 }
1500
1501 ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); }
1502
1504 return const_cast<OMPLoopDirective *>(this)->getDependentCounters();
1505 }
1506
1507 ArrayRef<Expr *> dependent_inits() { return getDependentInits(); }
1508
1510 return const_cast<OMPLoopDirective *>(this)->getDependentInits();
1511 }
1512
1513 ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); }
1514
1516 return const_cast<OMPLoopDirective *>(this)->getFinalsConditions();
1517 }
1518
1519 static bool classof(const Stmt *T) {
1520 return T->getStmtClass() == OMPSimdDirectiveClass ||
1521 T->getStmtClass() == OMPForDirectiveClass ||
1522 T->getStmtClass() == OMPForSimdDirectiveClass ||
1523 T->getStmtClass() == OMPParallelForDirectiveClass ||
1524 T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
1525 T->getStmtClass() == OMPTaskLoopDirectiveClass ||
1526 T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
1527 T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass ||
1528 T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass ||
1529 T->getStmtClass() == OMPMasterTaskLoopDirectiveClass ||
1530 T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass ||
1531 T->getStmtClass() == OMPGenericLoopDirectiveClass ||
1532 T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass ||
1533 T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass ||
1534 T->getStmtClass() == OMPParallelGenericLoopDirectiveClass ||
1535 T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass ||
1536 T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass ||
1537 T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass ||
1538 T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass ||
1539 T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass ||
1540 T->getStmtClass() == OMPDistributeDirectiveClass ||
1541 T->getStmtClass() == OMPTargetParallelForDirectiveClass ||
1542 T->getStmtClass() == OMPDistributeParallelForDirectiveClass ||
1543 T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass ||
1544 T->getStmtClass() == OMPDistributeSimdDirectiveClass ||
1545 T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass ||
1546 T->getStmtClass() == OMPTargetSimdDirectiveClass ||
1547 T->getStmtClass() == OMPTeamsDistributeDirectiveClass ||
1548 T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass ||
1549 T->getStmtClass() ==
1550 OMPTeamsDistributeParallelForSimdDirectiveClass ||
1551 T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass ||
1552 T->getStmtClass() ==
1553 OMPTargetTeamsDistributeParallelForDirectiveClass ||
1554 T->getStmtClass() ==
1555 OMPTargetTeamsDistributeParallelForSimdDirectiveClass ||
1556 T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass ||
1557 T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
1558 }
1559};
1560
1561/// This represents '#pragma omp simd' directive.
1562///
1563/// \code
1564/// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
1565/// \endcode
1566/// In this example directive '#pragma omp simd' has clauses 'private'
1567/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
1568/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
1569///
1571 friend class ASTStmtReader;
1573 /// Build directive with the given start and end location.
1574 ///
1575 /// \param StartLoc Starting location of the directive kind.
1576 /// \param EndLoc Ending location of the directive.
1577 /// \param CollapsedNum Number of collapsed nested loops.
1578 ///
1580 unsigned CollapsedNum)
1581 : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, StartLoc,
1582 EndLoc, CollapsedNum) {}
1583
1584 /// Build an empty directive.
1585 ///
1586 /// \param CollapsedNum Number of collapsed nested loops.
1587 ///
1588 explicit OMPSimdDirective(unsigned CollapsedNum)
1589 : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd,
1590 SourceLocation(), SourceLocation(), CollapsedNum) {}
1591
1592public:
1593 /// Creates directive with a list of \a Clauses.
1594 ///
1595 /// \param C AST context.
1596 /// \param StartLoc Starting location of the directive kind.
1597 /// \param EndLoc Ending Location of the directive.
1598 /// \param CollapsedNum Number of collapsed loops.
1599 /// \param Clauses List of clauses.
1600 /// \param AssociatedStmt Statement, associated with the directive.
1601 /// \param Exprs Helper expressions for CodeGen.
1602 ///
1603 static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1604 SourceLocation EndLoc, unsigned CollapsedNum,
1605 ArrayRef<OMPClause *> Clauses,
1606 Stmt *AssociatedStmt,
1607 const HelperExprs &Exprs);
1608
1609 /// Creates an empty directive with the place
1610 /// for \a NumClauses clauses.
1611 ///
1612 /// \param C AST context.
1613 /// \param CollapsedNum Number of collapsed nested loops.
1614 /// \param NumClauses Number of clauses.
1615 ///
1616 static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1617 unsigned CollapsedNum, EmptyShell);
1618
1619 static bool classof(const Stmt *T) {
1620 return T->getStmtClass() == OMPSimdDirectiveClass;
1621 }
1622};
1623
1624/// This represents '#pragma omp for' directive.
1625///
1626/// \code
1627/// #pragma omp for private(a,b) reduction(+:c,d)
1628/// \endcode
1629/// In this example directive '#pragma omp for' has clauses 'private' with the
1630/// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
1631/// and 'd'.
1632///
1634 friend class ASTStmtReader;
1636 /// true if current directive has inner cancel directive.
1637 bool HasCancel = false;
1638
1639 /// Build directive with the given start and end location.
1640 ///
1641 /// \param StartLoc Starting location of the directive kind.
1642 /// \param EndLoc Ending location of the directive.
1643 /// \param CollapsedNum Number of collapsed nested loops.
1644 ///
1646 unsigned CollapsedNum)
1647 : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, StartLoc,
1648 EndLoc, CollapsedNum) {}
1649
1650 /// Build an empty directive.
1651 ///
1652 /// \param CollapsedNum Number of collapsed nested loops.
1653 ///
1654 explicit OMPForDirective(unsigned CollapsedNum)
1655 : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for,
1656 SourceLocation(), SourceLocation(), CollapsedNum) {}
1657
1658 /// Sets special task reduction descriptor.
1659 void setTaskReductionRefExpr(Expr *E) {
1661 llvm::omp::OMPD_for)] = E;
1662 }
1663
1664 /// Set cancel state.
1665 void setHasCancel(bool Has) { HasCancel = Has; }
1666
1667public:
1668 /// Creates directive with a list of \a Clauses.
1669 ///
1670 /// \param C AST context.
1671 /// \param StartLoc Starting location of the directive kind.
1672 /// \param EndLoc Ending Location of the directive.
1673 /// \param CollapsedNum Number of collapsed loops.
1674 /// \param Clauses List of clauses.
1675 /// \param AssociatedStmt Statement, associated with the directive.
1676 /// \param Exprs Helper expressions for CodeGen.
1677 /// \param TaskRedRef Task reduction special reference expression to handle
1678 /// taskgroup descriptor.
1679 /// \param HasCancel true if current directive has inner cancel directive.
1680 ///
1681 static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1682 SourceLocation EndLoc, unsigned CollapsedNum,
1683 ArrayRef<OMPClause *> Clauses,
1684 Stmt *AssociatedStmt, const HelperExprs &Exprs,
1685 Expr *TaskRedRef, bool HasCancel);
1686
1687 /// Creates an empty directive with the place
1688 /// for \a NumClauses clauses.
1689 ///
1690 /// \param C AST context.
1691 /// \param CollapsedNum Number of collapsed nested loops.
1692 /// \param NumClauses Number of clauses.
1693 ///
1694 static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1695 unsigned CollapsedNum, EmptyShell);
1696
1697 /// Returns special task reduction reference expression.
1699 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
1700 getLoopsNumber(), llvm::omp::OMPD_for)]);
1701 }
1703 return const_cast<OMPForDirective *>(this)->getTaskReductionRefExpr();
1704 }
1705
1706 /// Return true if current directive has inner cancel directive.
1707 bool hasCancel() const { return HasCancel; }
1708
1709 static bool classof(const Stmt *T) {
1710 return T->getStmtClass() == OMPForDirectiveClass;
1711 }
1712};
1713
1714/// This represents '#pragma omp for simd' directive.
1715///
1716/// \code
1717/// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
1718/// \endcode
1719/// In this example directive '#pragma omp for simd' has clauses 'private'
1720/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
1721/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
1722///
1724 friend class ASTStmtReader;
1726 /// Build directive with the given start and end location.
1727 ///
1728 /// \param StartLoc Starting location of the directive kind.
1729 /// \param EndLoc Ending location of the directive.
1730 /// \param CollapsedNum Number of collapsed nested loops.
1731 ///
1733 unsigned CollapsedNum)
1734 : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
1735 StartLoc, EndLoc, CollapsedNum) {}
1736
1737 /// Build an empty directive.
1738 ///
1739 /// \param CollapsedNum Number of collapsed nested loops.
1740 ///
1741 explicit OMPForSimdDirective(unsigned CollapsedNum)
1742 : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
1743 SourceLocation(), SourceLocation(), CollapsedNum) {}
1744
1745public:
1746 /// Creates directive with a list of \a Clauses.
1747 ///
1748 /// \param C AST context.
1749 /// \param StartLoc Starting location of the directive kind.
1750 /// \param EndLoc Ending Location of the directive.
1751 /// \param CollapsedNum Number of collapsed loops.
1752 /// \param Clauses List of clauses.
1753 /// \param AssociatedStmt Statement, associated with the directive.
1754 /// \param Exprs Helper expressions for CodeGen.
1755 ///
1756 static OMPForSimdDirective *
1757 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1758 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1759 Stmt *AssociatedStmt, const HelperExprs &Exprs);
1760
1761 /// Creates an empty directive with the place
1762 /// for \a NumClauses clauses.
1763 ///
1764 /// \param C AST context.
1765 /// \param CollapsedNum Number of collapsed nested loops.
1766 /// \param NumClauses Number of clauses.
1767 ///
1768 static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
1769 unsigned NumClauses,
1770 unsigned CollapsedNum, EmptyShell);
1771
1772 static bool classof(const Stmt *T) {
1773 return T->getStmtClass() == OMPForSimdDirectiveClass;
1774 }
1775};
1776
1777/// This represents '#pragma omp sections' directive.
1778///
1779/// \code
1780/// #pragma omp sections private(a,b) reduction(+:c,d)
1781/// \endcode
1782/// In this example directive '#pragma omp sections' has clauses 'private' with
1783/// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
1784/// 'c' and 'd'.
1785///
1787 friend class ASTStmtReader;
1789
1790 /// true if current directive has inner cancel directive.
1791 bool HasCancel = false;
1792
1793 /// Build directive with the given start and end location.
1794 ///
1795 /// \param StartLoc Starting location of the directive kind.
1796 /// \param EndLoc Ending location of the directive.
1797 ///
1799 : OMPExecutableDirective(OMPSectionsDirectiveClass,
1800 llvm::omp::OMPD_sections, StartLoc, EndLoc) {}
1801
1802 /// Build an empty directive.
1803 ///
1804 explicit OMPSectionsDirective()
1805 : OMPExecutableDirective(OMPSectionsDirectiveClass,
1806 llvm::omp::OMPD_sections, SourceLocation(),
1807 SourceLocation()) {}
1808
1809 /// Sets special task reduction descriptor.
1810 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
1811
1812 /// Set cancel state.
1813 void setHasCancel(bool Has) { HasCancel = Has; }
1814
1815public:
1816 /// Creates directive with a list of \a Clauses.
1817 ///
1818 /// \param C AST context.
1819 /// \param StartLoc Starting location of the directive kind.
1820 /// \param EndLoc Ending Location of the directive.
1821 /// \param Clauses List of clauses.
1822 /// \param AssociatedStmt Statement, associated with the directive.
1823 /// \param TaskRedRef Task reduction special reference expression to handle
1824 /// taskgroup descriptor.
1825 /// \param HasCancel true if current directive has inner directive.
1826 ///
1827 static OMPSectionsDirective *
1828 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1829 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
1830 bool HasCancel);
1831
1832 /// Creates an empty directive with the place for \a NumClauses
1833 /// clauses.
1834 ///
1835 /// \param C AST context.
1836 /// \param NumClauses Number of clauses.
1837 ///
1838 static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
1839 unsigned NumClauses, EmptyShell);
1840
1841 /// Returns special task reduction reference expression.
1843 return cast_or_null<Expr>(Data->getChildren()[0]);
1844 }
1846 return const_cast<OMPSectionsDirective *>(this)->getTaskReductionRefExpr();
1847 }
1848
1849 /// Return true if current directive has inner cancel directive.
1850 bool hasCancel() const { return HasCancel; }
1851
1852 static bool classof(const Stmt *T) {
1853 return T->getStmtClass() == OMPSectionsDirectiveClass;
1854 }
1855};
1856
1857/// This represents '#pragma omp section' directive.
1858///
1859/// \code
1860/// #pragma omp section
1861/// \endcode
1862///
1864 friend class ASTStmtReader;
1866
1867 /// true if current directive has inner cancel directive.
1868 bool HasCancel = false;
1869
1870 /// Build directive with the given start and end location.
1871 ///
1872 /// \param StartLoc Starting location of the directive kind.
1873 /// \param EndLoc Ending location of the directive.
1874 ///
1876 : OMPExecutableDirective(OMPSectionDirectiveClass,
1877 llvm::omp::OMPD_section, StartLoc, EndLoc) {}
1878
1879 /// Build an empty directive.
1880 ///
1881 explicit OMPSectionDirective()
1882 : OMPExecutableDirective(OMPSectionDirectiveClass,
1883 llvm::omp::OMPD_section, SourceLocation(),
1884 SourceLocation()) {}
1885
1886public:
1887 /// Creates directive.
1888 ///
1889 /// \param C AST context.
1890 /// \param StartLoc Starting location of the directive kind.
1891 /// \param EndLoc Ending Location of the directive.
1892 /// \param AssociatedStmt Statement, associated with the directive.
1893 /// \param HasCancel true if current directive has inner directive.
1894 ///
1895 static OMPSectionDirective *Create(const ASTContext &C,
1896 SourceLocation StartLoc,
1897 SourceLocation EndLoc,
1898 Stmt *AssociatedStmt, bool HasCancel);
1899
1900 /// Creates an empty directive.
1901 ///
1902 /// \param C AST context.
1903 ///
1904 static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1905
1906 /// Set cancel state.
1907 void setHasCancel(bool Has) { HasCancel = Has; }
1908
1909 /// Return true if current directive has inner cancel directive.
1910 bool hasCancel() const { return HasCancel; }
1911
1912 static bool classof(const Stmt *T) {
1913 return T->getStmtClass() == OMPSectionDirectiveClass;
1914 }
1915};
1916
1917/// This represents '#pragma omp single' directive.
1918///
1919/// \code
1920/// #pragma omp single private(a,b) copyprivate(c,d)
1921/// \endcode
1922/// In this example directive '#pragma omp single' has clauses 'private' with
1923/// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
1924///
1926 friend class ASTStmtReader;
1928 /// Build directive with the given start and end location.
1929 ///
1930 /// \param StartLoc Starting location of the directive kind.
1931 /// \param EndLoc Ending location of the directive.
1932 ///
1934 : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
1935 StartLoc, EndLoc) {}
1936
1937 /// Build an empty directive.
1938 ///
1939 explicit OMPSingleDirective()
1940 : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
1942
1943public:
1944 /// Creates directive with a list of \a Clauses.
1945 ///
1946 /// \param C AST context.
1947 /// \param StartLoc Starting location of the directive kind.
1948 /// \param EndLoc Ending Location of the directive.
1949 /// \param Clauses List of clauses.
1950 /// \param AssociatedStmt Statement, associated with the directive.
1951 ///
1952 static OMPSingleDirective *
1953 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1954 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1955
1956 /// Creates an empty directive with the place for \a NumClauses
1957 /// clauses.
1958 ///
1959 /// \param C AST context.
1960 /// \param NumClauses Number of clauses.
1961 ///
1962 static OMPSingleDirective *CreateEmpty(const ASTContext &C,
1963 unsigned NumClauses, EmptyShell);
1964
1965 static bool classof(const Stmt *T) {
1966 return T->getStmtClass() == OMPSingleDirectiveClass;
1967 }
1968};
1969
1970/// This represents '#pragma omp master' directive.
1971///
1972/// \code
1973/// #pragma omp master
1974/// \endcode
1975///
1977 friend class ASTStmtReader;
1979 /// Build directive with the given start and end location.
1980 ///
1981 /// \param StartLoc Starting location of the directive kind.
1982 /// \param EndLoc Ending location of the directive.
1983 ///
1985 : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
1986 StartLoc, EndLoc) {}
1987
1988 /// Build an empty directive.
1989 ///
1990 explicit OMPMasterDirective()
1991 : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
1993
1994public:
1995 /// Creates directive.
1996 ///
1997 /// \param C AST context.
1998 /// \param StartLoc Starting location of the directive kind.
1999 /// \param EndLoc Ending Location of the directive.
2000 /// \param AssociatedStmt Statement, associated with the directive.
2001 ///
2002 static OMPMasterDirective *Create(const ASTContext &C,
2003 SourceLocation StartLoc,
2004 SourceLocation EndLoc,
2005 Stmt *AssociatedStmt);
2006
2007 /// Creates an empty directive.
2008 ///
2009 /// \param C AST context.
2010 ///
2011 static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2012
2013 static bool classof(const Stmt *T) {
2014 return T->getStmtClass() == OMPMasterDirectiveClass;
2015 }
2016};
2017
2018/// This represents '#pragma omp critical' directive.
2019///
2020/// \code
2021/// #pragma omp critical
2022/// \endcode
2023///
2025 friend class ASTStmtReader;
2027 /// Name of the directive.
2028 DeclarationNameInfo DirName;
2029 /// Build directive with the given start and end location.
2030 ///
2031 /// \param Name Name of the directive.
2032 /// \param StartLoc Starting location of the directive kind.
2033 /// \param EndLoc Ending location of the directive.
2034 ///
2036 SourceLocation EndLoc)
2037 : OMPExecutableDirective(OMPCriticalDirectiveClass,
2038 llvm::omp::OMPD_critical, StartLoc, EndLoc),
2039 DirName(Name) {}
2040
2041 /// Build an empty directive.
2042 ///
2043 explicit OMPCriticalDirective()
2044 : OMPExecutableDirective(OMPCriticalDirectiveClass,
2045 llvm::omp::OMPD_critical, SourceLocation(),
2046 SourceLocation()) {}
2047
2048 /// Set name of the directive.
2049 ///
2050 /// \param Name Name of the directive.
2051 ///
2052 void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
2053
2054public:
2055 /// Creates directive.
2056 ///
2057 /// \param C AST context.
2058 /// \param Name Name of the directive.
2059 /// \param StartLoc Starting location of the directive kind.
2060 /// \param EndLoc Ending Location of the directive.
2061 /// \param Clauses List of clauses.
2062 /// \param AssociatedStmt Statement, associated with the directive.
2063 ///
2064 static OMPCriticalDirective *
2065 Create(const ASTContext &C, const DeclarationNameInfo &Name,
2066 SourceLocation StartLoc, SourceLocation EndLoc,
2067 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2068
2069 /// Creates an empty directive.
2070 ///
2071 /// \param C AST context.
2072 /// \param NumClauses Number of clauses.
2073 ///
2074 static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
2075 unsigned NumClauses, EmptyShell);
2076
2077 /// Return name of the directive.
2078 ///
2079 DeclarationNameInfo getDirectiveName() const { return DirName; }
2080
2081 static bool classof(const Stmt *T) {
2082 return T->getStmtClass() == OMPCriticalDirectiveClass;
2083 }
2084};
2085
2086/// This represents '#pragma omp parallel for' directive.
2087///
2088/// \code
2089/// #pragma omp parallel for private(a,b) reduction(+:c,d)
2090/// \endcode
2091/// In this example directive '#pragma omp parallel for' has clauses 'private'
2092/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
2093/// variables 'c' and 'd'.
2094///
2096 friend class ASTStmtReader;
2098
2099 /// true if current region has inner cancel directive.
2100 bool HasCancel = false;
2101
2102 /// Build directive with the given start and end location.
2103 ///
2104 /// \param StartLoc Starting location of the directive kind.
2105 /// \param EndLoc Ending location of the directive.
2106 /// \param CollapsedNum Number of collapsed nested loops.
2107 ///
2109 unsigned CollapsedNum)
2110 : OMPLoopDirective(OMPParallelForDirectiveClass,
2111 llvm::omp::OMPD_parallel_for, StartLoc, EndLoc,
2112 CollapsedNum) {}
2113
2114 /// Build an empty directive.
2115 ///
2116 /// \param CollapsedNum Number of collapsed nested loops.
2117 ///
2118 explicit OMPParallelForDirective(unsigned CollapsedNum)
2119 : OMPLoopDirective(OMPParallelForDirectiveClass,
2120 llvm::omp::OMPD_parallel_for, SourceLocation(),
2121 SourceLocation(), CollapsedNum) {}
2122
2123 /// Sets special task reduction descriptor.
2124 void setTaskReductionRefExpr(Expr *E) {
2126 llvm::omp::OMPD_parallel_for)] = E;
2127 }
2128
2129 /// Set cancel state.
2130 void setHasCancel(bool Has) { HasCancel = Has; }
2131
2132public:
2133 /// Creates directive with a list of \a Clauses.
2134 ///
2135 /// \param C AST context.
2136 /// \param StartLoc Starting location of the directive kind.
2137 /// \param EndLoc Ending Location of the directive.
2138 /// \param CollapsedNum Number of collapsed loops.
2139 /// \param Clauses List of clauses.
2140 /// \param AssociatedStmt Statement, associated with the directive.
2141 /// \param Exprs Helper expressions for CodeGen.
2142 /// \param TaskRedRef Task reduction special reference expression to handle
2143 /// taskgroup descriptor.
2144 /// \param HasCancel true if current directive has inner cancel directive.
2145 ///
2146 static OMPParallelForDirective *
2147 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2148 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2149 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
2150 bool HasCancel);
2151
2152 /// Creates an empty directive with the place
2153 /// for \a NumClauses clauses.
2154 ///
2155 /// \param C AST context.
2156 /// \param CollapsedNum Number of collapsed nested loops.
2157 /// \param NumClauses Number of clauses.
2158 ///
2159 static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
2160 unsigned NumClauses,
2161 unsigned CollapsedNum,
2162 EmptyShell);
2163
2164 /// Returns special task reduction reference expression.
2166 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
2167 getLoopsNumber(), llvm::omp::OMPD_parallel_for)]);
2168 }
2170 return const_cast<OMPParallelForDirective *>(this)
2172 }
2173
2174 /// Return true if current directive has inner cancel directive.
2175 bool hasCancel() const { return HasCancel; }
2176
2177 static bool classof(const Stmt *T) {
2178 return T->getStmtClass() == OMPParallelForDirectiveClass;
2179 }
2180};
2181
2182/// This represents '#pragma omp parallel for simd' directive.
2183///
2184/// \code
2185/// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
2186/// \endcode
2187/// In this example directive '#pragma omp parallel for simd' has clauses
2188/// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
2189/// and linear step 's', 'reduction' with operator '+' and variables 'c' and
2190/// 'd'.
2191///
2193 friend class ASTStmtReader;
2195 /// Build directive with the given start and end location.
2196 ///
2197 /// \param StartLoc Starting location of the directive kind.
2198 /// \param EndLoc Ending location of the directive.
2199 /// \param CollapsedNum Number of collapsed nested loops.
2200 ///
2202 unsigned CollapsedNum)
2203 : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
2204 llvm::omp::OMPD_parallel_for_simd, StartLoc, EndLoc,
2205 CollapsedNum) {}
2206
2207 /// Build an empty directive.
2208 ///
2209 /// \param CollapsedNum Number of collapsed nested loops.
2210 ///
2211 explicit OMPParallelForSimdDirective(unsigned CollapsedNum)
2212 : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
2213 llvm::omp::OMPD_parallel_for_simd, SourceLocation(),
2214 SourceLocation(), CollapsedNum) {}
2215
2216public:
2217 /// Creates directive with a list of \a Clauses.
2218 ///
2219 /// \param C AST context.
2220 /// \param StartLoc Starting location of the directive kind.
2221 /// \param EndLoc Ending Location of the directive.
2222 /// \param CollapsedNum Number of collapsed loops.
2223 /// \param Clauses List of clauses.
2224 /// \param AssociatedStmt Statement, associated with the directive.
2225 /// \param Exprs Helper expressions for CodeGen.
2226 ///
2227 static OMPParallelForSimdDirective *
2228 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2229 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2230 Stmt *AssociatedStmt, const HelperExprs &Exprs);
2231
2232 /// Creates an empty directive with the place
2233 /// for \a NumClauses clauses.
2234 ///
2235 /// \param C AST context.
2236 /// \param CollapsedNum Number of collapsed nested loops.
2237 /// \param NumClauses Number of clauses.
2238 ///
2239 static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
2240 unsigned NumClauses,
2241 unsigned CollapsedNum,
2242 EmptyShell);
2243
2244 static bool classof(const Stmt *T) {
2245 return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
2246 }
2247};
2248
2249/// This represents '#pragma omp parallel master' directive.
2250///
2251/// \code
2252/// #pragma omp parallel master private(a,b)
2253/// \endcode
2254/// In this example directive '#pragma omp parallel master' has clauses
2255/// 'private' with the variables 'a' and 'b'
2256///
2258 friend class ASTStmtReader;
2260
2262 : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
2263 llvm::omp::OMPD_parallel_master, StartLoc,
2264 EndLoc) {}
2265
2267 : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
2268 llvm::omp::OMPD_parallel_master,
2270
2271 /// Sets special task reduction descriptor.
2272 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2273
2274public:
2275 /// Creates directive with a list of \a Clauses.
2276 ///
2277 /// \param C AST context.
2278 /// \param StartLoc Starting location of the directive kind.
2279 /// \param EndLoc Ending Location of the directive.
2280 /// \param Clauses List of clauses.
2281 /// \param AssociatedStmt Statement, associated with the directive.
2282 /// \param TaskRedRef Task reduction special reference expression to handle
2283 /// taskgroup descriptor.
2284 ///
2285 static OMPParallelMasterDirective *
2286 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2287 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
2288
2289 /// Creates an empty directive with the place for \a NumClauses
2290 /// clauses.
2291 ///
2292 /// \param C AST context.
2293 /// \param NumClauses Number of clauses.
2294 ///
2295 static OMPParallelMasterDirective *
2296 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2297
2298 /// Returns special task reduction reference expression.
2300 return cast_or_null<Expr>(Data->getChildren()[0]);
2301 }
2303 return const_cast<OMPParallelMasterDirective *>(this)
2305 }
2306
2307 static bool classof(const Stmt *T) {
2308 return T->getStmtClass() == OMPParallelMasterDirectiveClass;
2309 }
2310};
2311
2312/// This represents '#pragma omp parallel masked' directive.
2313///
2314/// \code
2315/// #pragma omp parallel masked filter(tid)
2316/// \endcode
2317/// In this example directive '#pragma omp parallel masked' has a clause
2318/// 'filter' with the variable tid
2319///
2321 friend class ASTStmtReader;
2323
2325 : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
2326 llvm::omp::OMPD_parallel_masked, StartLoc,
2327 EndLoc) {}
2328
2330 : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
2331 llvm::omp::OMPD_parallel_masked,
2333
2334 /// Sets special task reduction descriptor.
2335 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2336
2337public:
2338 /// Creates directive with a list of \a Clauses.
2339 ///
2340 /// \param C AST context.
2341 /// \param StartLoc Starting location of the directive kind.
2342 /// \param EndLoc Ending Location of the directive.
2343 /// \param Clauses List of clauses.
2344 /// \param AssociatedStmt Statement, associated with the directive.
2345 /// \param TaskRedRef Task reduction special reference expression to handle
2346 /// taskgroup descriptor.
2347 ///
2348 static OMPParallelMaskedDirective *
2349 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2350 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
2351
2352 /// Creates an empty directive with the place for \a NumClauses
2353 /// clauses.
2354 ///
2355 /// \param C AST context.
2356 /// \param NumClauses Number of clauses.
2357 ///
2358 static OMPParallelMaskedDirective *
2359 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2360
2361 /// Returns special task reduction reference expression.
2363 return cast_or_null<Expr>(Data->getChildren()[0]);
2364 }
2366 return const_cast<OMPParallelMaskedDirective *>(this)
2368 }
2369
2370 static bool classof(const Stmt *T) {
2371 return T->getStmtClass() == OMPParallelMaskedDirectiveClass;
2372 }
2373};
2374
2375/// This represents '#pragma omp parallel sections' directive.
2376///
2377/// \code
2378/// #pragma omp parallel sections private(a,b) reduction(+:c,d)
2379/// \endcode
2380/// In this example directive '#pragma omp parallel sections' has clauses
2381/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
2382/// and variables 'c' and 'd'.
2383///
2385 friend class ASTStmtReader;
2387
2388 /// true if current directive has inner cancel directive.
2389 bool HasCancel = false;
2390
2391 /// Build directive with the given start and end location.
2392 ///
2393 /// \param StartLoc Starting location of the directive kind.
2394 /// \param EndLoc Ending location of the directive.
2395 ///
2397 : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
2398 llvm::omp::OMPD_parallel_sections, StartLoc,
2399 EndLoc) {}
2400
2401 /// Build an empty directive.
2402 ///
2404 : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
2405 llvm::omp::OMPD_parallel_sections,
2407
2408 /// Sets special task reduction descriptor.
2409 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2410
2411 /// Set cancel state.
2412 void setHasCancel(bool Has) { HasCancel = Has; }
2413
2414public:
2415 /// Creates directive with a list of \a Clauses.
2416 ///
2417 /// \param C AST context.
2418 /// \param StartLoc Starting location of the directive kind.
2419 /// \param EndLoc Ending Location of the directive.
2420 /// \param Clauses List of clauses.
2421 /// \param AssociatedStmt Statement, associated with the directive.
2422 /// \param TaskRedRef Task reduction special reference expression to handle
2423 /// taskgroup descriptor.
2424 /// \param HasCancel true if current directive has inner cancel directive.
2425 ///
2426 static OMPParallelSectionsDirective *
2427 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2428 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
2429 bool HasCancel);
2430
2431 /// Creates an empty directive with the place for \a NumClauses
2432 /// clauses.
2433 ///
2434 /// \param C AST context.
2435 /// \param NumClauses Number of clauses.
2436 ///
2437 static OMPParallelSectionsDirective *
2438 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2439
2440 /// Returns special task reduction reference expression.
2442 return cast_or_null<Expr>(Data->getChildren()[0]);
2443 }
2445 return const_cast<OMPParallelSectionsDirective *>(this)
2447 }
2448
2449 /// Return true if current directive has inner cancel directive.
2450 bool hasCancel() const { return HasCancel; }
2451
2452 static bool classof(const Stmt *T) {
2453 return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
2454 }
2455};
2456
2457/// This represents '#pragma omp task' directive.
2458///
2459/// \code
2460/// #pragma omp task private(a,b) final(d)
2461/// \endcode
2462/// In this example directive '#pragma omp task' has clauses 'private' with the
2463/// variables 'a' and 'b' and 'final' with condition 'd'.
2464///
2466 friend class ASTStmtReader;
2468 /// true if this directive has inner cancel directive.
2469 bool HasCancel = false;
2470
2471 /// Build directive with the given start and end location.
2472 ///
2473 /// \param StartLoc Starting location of the directive kind.
2474 /// \param EndLoc Ending location of the directive.
2475 ///
2477 : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
2478 StartLoc, EndLoc) {}
2479
2480 /// Build an empty directive.
2481 ///
2482 explicit OMPTaskDirective()
2483 : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
2485
2486 /// Set cancel state.
2487 void setHasCancel(bool Has) { HasCancel = Has; }
2488
2489public:
2490 /// Creates directive with a list of \a Clauses.
2491 ///
2492 /// \param C AST context.
2493 /// \param StartLoc Starting location of the directive kind.
2494 /// \param EndLoc Ending Location of the directive.
2495 /// \param Clauses List of clauses.
2496 /// \param AssociatedStmt Statement, associated with the directive.
2497 /// \param HasCancel true, if current directive has inner cancel directive.
2498 ///
2499 static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2500 SourceLocation EndLoc,
2501 ArrayRef<OMPClause *> Clauses,
2502 Stmt *AssociatedStmt, bool HasCancel);
2503
2504 /// Creates an empty directive with the place for \a NumClauses
2505 /// clauses.
2506 ///
2507 /// \param C AST context.
2508 /// \param NumClauses Number of clauses.
2509 ///
2510 static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
2511 EmptyShell);
2512
2513 /// Return true if current directive has inner cancel directive.
2514 bool hasCancel() const { return HasCancel; }
2515
2516 static bool classof(const Stmt *T) {
2517 return T->getStmtClass() == OMPTaskDirectiveClass;
2518 }
2519};
2520
2521/// This represents '#pragma omp taskyield' directive.
2522///
2523/// \code
2524/// #pragma omp taskyield
2525/// \endcode
2526///
2528 friend class ASTStmtReader;
2530 /// Build directive with the given start and end location.
2531 ///
2532 /// \param StartLoc Starting location of the directive kind.
2533 /// \param EndLoc Ending location of the directive.
2534 ///
2536 : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
2537 llvm::omp::OMPD_taskyield, StartLoc, EndLoc) {}
2538
2539 /// Build an empty directive.
2540 ///
2541 explicit OMPTaskyieldDirective()
2542 : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
2543 llvm::omp::OMPD_taskyield, SourceLocation(),
2544 SourceLocation()) {}
2545
2546public:
2547 /// Creates directive.
2548 ///
2549 /// \param C AST context.
2550 /// \param StartLoc Starting location of the directive kind.
2551 /// \param EndLoc Ending Location of the directive.
2552 ///
2553 static OMPTaskyieldDirective *
2554 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
2555
2556 /// Creates an empty directive.
2557 ///
2558 /// \param C AST context.
2559 ///
2560 static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2561
2562 static bool classof(const Stmt *T) {
2563 return T->getStmtClass() == OMPTaskyieldDirectiveClass;
2564 }
2565};
2566
2567/// This represents '#pragma omp barrier' directive.
2568///
2569/// \code
2570/// #pragma omp barrier
2571/// \endcode
2572///
2574 friend class ASTStmtReader;
2576 /// Build directive with the given start and end location.
2577 ///
2578 /// \param StartLoc Starting location of the directive kind.
2579 /// \param EndLoc Ending location of the directive.
2580 ///
2582 : OMPExecutableDirective(OMPBarrierDirectiveClass,
2583 llvm::omp::OMPD_barrier, StartLoc, EndLoc) {}
2584
2585 /// Build an empty directive.
2586 ///
2587 explicit OMPBarrierDirective()
2588 : OMPExecutableDirective(OMPBarrierDirectiveClass,
2589 llvm::omp::OMPD_barrier, SourceLocation(),
2590 SourceLocation()) {}
2591
2592public:
2593 /// Creates directive.
2594 ///
2595 /// \param C AST context.
2596 /// \param StartLoc Starting location of the directive kind.
2597 /// \param EndLoc Ending Location of the directive.
2598 ///
2599 static OMPBarrierDirective *
2600 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
2601
2602 /// Creates an empty directive.
2603 ///
2604 /// \param C AST context.
2605 ///
2606 static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2607
2608 static bool classof(const Stmt *T) {
2609 return T->getStmtClass() == OMPBarrierDirectiveClass;
2610 }
2611};
2612
2613/// This represents '#pragma omp taskwait' directive.
2614///
2615/// \code
2616/// #pragma omp taskwait
2617/// \endcode
2618///
2620 friend class ASTStmtReader;
2622 /// Build directive with the given start and end location.
2623 ///
2624 /// \param StartLoc Starting location of the directive kind.
2625 /// \param EndLoc Ending location of the directive.
2626 ///
2628 : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
2629 llvm::omp::OMPD_taskwait, StartLoc, EndLoc) {}
2630
2631 /// Build an empty directive.
2632 ///
2633 explicit OMPTaskwaitDirective()
2634 : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
2635 llvm::omp::OMPD_taskwait, SourceLocation(),
2636 SourceLocation()) {}
2637
2638public:
2639 /// Creates directive.
2640 ///
2641 /// \param C AST context.
2642 /// \param StartLoc Starting location of the directive kind.
2643 /// \param EndLoc Ending Location of the directive.
2644 /// \param Clauses List of clauses.
2645 ///
2646 static OMPTaskwaitDirective *Create(const ASTContext &C,
2647 SourceLocation StartLoc,
2648 SourceLocation EndLoc,
2649 ArrayRef<OMPClause *> Clauses);
2650
2651 /// Creates an empty directive.
2652 ///
2653 /// \param C AST context.
2654 /// \param NumClauses Number of clauses.
2655 ///
2656 static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C,
2657 unsigned NumClauses, EmptyShell);
2658
2659 static bool classof(const Stmt *T) {
2660 return T->getStmtClass() == OMPTaskwaitDirectiveClass;
2661 }
2662};
2663
2664/// This represents '#pragma omp taskgroup' directive.
2665///
2666/// \code
2667/// #pragma omp taskgroup
2668/// \endcode
2669///
2671 friend class ASTStmtReader;
2673 /// Build directive with the given start and end location.
2674 ///
2675 /// \param StartLoc Starting location of the directive kind.
2676 /// \param EndLoc Ending location of the directive.
2677 ///
2679 : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
2680 llvm::omp::OMPD_taskgroup, StartLoc, EndLoc) {}
2681
2682 /// Build an empty directive.
2683 ///
2684 explicit OMPTaskgroupDirective()
2685 : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
2686 llvm::omp::OMPD_taskgroup, SourceLocation(),
2687 SourceLocation()) {}
2688
2689 /// Sets the task_reduction return variable.
2690 void setReductionRef(Expr *RR) { Data->getChildren()[0] = RR; }
2691
2692public:
2693 /// Creates directive.
2694 ///
2695 /// \param C AST context.
2696 /// \param StartLoc Starting location of the directive kind.
2697 /// \param EndLoc Ending Location of the directive.
2698 /// \param Clauses List of clauses.
2699 /// \param AssociatedStmt Statement, associated with the directive.
2700 /// \param ReductionRef Reference to the task_reduction return variable.
2701 ///
2702 static OMPTaskgroupDirective *
2703 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2704 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
2705 Expr *ReductionRef);
2706
2707 /// Creates an empty directive.
2708 ///
2709 /// \param C AST context.
2710 /// \param NumClauses Number of clauses.
2711 ///
2712 static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C,
2713 unsigned NumClauses, EmptyShell);
2714
2715
2716 /// Returns reference to the task_reduction return variable.
2717 const Expr *getReductionRef() const {
2718 return const_cast<OMPTaskgroupDirective *>(this)->getReductionRef();
2719 }
2720 Expr *getReductionRef() { return cast_or_null<Expr>(Data->getChildren()[0]); }
2721
2722 static bool classof(const Stmt *T) {
2723 return T->getStmtClass() == OMPTaskgroupDirectiveClass;
2724 }
2725};
2726
2727/// This represents '#pragma omp flush' directive.
2728///
2729/// \code
2730/// #pragma omp flush(a,b)
2731/// \endcode
2732/// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
2733/// and 'b'.
2734/// 'omp flush' directive does not have clauses but have an optional list of
2735/// variables to flush. This list of variables is stored within some fake clause
2736/// FlushClause.
2738 friend class ASTStmtReader;
2740 /// Build directive with the given start and end location.
2741 ///
2742 /// \param StartLoc Starting location of the directive kind.
2743 /// \param EndLoc Ending location of the directive.
2744 ///
2746 : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
2747 StartLoc, EndLoc) {}
2748
2749 /// Build an empty directive.
2750 ///
2751 explicit OMPFlushDirective()
2752 : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
2754
2755public:
2756 /// Creates directive with a list of \a Clauses.
2757 ///
2758 /// \param C AST context.
2759 /// \param StartLoc Starting location of the directive kind.
2760 /// \param EndLoc Ending Location of the directive.
2761 /// \param Clauses List of clauses (only single OMPFlushClause clause is
2762 /// allowed).
2763 ///
2764 static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2765 SourceLocation EndLoc,
2766 ArrayRef<OMPClause *> Clauses);
2767
2768 /// Creates an empty directive with the place for \a NumClauses
2769 /// clauses.
2770 ///
2771 /// \param C AST context.
2772 /// \param NumClauses Number of clauses.
2773 ///
2774 static OMPFlushDirective *CreateEmpty(const ASTContext &C,
2775 unsigned NumClauses, EmptyShell);
2776
2777 static bool classof(const Stmt *T) {
2778 return T->getStmtClass() == OMPFlushDirectiveClass;
2779 }
2780};
2781
2782/// This represents '#pragma omp depobj' directive.
2783///
2784/// \code
2785/// #pragma omp depobj(a) depend(in:x,y)
2786/// \endcode
2787/// In this example directive '#pragma omp depobj' initializes a depobj object
2788/// 'a' with dependence type 'in' and a list with 'x' and 'y' locators.
2790 friend class ASTStmtReader;
2792
2793 /// Build directive with the given start and end location.
2794 ///
2795 /// \param StartLoc Starting location of the directive kind.
2796 /// \param EndLoc Ending location of the directive.
2797 ///
2799 : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
2800 StartLoc, EndLoc) {}
2801
2802 /// Build an empty directive.
2803 ///
2804 explicit OMPDepobjDirective()
2805 : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
2807
2808public:
2809 /// Creates directive with a list of \a Clauses.
2810 ///
2811 /// \param C AST context.
2812 /// \param StartLoc Starting location of the directive kind.
2813 /// \param EndLoc Ending Location of the directive.
2814 /// \param Clauses List of clauses.
2815 ///
2816 static OMPDepobjDirective *Create(const ASTContext &C,
2817 SourceLocation StartLoc,
2818 SourceLocation EndLoc,
2819 ArrayRef<OMPClause *> Clauses);
2820
2821 /// Creates an empty directive with the place for \a NumClauses
2822 /// clauses.
2823 ///
2824 /// \param C AST context.
2825 /// \param NumClauses Number of clauses.
2826 ///
2827 static OMPDepobjDirective *CreateEmpty(const ASTContext &C,
2828 unsigned NumClauses, EmptyShell);
2829
2830 static bool classof(const Stmt *T) {
2831 return T->getStmtClass() == OMPDepobjDirectiveClass;
2832 }
2833};
2834
2835/// This represents '#pragma omp ordered' directive.
2836///
2837/// \code
2838/// #pragma omp ordered
2839/// \endcode
2840///
2842 friend class ASTStmtReader;
2844 /// Build directive with the given start and end location.
2845 ///
2846 /// \param StartLoc Starting location of the directive kind.
2847 /// \param EndLoc Ending location of the directive.
2848 ///
2850 : OMPExecutableDirective(OMPOrderedDirectiveClass,
2851 llvm::omp::OMPD_ordered, StartLoc, EndLoc) {}
2852
2853 /// Build an empty directive.
2854 ///
2855 explicit OMPOrderedDirective()
2856 : OMPExecutableDirective(OMPOrderedDirectiveClass,
2857 llvm::omp::OMPD_ordered, SourceLocation(),
2858 SourceLocation()) {}
2859
2860public:
2861 /// Creates directive.
2862 ///
2863 /// \param C AST context.
2864 /// \param StartLoc Starting location of the directive kind.
2865 /// \param EndLoc Ending Location of the directive.
2866 /// \param Clauses List of clauses.
2867 /// \param AssociatedStmt Statement, associated with the directive.
2868 ///
2869 static OMPOrderedDirective *
2870 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2871 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2872
2873 /// Creates an empty directive.
2874 ///
2875 /// \param C AST context.
2876 /// \param NumClauses Number of clauses.
2877 /// \param IsStandalone true, if the standalone directive is created.
2878 ///
2879 static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
2880 unsigned NumClauses,
2881 bool IsStandalone, EmptyShell);
2882
2883 static bool classof(const Stmt *T) {
2884 return T->getStmtClass() == OMPOrderedDirectiveClass;
2885 }
2886};
2887
2888/// This represents '#pragma omp atomic' directive.
2889///
2890/// \code
2891/// #pragma omp atomic capture
2892/// \endcode
2893/// In this example directive '#pragma omp atomic' has clause 'capture'.
2894///
2896 friend class ASTStmtReader;
2898
2899 struct FlagTy {
2900 /// Used for 'atomic update' or 'atomic capture' constructs. They may
2901 /// have atomic expressions of forms:
2902 /// \code
2903 /// x = x binop expr;
2904 /// x = expr binop x;
2905 /// \endcode
2906 /// This field is 1 for the first form of the expression and 0 for the
2907 /// second. Required for correct codegen of non-associative operations (like
2908 /// << or >>).
2909 uint8_t IsXLHSInRHSPart : 1;
2910 /// Used for 'atomic update' or 'atomic capture' constructs. They may
2911 /// have atomic expressions of forms:
2912 /// \code
2913 /// v = x; <update x>;
2914 /// <update x>; v = x;
2915 /// \endcode
2916 /// This field is 1 for the first(postfix) form of the expression and 0
2917 /// otherwise.
2918 uint8_t IsPostfixUpdate : 1;
2919 /// 1 if 'v' is updated only when the condition is false (compare capture
2920 /// only).
2921 uint8_t IsFailOnly : 1;
2922 } Flags;
2923
2924 /// Build directive with the given start and end location.
2925 ///
2926 /// \param StartLoc Starting location of the directive kind.
2927 /// \param EndLoc Ending location of the directive.
2928 ///
2930 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
2931 StartLoc, EndLoc) {}
2932
2933 /// Build an empty directive.
2934 ///
2935 explicit OMPAtomicDirective()
2936 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
2937 SourceLocation(), SourceLocation()) {}
2938
2939 enum DataPositionTy : size_t {
2940 POS_X = 0,
2941 POS_V,
2942 POS_E,
2943 POS_UpdateExpr,
2944 POS_D,
2945 POS_Cond,
2946 POS_R,
2947 };
2948
2949 /// Set 'x' part of the associated expression/statement.
2950 void setX(Expr *X) { Data->getChildren()[DataPositionTy::POS_X] = X; }
2951 /// Set helper expression of the form
2952 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
2953 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2954 void setUpdateExpr(Expr *UE) {
2955 Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE;
2956 }
2957 /// Set 'v' part of the associated expression/statement.
2958 void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; }
2959 /// Set 'r' part of the associated expression/statement.
2960 void setR(Expr *R) { Data->getChildren()[DataPositionTy::POS_R] = R; }
2961 /// Set 'expr' part of the associated expression/statement.
2962 void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; }
2963 /// Set 'd' part of the associated expression/statement.
2964 void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; }
2965 /// Set conditional expression in `atomic compare`.
2966 void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; }
2967
2968public:
2970 /// 'x' part of the associated expression/statement.
2971 Expr *X = nullptr;
2972 /// 'v' part of the associated expression/statement.
2973 Expr *V = nullptr;
2974 // 'r' part of the associated expression/statement.
2975 Expr *R = nullptr;
2976 /// 'expr' part of the associated expression/statement.
2977 Expr *E = nullptr;
2978 /// UE Helper expression of the form:
2979 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
2980 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2981 Expr *UE = nullptr;
2982 /// 'd' part of the associated expression/statement.
2983 Expr *D = nullptr;
2984 /// Conditional expression in `atomic compare` construct.
2985 Expr *Cond = nullptr;
2986 /// True if UE has the first form and false if the second.
2988 /// True if original value of 'x' must be stored in 'v', not an updated one.
2990 /// True if 'v' is updated only when the condition is false (compare capture
2991 /// only).
2993 };
2994
2995 /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
2996 /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
2997 /// detailed description of 'x', 'v' and 'expr').
2998 ///
2999 /// \param C AST context.
3000 /// \param StartLoc Starting location of the directive kind.
3001 /// \param EndLoc Ending Location of the directive.
3002 /// \param Clauses List of clauses.
3003 /// \param AssociatedStmt Statement, associated with the directive.
3004 /// \param Exprs Associated expressions or statements.
3005 static OMPAtomicDirective *Create(const ASTContext &C,
3006 SourceLocation StartLoc,
3007 SourceLocation EndLoc,
3008 ArrayRef<OMPClause *> Clauses,
3009 Stmt *AssociatedStmt, Expressions Exprs);
3010
3011 /// Creates an empty directive with the place for \a NumClauses
3012 /// clauses.
3013 ///
3014 /// \param C AST context.
3015 /// \param NumClauses Number of clauses.
3016 ///
3018 unsigned NumClauses, EmptyShell);
3019
3020 /// Get 'x' part of the associated expression/statement.
3022 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
3023 }
3024 const Expr *getX() const {
3025 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
3026 }
3027 /// Get helper expression of the form
3028 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
3029 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3031 return cast_or_null<Expr>(
3032 Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
3033 }
3034 const Expr *getUpdateExpr() const {
3035 return cast_or_null<Expr>(
3036 Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
3037 }
3038 /// Return true if helper update expression has form
3039 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
3040 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3041 bool isXLHSInRHSPart() const { return Flags.IsXLHSInRHSPart; }
3042 /// Return true if 'v' expression must be updated to original value of
3043 /// 'x', false if 'v' must be updated to the new value of 'x'.
3044 bool isPostfixUpdate() const { return Flags.IsPostfixUpdate; }
3045 /// Return true if 'v' is updated only when the condition is evaluated false
3046 /// (compare capture only).
3047 bool isFailOnly() const { return Flags.IsFailOnly; }
3048 /// Get 'v' part of the associated expression/statement.
3050 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
3051 }
3052 const Expr *getV() const {
3053 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
3054 }
3055 /// Get 'r' part of the associated expression/statement.
3057 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
3058 }
3059 const Expr *getR() const {
3060 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
3061 }
3062 /// Get 'expr' part of the associated expression/statement.
3064 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
3065 }
3066 const Expr *getExpr() const {
3067 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
3068 }
3069 /// Get 'd' part of the associated expression/statement.
3071 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
3072 }
3073 Expr *getD() const {
3074 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
3075 }
3076 /// Get the 'cond' part of the source atomic expression.
3078 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
3079 }
3081 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
3082 }
3083
3084 static bool classof(const Stmt *T) {
3085 return T->getStmtClass() == OMPAtomicDirectiveClass;
3086 }
3087};
3088
3089/// This represents '#pragma omp target' directive.
3090///
3091/// \code
3092/// #pragma omp target if(a)
3093/// \endcode
3094/// In this example directive '#pragma omp target' has clause 'if' with
3095/// condition 'a'.
3096///
3098 friend class ASTStmtReader;
3100 /// Build directive with the given start and end location.
3101 ///
3102 /// \param StartLoc Starting location of the directive kind.
3103 /// \param EndLoc Ending location of the directive.
3104 ///
3106 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
3107 StartLoc, EndLoc) {}
3108
3109 /// Build an empty directive.
3110 ///
3111 explicit OMPTargetDirective()
3112 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
3114
3115public:
3116 /// Creates directive with a list of \a Clauses.
3117 ///
3118 /// \param C AST context.
3119 /// \param StartLoc Starting location of the directive kind.
3120 /// \param EndLoc Ending Location of the directive.
3121 /// \param Clauses List of clauses.
3122 /// \param AssociatedStmt Statement, associated with the directive.
3123 ///
3124 static OMPTargetDirective *
3125 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3126 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3127
3128 /// Creates an empty directive with the place for \a NumClauses
3129 /// clauses.
3130 ///
3131 /// \param C AST context.
3132 /// \param NumClauses Number of clauses.
3133 ///
3134 static OMPTargetDirective *CreateEmpty(const ASTContext &C,
3135 unsigned NumClauses, EmptyShell);
3136
3137 static bool classof(const Stmt *T) {
3138 return T->getStmtClass() == OMPTargetDirectiveClass;
3139 }
3140};
3141
3142/// This represents '#pragma omp target data' directive.
3143///
3144/// \code
3145/// #pragma omp target data device(0) if(a) map(b[:])
3146/// \endcode
3147/// In this example directive '#pragma omp target data' has clauses 'device'
3148/// with the value '0', 'if' with condition 'a' and 'map' with array
3149/// section 'b[:]'.
3150///
3152 friend class ASTStmtReader;
3154 /// Build directive with the given start and end location.
3155 ///
3156 /// \param StartLoc Starting location of the directive kind.
3157 /// \param EndLoc Ending Location of the directive.
3158 ///
3160 : OMPExecutableDirective(OMPTargetDataDirectiveClass,
3161 llvm::omp::OMPD_target_data, StartLoc, EndLoc) {}
3162
3163 /// Build an empty directive.
3164 ///
3165 explicit OMPTargetDataDirective()
3166 : OMPExecutableDirective(OMPTargetDataDirectiveClass,
3167 llvm::omp::OMPD_target_data, SourceLocation(),
3168 SourceLocation()) {}
3169
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 OMPTargetDataDirective *
3180 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3181 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3182
3183 /// Creates an empty directive with the place for \a N clauses.
3184 ///
3185 /// \param C AST context.
3186 /// \param N The number of clauses.
3187 ///
3188 static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
3189 EmptyShell);
3190
3191 static bool classof(const Stmt *T) {
3192 return T->getStmtClass() == OMPTargetDataDirectiveClass;
3193 }
3194};
3195
3196/// This represents '#pragma omp target enter data' directive.
3197///
3198/// \code
3199/// #pragma omp target enter data device(0) if(a) map(b[:])
3200/// \endcode
3201/// In this example directive '#pragma omp target enter data' has clauses
3202/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
3203/// section 'b[:]'.
3204///
3206 friend class ASTStmtReader;
3208 /// Build directive with the given start and end location.
3209 ///
3210 /// \param StartLoc Starting location of the directive kind.
3211 /// \param EndLoc Ending Location of the directive.
3212 ///
3214 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3215 llvm::omp::OMPD_target_enter_data, StartLoc,
3216 EndLoc) {}
3217
3218 /// Build an empty directive.
3219 ///
3221 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3222 llvm::omp::OMPD_target_enter_data,
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 OMPTargetEnterDataDirective *
3235 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3236 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3237
3238 /// Creates an empty directive with the place for \a N clauses.
3239 ///
3240 /// \param C AST context.
3241 /// \param N The number of clauses.
3242 ///
3243 static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C,
3244 unsigned N, EmptyShell);
3245
3246 static bool classof(const Stmt *T) {
3247 return T->getStmtClass() == OMPTargetEnterDataDirectiveClass;
3248 }
3249};
3250
3251/// This represents '#pragma omp target exit data' directive.
3252///
3253/// \code
3254/// #pragma omp target exit data device(0) if(a) map(b[:])
3255/// \endcode
3256/// In this example directive '#pragma omp target exit data' has clauses
3257/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
3258/// section 'b[:]'.
3259///
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(OMPTargetExitDataDirectiveClass,
3270 llvm::omp::OMPD_target_exit_data, StartLoc,
3271 EndLoc) {}
3272
3273 /// Build an empty directive.
3274 ///
3276 : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3277 llvm::omp::OMPD_target_exit_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 OMPTargetExitDataDirective *
3290 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3291 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3292
3293 /// Creates an empty directive with the place for \a N clauses.
3294 ///
3295 /// \param C AST context.
3296 /// \param N The number of clauses.
3297 ///
3298 static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
3299 unsigned N, EmptyShell);
3300
3301 static bool classof(const Stmt *T) {
3302 return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
3303 }
3304};
3305
3306/// This represents '#pragma omp target parallel' directive.
3307///
3308/// \code
3309/// #pragma omp target parallel if(a)
3310/// \endcode
3311/// In this example directive '#pragma omp target parallel' has clause 'if' with
3312/// condition 'a'.
3313///
3315 friend class ASTStmtReader;
3317 /// true if the construct has inner cancel directive.
3318 bool HasCancel = false;
3319
3320 /// Build directive with the given start and end location.
3321 ///
3322 /// \param StartLoc Starting location of the directive kind.
3323 /// \param EndLoc Ending location of the directive.
3324 ///
3326 : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3327 llvm::omp::OMPD_target_parallel, StartLoc,
3328 EndLoc) {}
3329
3330 /// Build an empty directive.
3331 ///
3333 : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3334 llvm::omp::OMPD_target_parallel,
3336
3337 /// Sets special task reduction descriptor.
3338 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
3339 /// Set cancel state.
3340 void setHasCancel(bool Has) { HasCancel = Has; }
3341
3342public:
3343 /// Creates directive with a list of \a Clauses.
3344 ///
3345 /// \param C AST context.
3346 /// \param StartLoc Starting location of the directive kind.
3347 /// \param EndLoc Ending Location of the directive.
3348 /// \param Clauses List of clauses.
3349 /// \param AssociatedStmt Statement, associated with the directive.
3350 /// \param TaskRedRef Task reduction special reference expression to handle
3351 /// taskgroup descriptor.
3352 /// \param HasCancel true if this directive has inner cancel directive.
3353 ///
3354 static OMPTargetParallelDirective *
3355 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3356 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
3357 bool HasCancel);
3358
3359 /// Creates an empty directive with the place for \a NumClauses
3360 /// clauses.
3361 ///
3362 /// \param C AST context.
3363 /// \param NumClauses Number of clauses.
3364 ///
3365 static OMPTargetParallelDirective *
3366 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
3367
3368 /// Returns special task reduction reference expression.
3370 return cast_or_null<Expr>(Data->getChildren()[0]);
3371 }
3373 return const_cast<OMPTargetParallelDirective *>(this)
3375 }
3376
3377 /// Return true if current directive has inner cancel directive.
3378 bool hasCancel() const { return HasCancel; }
3379
3380 static bool classof(const Stmt *T) {
3381 return T->getStmtClass() == OMPTargetParallelDirectiveClass;
3382 }
3383};
3384
3385/// This represents '#pragma omp target parallel for' directive.
3386///
3387/// \code
3388/// #pragma omp target parallel for private(a,b) reduction(+:c,d)
3389/// \endcode
3390/// In this example directive '#pragma omp target parallel for' has clauses
3391/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
3392/// and variables 'c' and 'd'.
3393///
3395 friend class ASTStmtReader;
3397
3398 /// true if current region has inner cancel directive.
3399 bool HasCancel = false;
3400
3401 /// Build directive with the given start and end location.
3402 ///
3403 /// \param StartLoc Starting location of the directive kind.
3404 /// \param EndLoc Ending location of the directive.
3405 /// \param CollapsedNum Number of collapsed nested loops.
3406 ///
3408 unsigned CollapsedNum)
3409 : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3410 llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc,
3411 CollapsedNum) {}
3412
3413 /// Build an empty directive.
3414 ///
3415 /// \param CollapsedNum Number of collapsed nested loops.
3416 ///
3417 explicit OMPTargetParallelForDirective(unsigned CollapsedNum)
3418 : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3419 llvm::omp::OMPD_target_parallel_for, SourceLocation(),
3420 SourceLocation(), CollapsedNum) {}
3421
3422 /// Sets special task reduction descriptor.
3423 void setTaskReductionRefExpr(Expr *E) {
3425 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E;
3426 }
3427
3428 /// Set cancel state.
3429 void setHasCancel(bool Has) { HasCancel = Has; }
3430
3431public:
3432 /// Creates directive with a list of \a Clauses.
3433 ///
3434 /// \param C AST context.
3435 /// \param StartLoc Starting location of the directive kind.
3436 /// \param EndLoc Ending Location of the directive.
3437 /// \param CollapsedNum Number of collapsed loops.
3438 /// \param Clauses List of clauses.
3439 /// \param AssociatedStmt Statement, associated with the directive.
3440 /// \param Exprs Helper expressions for CodeGen.
3441 /// \param TaskRedRef Task reduction special reference expression to handle
3442 /// taskgroup descriptor.
3443 /// \param HasCancel true if current directive has inner cancel directive.
3444 ///
3445 static OMPTargetParallelForDirective *
3446 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3447 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3448 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
3449 bool HasCancel);
3450
3451 /// Creates an empty directive with the place
3452 /// for \a NumClauses clauses.
3453 ///
3454 /// \param C AST context.
3455 /// \param CollapsedNum Number of collapsed nested loops.
3456 /// \param NumClauses Number of clauses.
3457 ///
3458 static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C,
3459 unsigned NumClauses,
3460 unsigned CollapsedNum,
3461 EmptyShell);
3462
3463 /// Returns special task reduction reference expression.
3465 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
3466 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]);
3467 }
3469 return const_cast<OMPTargetParallelForDirective *>(this)
3471 }
3472
3473 /// Return true if current directive has inner cancel directive.
3474 bool hasCancel() const { return HasCancel; }
3475
3476 static bool classof(const Stmt *T) {
3477 return T->getStmtClass() == OMPTargetParallelForDirectiveClass;
3478 }
3479};
3480
3481/// This represents '#pragma omp teams' directive.
3482///
3483/// \code
3484/// #pragma omp teams if(a)
3485/// \endcode
3486/// In this example directive '#pragma omp teams' has clause 'if' with
3487/// condition 'a'.
3488///
3490 friend class ASTStmtReader;
3492 /// Build directive with the given start and end location.
3493 ///
3494 /// \param StartLoc Starting location of the directive kind.
3495 /// \param EndLoc Ending location of the directive.
3496 ///
3498 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3499 StartLoc, EndLoc) {}
3500
3501 /// Build an empty directive.
3502 ///
3503 explicit OMPTeamsDirective()
3504 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3506
3507public:
3508 /// Creates directive with a list of \a Clauses.
3509 ///
3510 /// \param C AST context.
3511 /// \param StartLoc Starting location of the directive kind.
3512 /// \param EndLoc Ending Location of the directive.
3513 /// \param Clauses List of clauses.
3514 /// \param AssociatedStmt Statement, associated with the directive.
3515 ///
3516 static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
3517 SourceLocation EndLoc,
3518 ArrayRef<OMPClause *> Clauses,
3519 Stmt *AssociatedStmt);
3520
3521 /// Creates an empty directive with the place for \a NumClauses
3522 /// clauses.
3523 ///
3524 /// \param C AST context.
3525 /// \param NumClauses Number of clauses.
3526 ///
3527 static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
3528 unsigned NumClauses, EmptyShell);
3529
3530 static bool classof(const Stmt *T) {
3531 return T->getStmtClass() == OMPTeamsDirectiveClass;
3532 }
3533};
3534
3535/// This represents '#pragma omp cancellation point' directive.
3536///
3537/// \code
3538/// #pragma omp cancellation point for
3539/// \endcode
3540///
3541/// In this example a cancellation point is created for innermost 'for' region.
3543 friend class ASTStmtReader;
3545 OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
3546 /// Build directive with the given start and end location.
3547 ///
3548 /// \param StartLoc Starting location of the directive kind.
3549 /// \param EndLoc Ending location of the directive.
3550 /// statements and child expressions.
3551 ///
3553 : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3554 llvm::omp::OMPD_cancellation_point, StartLoc,
3555 EndLoc) {}
3556
3557 /// Build an empty directive.
3559 : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3560 llvm::omp::OMPD_cancellation_point,
3562
3563 /// Set cancel region for current cancellation point.
3564 /// \param CR Cancellation region.
3565 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
3566
3567public:
3568 /// Creates directive.
3569 ///
3570 /// \param C AST context.
3571 /// \param StartLoc Starting location of the directive kind.
3572 /// \param EndLoc Ending Location of the directive.
3573 ///
3574 static OMPCancellationPointDirective *
3575 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3576 OpenMPDirectiveKind CancelRegion);
3577
3578 /// Creates an empty directive.
3579 ///
3580 /// \param C AST context.
3581 ///
3582 static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
3583 EmptyShell);
3584
3585 /// Get cancellation region for the current cancellation point.
3586 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
3587
3588 static bool classof(const Stmt *T) {
3589 return T->getStmtClass() == OMPCancellationPointDirectiveClass;
3590 }
3591};
3592
3593/// This represents '#pragma omp cancel' directive.
3594///
3595/// \code
3596/// #pragma omp cancel for
3597/// \endcode
3598///
3599/// In this example a cancel is created for innermost 'for' region.
3601 friend class ASTStmtReader;
3603 OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
3604 /// Build directive with the given start and end location.
3605 ///
3606 /// \param StartLoc Starting location of the directive kind.
3607 /// \param EndLoc Ending location of the directive.
3608 ///
3610 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3611 StartLoc, EndLoc) {}
3612
3613 /// Build an empty directive.
3614 ///
3615 explicit OMPCancelDirective()
3616 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3618
3619 /// Set cancel region for current cancellation point.
3620 /// \param CR Cancellation region.
3621 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
3622
3623public:
3624 /// Creates directive.
3625 ///
3626 /// \param C AST context.
3627 /// \param StartLoc Starting location of the directive kind.
3628 /// \param EndLoc Ending Location of the directive.
3629 /// \param Clauses List of clauses.
3630 ///
3631 static OMPCancelDirective *
3632 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3633 ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
3634
3635 /// Creates an empty directive.
3636 ///
3637 /// \param C AST context.
3638 /// \param NumClauses Number of clauses.
3639 ///
3640 static OMPCancelDirective *CreateEmpty(const ASTContext &C,
3641 unsigned NumClauses, EmptyShell);
3642
3643 /// Get cancellation region for the current cancellation point.
3644 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
3645
3646 static bool classof(const Stmt *T) {
3647 return T->getStmtClass() == OMPCancelDirectiveClass;
3648 }
3649};
3650
3651/// This represents '#pragma omp taskloop' directive.
3652///
3653/// \code
3654/// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
3655/// \endcode
3656/// In this example directive '#pragma omp taskloop' has clauses 'private'
3657/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
3658/// 'num_tasks' with expression 'num'.
3659///
3661 friend class ASTStmtReader;
3663 /// true if the construct has inner cancel directive.
3664 bool HasCancel = false;
3665
3666 /// Build directive with the given start and end location.
3667 ///
3668 /// \param StartLoc Starting location of the directive kind.
3669 /// \param EndLoc Ending location of the directive.
3670 /// \param CollapsedNum Number of collapsed nested loops.
3671 ///
3673 unsigned CollapsedNum)
3674 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3675 StartLoc, EndLoc, CollapsedNum) {}
3676
3677 /// Build an empty directive.
3678 ///
3679 /// \param CollapsedNum Number of collapsed nested loops.
3680 ///
3681 explicit OMPTaskLoopDirective(unsigned CollapsedNum)
3682 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3683 SourceLocation(), SourceLocation(), CollapsedNum) {}
3684
3685 /// Set cancel state.
3686 void setHasCancel(bool Has) { HasCancel = Has; }
3687
3688public:
3689 /// Creates directive with a list of \a Clauses.
3690 ///
3691 /// \param C AST context.
3692 /// \param StartLoc Starting location of the directive kind.
3693 /// \param EndLoc Ending Location of the directive.
3694 /// \param CollapsedNum Number of collapsed loops.
3695 /// \param Clauses List of clauses.
3696 /// \param AssociatedStmt Statement, associated with the directive.
3697 /// \param Exprs Helper expressions for CodeGen.
3698 /// \param HasCancel true if this directive has inner cancel directive.
3699 ///
3700 static OMPTaskLoopDirective *
3701 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3702 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3703 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3704
3705 /// Creates an empty directive with the place
3706 /// for \a NumClauses clauses.
3707 ///
3708 /// \param C AST context.
3709 /// \param CollapsedNum Number of collapsed nested loops.
3710 /// \param NumClauses Number of clauses.
3711 ///
3712 static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
3713 unsigned NumClauses,
3714 unsigned CollapsedNum, EmptyShell);
3715
3716 /// Return true if current directive has inner cancel directive.
3717 bool hasCancel() const { return HasCancel; }
3718
3719 static bool classof(const Stmt *T) {
3720 return T->getStmtClass() == OMPTaskLoopDirectiveClass;
3721 }
3722};
3723
3724/// This represents '#pragma omp taskloop simd' directive.
3725///
3726/// \code
3727/// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
3728/// \endcode
3729/// In this example directive '#pragma omp taskloop simd' has clauses 'private'
3730/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
3731/// 'num_tasks' with expression 'num'.
3732///
3734 friend class ASTStmtReader;
3736 /// Build directive with the given start and end location.
3737 ///
3738 /// \param StartLoc Starting location of the directive kind.
3739 /// \param EndLoc Ending location of the directive.
3740 /// \param CollapsedNum Number of collapsed nested loops.
3741 ///
3743 unsigned CollapsedNum)
3744 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3745 llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc,
3746 CollapsedNum) {}
3747
3748 /// Build an empty directive.
3749 ///
3750 /// \param CollapsedNum Number of collapsed nested loops.
3751 ///
3752 explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum)
3753 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3754 llvm::omp::OMPD_taskloop_simd, SourceLocation(),
3755 SourceLocation(), CollapsedNum) {}
3756
3757public:
3758 /// Creates directive with a list of \a Clauses.
3759 ///
3760 /// \param C AST context.
3761 /// \param StartLoc Starting location of the directive kind.
3762 /// \param EndLoc Ending Location of the directive.
3763 /// \param CollapsedNum Number of collapsed loops.
3764 /// \param Clauses List of clauses.
3765 /// \param AssociatedStmt Statement, associated with the directive.
3766 /// \param Exprs Helper expressions for CodeGen.
3767 ///
3768 static OMPTaskLoopSimdDirective *
3769 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3770 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3771 Stmt *AssociatedStmt, const HelperExprs &Exprs);
3772
3773 /// Creates an empty directive with the place
3774 /// for \a NumClauses clauses.
3775 ///
3776 /// \param C AST context.
3777 /// \param CollapsedNum Number of collapsed nested loops.
3778 /// \param NumClauses Number of clauses.
3779 ///
3780 static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
3781 unsigned NumClauses,
3782 unsigned CollapsedNum,
3783 EmptyShell);
3784
3785 static bool classof(const Stmt *T) {
3786 return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
3787 }
3788};
3789
3790/// This represents '#pragma omp master taskloop' directive.
3791///
3792/// \code
3793/// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num)
3794/// \endcode
3795/// In this example directive '#pragma omp master taskloop' has clauses
3796/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3797/// and 'num_tasks' with expression 'num'.
3798///
3800 friend class ASTStmtReader;
3802 /// true if the construct has inner cancel directive.
3803 bool HasCancel = false;
3804
3805 /// Build directive with the given start and end location.
3806 ///
3807 /// \param StartLoc Starting location of the directive kind.
3808 /// \param EndLoc Ending location of the directive.
3809 /// \param CollapsedNum Number of collapsed nested loops.
3810 ///
3812 unsigned CollapsedNum)
3813 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3814 llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc,
3815 CollapsedNum) {}
3816
3817 /// Build an empty directive.
3818 ///
3819 /// \param CollapsedNum Number of collapsed nested loops.
3820 ///
3821 explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum)
3822 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3823 llvm::omp::OMPD_master_taskloop, SourceLocation(),
3824 SourceLocation(), CollapsedNum) {}
3825
3826 /// Set cancel state.
3827 void setHasCancel(bool Has) { HasCancel = Has; }
3828
3829public:
3830 /// Creates directive with a list of \a Clauses.
3831 ///
3832 /// \param C AST context.
3833 /// \param StartLoc Starting location of the directive kind.
3834 /// \param EndLoc Ending Location of the directive.
3835 /// \param CollapsedNum Number of collapsed loops.
3836 /// \param Clauses List of clauses.
3837 /// \param AssociatedStmt Statement, associated with the directive.
3838 /// \param Exprs Helper expressions for CodeGen.
3839 /// \param HasCancel true if this directive has inner cancel directive.
3840 ///
3841 static OMPMasterTaskLoopDirective *
3842 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3843 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3844 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3845
3846 /// Creates an empty directive with the place
3847 /// for \a NumClauses clauses.
3848 ///
3849 /// \param C AST context.
3850 /// \param CollapsedNum Number of collapsed nested loops.
3851 /// \param NumClauses Number of clauses.
3852 ///
3853 static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
3854 unsigned NumClauses,
3855 unsigned CollapsedNum,
3856 EmptyShell);
3857
3858 /// Return true if current directive has inner cancel directive.
3859 bool hasCancel() const { return HasCancel; }
3860
3861 static bool classof(const Stmt *T) {
3862 return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass;
3863 }
3864};
3865
3866/// This represents '#pragma omp masked taskloop' directive.
3867///
3868/// \code
3869/// #pragma omp masked taskloop private(a,b) grainsize(val) num_tasks(num)
3870/// \endcode
3871/// In this example directive '#pragma omp masked taskloop' has clauses
3872/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3873/// and 'num_tasks' with expression 'num'.
3874///
3876 friend class ASTStmtReader;
3878 /// true if the construct has inner cancel directive.
3879 bool HasCancel = false;
3880
3881 /// Build directive with the given start and end location.
3882 ///
3883 /// \param StartLoc Starting location of the directive kind.
3884 /// \param EndLoc Ending location of the directive.
3885 /// \param CollapsedNum Number of collapsed nested loops.
3886 ///
3888 unsigned CollapsedNum)
3889 : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
3890 llvm::omp::OMPD_masked_taskloop, StartLoc, EndLoc,
3891 CollapsedNum) {}
3892
3893 /// Build an empty directive.
3894 ///
3895 /// \param CollapsedNum Number of collapsed nested loops.
3896 ///
3897 explicit OMPMaskedTaskLoopDirective(unsigned CollapsedNum)
3898 : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
3899 llvm::omp::OMPD_masked_taskloop, SourceLocation(),
3900 SourceLocation(), CollapsedNum) {}
3901
3902 /// Set cancel state.
3903 void setHasCancel(bool Has) { HasCancel = Has; }
3904
3905public:
3906 /// Creates directive with a list of \a Clauses.
3907 ///
3908 /// \param C AST context.
3909 /// \param StartLoc Starting location of the directive kind.
3910 /// \param EndLoc Ending Location of the directive.
3911 /// \param CollapsedNum Number of collapsed loops.
3912 /// \param Clauses List of clauses.
3913 /// \param AssociatedStmt Statement, associated with the directive.
3914 /// \param Exprs Helper expressions for CodeGen.
3915 /// \param HasCancel true if this directive has inner cancel directive.
3916 ///
3917 static OMPMaskedTaskLoopDirective *
3918 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3919 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3920 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3921
3922 /// Creates an empty directive with the place
3923 /// for \a NumClauses clauses.
3924 ///
3925 /// \param C AST context.
3926 /// \param CollapsedNum Number of collapsed nested loops.
3927 /// \param NumClauses Number of clauses.
3928 ///
3929 static OMPMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
3930 unsigned NumClauses,
3931 unsigned CollapsedNum,
3932 EmptyShell);
3933
3934 /// Return true if current directive has inner cancel directive.
3935 bool hasCancel() const { return HasCancel; }
3936
3937 static bool classof(const Stmt *T) {
3938 return T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass;
3939 }
3940};
3941
3942/// This represents '#pragma omp master taskloop simd' directive.
3943///
3944/// \code
3945/// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num)
3946/// \endcode
3947/// In this example directive '#pragma omp master taskloop simd' has clauses
3948/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3949/// and 'num_tasks' with expression 'num'.
3950///
3952 friend class ASTStmtReader;
3954 /// Build directive with the given start and end location.
3955 ///
3956 /// \param StartLoc Starting location of the directive kind.
3957 /// \param EndLoc Ending location of the directive.
3958 /// \param CollapsedNum Number of collapsed nested loops.
3959 ///
3961 unsigned CollapsedNum)
3962 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
3963 llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc,
3964 CollapsedNum) {}
3965
3966 /// Build an empty directive.
3967 ///
3968 /// \param CollapsedNum Number of collapsed nested loops.
3969 ///
3970 explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum)
3971 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
3972 llvm::omp::OMPD_master_taskloop_simd, SourceLocation(),
3973 SourceLocation(), CollapsedNum) {}
3974
3975public:
3976 /// Creates directive with a list of \p Clauses.
3977 ///
3978 /// \param C AST context.
3979 /// \param StartLoc Starting location of the directive kind.
3980 /// \param EndLoc Ending Location of the directive.
3981 /// \param CollapsedNum Number of collapsed loops.
3982 /// \param Clauses List of clauses.
3983 /// \param AssociatedStmt Statement, associated with the directive.
3984 /// \param Exprs Helper expressions for CodeGen.
3985 ///
3986 static OMPMasterTaskLoopSimdDirective *
3987 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3988 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3989 Stmt *AssociatedStmt, const HelperExprs &Exprs);
3990
3991 /// Creates an empty directive with the place for \p NumClauses clauses.
3992 ///
3993 /// \param C AST context.
3994 /// \param CollapsedNum Number of collapsed nested loops.
3995 /// \param NumClauses Number of clauses.
3996 ///
3997 static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
3998 unsigned NumClauses,
3999 unsigned CollapsedNum,
4000 EmptyShell);
4001
4002 static bool classof(const Stmt *T) {
4003 return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass;
4004 }
4005};
4006
4007/// This represents '#pragma omp masked taskloop simd' directive.
4008///
4009/// \code
4010/// #pragma omp masked taskloop simd private(a,b) grainsize(val) num_tasks(num)
4011/// \endcode
4012/// In this example directive '#pragma omp masked taskloop simd' has clauses
4013/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4014/// and 'num_tasks' with expression 'num'.
4015///
4017 friend class ASTStmtReader;
4019 /// Build directive with the given start and end location.
4020 ///
4021 /// \param StartLoc Starting location of the directive kind.
4022 /// \param EndLoc Ending location of the directive.
4023 /// \param CollapsedNum Number of collapsed nested loops.
4024 ///
4026 unsigned CollapsedNum)
4027 : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
4028 llvm::omp::OMPD_masked_taskloop_simd, StartLoc, EndLoc,
4029 CollapsedNum) {}
4030
4031 /// Build an empty directive.
4032 ///
4033 /// \param CollapsedNum Number of collapsed nested loops.
4034 ///
4035 explicit OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
4036 : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
4037 llvm::omp::OMPD_masked_taskloop_simd, SourceLocation(),
4038 SourceLocation(), CollapsedNum) {}
4039
4040public:
4041 /// Creates directive with a list of \p Clauses.
4042 ///
4043 /// \param C AST context.
4044 /// \param StartLoc Starting location of the directive kind.
4045 /// \param EndLoc Ending Location of the directive.
4046 /// \param CollapsedNum Number of collapsed loops.
4047 /// \param Clauses List of clauses.
4048 /// \param AssociatedStmt Statement, associated with the directive.
4049 /// \param Exprs Helper expressions for CodeGen.
4050 ///
4051 static OMPMaskedTaskLoopSimdDirective *
4052 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4053 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4054 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4055
4056 /// Creates an empty directive with the place for \p NumClauses clauses.
4057 ///
4058 /// \param C AST context.
4059 /// \param CollapsedNum Number of collapsed nested loops.
4060 /// \param NumClauses Number of clauses.
4061 ///
4062 static OMPMaskedTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
4063 unsigned NumClauses,
4064 unsigned CollapsedNum,
4065 EmptyShell);
4066
4067 static bool classof(const Stmt *T) {
4068 return T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass;
4069 }
4070};
4071
4072/// This represents '#pragma omp parallel master taskloop' directive.
4073///
4074/// \code
4075/// #pragma omp parallel master taskloop private(a,b) grainsize(val)
4076/// num_tasks(num)
4077/// \endcode
4078/// In this example directive '#pragma omp parallel master taskloop' has clauses
4079/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4080/// and 'num_tasks' with expression 'num'.
4081///
4083 friend class ASTStmtReader;
4085 /// true if the construct has inner cancel directive.
4086 bool HasCancel = false;
4087
4088 /// Build directive with the given start and end location.
4089 ///
4090 /// \param StartLoc Starting location of the directive kind.
4091 /// \param EndLoc Ending location of the directive.
4092 /// \param CollapsedNum Number of collapsed nested loops.
4093 ///
4095 SourceLocation EndLoc,
4096 unsigned CollapsedNum)
4097 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
4098 llvm::omp::OMPD_parallel_master_taskloop, StartLoc,
4099 EndLoc, CollapsedNum) {}
4100
4101 /// Build an empty directive.
4102 ///
4103 /// \param CollapsedNum Number of collapsed nested loops.
4104 ///
4105 explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum)
4106 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
4107 llvm::omp::OMPD_parallel_master_taskloop,
4108 SourceLocation(), SourceLocation(), CollapsedNum) {}
4109
4110 /// Set cancel state.
4111 void setHasCancel(bool Has) { HasCancel = Has; }
4112
4113public:
4114 /// Creates directive with a list of \a Clauses.
4115 ///
4116 /// \param C AST context.
4117 /// \param StartLoc Starting location of the directive kind.
4118 /// \param EndLoc Ending Location of the directive.
4119 /// \param CollapsedNum Number of collapsed loops.
4120 /// \param Clauses List of clauses.
4121 /// \param AssociatedStmt Statement, associated with the directive.
4122 /// \param Exprs Helper expressions for CodeGen.
4123 /// \param HasCancel true if this directive has inner cancel directive.
4124 ///
4125 static OMPParallelMasterTaskLoopDirective *
4126 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4127 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4128 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
4129
4130 /// Creates an empty directive with the place
4131 /// for \a NumClauses clauses.
4132 ///
4133 /// \param C AST context.
4134 /// \param CollapsedNum Number of collapsed nested loops.
4135 /// \param NumClauses Number of clauses.
4136 ///
4137 static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
4138 unsigned NumClauses,
4139 unsigned CollapsedNum,
4140 EmptyShell);
4141
4142 /// Return true if current directive has inner cancel directive.
4143 bool hasCancel() const { return HasCancel; }
4144
4145 static bool classof(const Stmt *T) {
4146 return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass;
4147 }
4148};
4149
4150/// This represents '#pragma omp parallel masked taskloop' directive.
4151///
4152/// \code
4153/// #pragma omp parallel masked taskloop private(a,b) grainsize(val)
4154/// num_tasks(num)
4155/// \endcode
4156/// In this example directive '#pragma omp parallel masked taskloop' has clauses
4157/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4158/// and 'num_tasks' with expression 'num'.
4159///
4161 friend class ASTStmtReader;
4163 /// true if the construct has inner cancel directive.
4164 bool HasCancel = false;
4165
4166 /// Build directive with the given start and end location.
4167 ///
4168 /// \param StartLoc Starting location of the directive kind.
4169 /// \param EndLoc Ending location of the directive.
4170 /// \param CollapsedNum Number of collapsed nested loops.
4171 ///
4173 SourceLocation EndLoc,
4174 unsigned CollapsedNum)
4175 : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
4176 llvm::omp::OMPD_parallel_masked_taskloop, StartLoc,
4177 EndLoc, CollapsedNum) {}
4178
4179 /// Build an empty directive.
4180 ///
4181 /// \param CollapsedNum Number of collapsed nested loops.
4182 ///
4183 explicit OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum)
4184 : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
4185 llvm::omp::OMPD_parallel_masked_taskloop,
4186 SourceLocation(), SourceLocation(), CollapsedNum) {}
4187
4188 /// Set cancel state.
4189 void setHasCancel(bool Has) { HasCancel = Has; }
4190
4191public:
4192 /// Creates directive with a list of \a Clauses.
4193 ///
4194 /// \param C AST context.
4195 /// \param StartLoc Starting location of the directive kind.
4196 /// \param EndLoc Ending Location of the directive.
4197 /// \param CollapsedNum Number of collapsed loops.
4198 /// \param Clauses List of clauses.
4199 /// \param AssociatedStmt Statement, associated with the directive.
4200 /// \param Exprs Helper expressions for CodeGen.
4201 /// \param HasCancel true if this directive has inner cancel directive.
4202 ///
4203 static OMPParallelMaskedTaskLoopDirective *
4204 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4205 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4206 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
4207
4208 /// Creates an empty directive with the place
4209 /// for \a NumClauses clauses.
4210 ///
4211 /// \param C AST context.
4212 /// \param CollapsedNum Number of collapsed nested loops.
4213 /// \param NumClauses Number of clauses.
4214 ///
4215 static OMPParallelMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
4216 unsigned NumClauses,
4217 unsigned CollapsedNum,
4218 EmptyShell);
4219
4220 /// Return true if current directive has inner cancel directive.
4221 bool hasCancel() const { return HasCancel; }
4222
4223 static bool classof(const Stmt *T) {
4224 return T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass;
4225 }
4226};
4227
4228/// This represents '#pragma omp parallel master taskloop simd' directive.
4229///
4230/// \code
4231/// #pragma omp parallel master taskloop simd private(a,b) grainsize(val)
4232/// num_tasks(num)
4233/// \endcode
4234/// In this example directive '#pragma omp parallel master taskloop simd' has
4235/// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
4236/// expression 'val' and 'num_tasks' with expression 'num'.
4237///
4239 friend class ASTStmtReader;
4241 /// Build directive with the given start and end location.
4242 ///
4243 /// \param StartLoc Starting location of the directive kind.
4244 /// \param EndLoc Ending location of the directive.
4245 /// \param CollapsedNum Number of collapsed nested loops.
4246 ///
4248 SourceLocation EndLoc,
4249 unsigned CollapsedNum)
4250 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
4251 llvm::omp::OMPD_parallel_master_taskloop_simd,
4252 StartLoc, EndLoc, CollapsedNum) {}
4253
4254 /// Build an empty directive.
4255 ///
4256 /// \param CollapsedNum Number of collapsed nested loops.
4257 ///
4258 explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum)
4259 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
4260 llvm::omp::OMPD_parallel_master_taskloop_simd,
4261 SourceLocation(), SourceLocation(), CollapsedNum) {}
4262
4263public:
4264 /// Creates directive with a list of \p Clauses.
4265 ///
4266 /// \param C AST context.
4267 /// \param StartLoc Starting location of the directive kind.
4268 /// \param EndLoc Ending Location of the directive.
4269 /// \param CollapsedNum Number of collapsed loops.
4270 /// \param Clauses List of clauses.
4271 /// \param AssociatedStmt Statement, associated with the directive.
4272 /// \param Exprs Helper expressions for CodeGen.
4273 ///
4274 static OMPParallelMasterTaskLoopSimdDirective *
4275 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4276 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4277 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4278
4279 /// Creates an empty directive with the place
4280 /// for \a NumClauses clauses.
4281 ///
4282 /// \param C AST context.
4283 /// \param CollapsedNum Number of collapsed nested loops.
4284 /// \param NumClauses Number of clauses.
4285 ///
4286 static OMPParallelMasterTaskLoopSimdDirective *
4287 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4288 EmptyShell);
4289
4290 static bool classof(const Stmt *T) {
4291 return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass;
4292 }
4293};
4294
4295/// This represents '#pragma omp parallel masked taskloop simd' directive.
4296///
4297/// \code
4298/// #pragma omp parallel masked taskloop simd private(a,b) grainsize(val)
4299/// num_tasks(num)
4300/// \endcode
4301/// In this example directive '#pragma omp parallel masked taskloop simd' has
4302/// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
4303/// expression 'val' and 'num_tasks' with expression 'num'.
4304///
4306 friend class ASTStmtReader;
4308 /// Build directive with the given start and end location.
4309 ///
4310 /// \param StartLoc Starting location of the directive kind.
4311 /// \param EndLoc Ending location of the directive.
4312 /// \param CollapsedNum Number of collapsed nested loops.
4313 ///
4315 SourceLocation EndLoc,
4316 unsigned CollapsedNum)
4317 : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
4318 llvm::omp::OMPD_parallel_masked_taskloop_simd,
4319 StartLoc, EndLoc, CollapsedNum) {}
4320
4321 /// Build an empty directive.
4322 ///
4323 /// \param CollapsedNum Number of collapsed nested loops.
4324 ///
4325 explicit OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
4326 : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
4327 llvm::omp::OMPD_parallel_masked_taskloop_simd,
4328 SourceLocation(), SourceLocation(), CollapsedNum) {}
4329
4330public:
4331 /// Creates directive with a list of \p Clauses.
4332 ///
4333 /// \param C AST context.
4334 /// \param StartLoc Starting location of the directive kind.
4335 /// \param EndLoc Ending Location of the directive.
4336 /// \param CollapsedNum Number of collapsed loops.
4337 /// \param Clauses List of clauses.
4338 /// \param AssociatedStmt Statement, associated with the directive.
4339 /// \param Exprs Helper expressions for CodeGen.
4340 ///
4341 static OMPParallelMaskedTaskLoopSimdDirective *
4342 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4343 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4344 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4345
4346 /// Creates an empty directive with the place
4347 /// for \a NumClauses clauses.
4348 ///
4349 /// \param C AST context.
4350 /// \param CollapsedNum Number of collapsed nested loops.
4351 /// \param NumClauses Number of clauses.
4352 ///
4353 static OMPParallelMaskedTaskLoopSimdDirective *
4354 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4355 EmptyShell);
4356
4357 static bool classof(const Stmt *T) {
4358 return T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass;
4359 }
4360};
4361
4362/// This represents '#pragma omp distribute' directive.
4363///
4364/// \code
4365/// #pragma omp distribute private(a,b)
4366/// \endcode
4367/// In this example directive '#pragma omp distribute' has clauses 'private'
4368/// with the variables 'a' and 'b'
4369///
4371 friend class ASTStmtReader;
4373
4374 /// Build directive with the given start and end location.
4375 ///
4376 /// \param StartLoc Starting location of the directive kind.
4377 /// \param EndLoc Ending location of the directive.
4378 /// \param CollapsedNum Number of collapsed nested loops.
4379 ///
4381 unsigned CollapsedNum)
4382 : OMPLoopDirective(OMPDistributeDirectiveClass,
4383 llvm::omp::OMPD_distribute, StartLoc, EndLoc,
4384 CollapsedNum) {}
4385
4386 /// Build an empty directive.
4387 ///
4388 /// \param CollapsedNum Number of collapsed nested loops.
4389 ///
4390 explicit OMPDistributeDirective(unsigned CollapsedNum)
4391 : OMPLoopDirective(OMPDistributeDirectiveClass,
4392 llvm::omp::OMPD_distribute, SourceLocation(),
4393 SourceLocation(), CollapsedNum) {}
4394
4395public:
4396 /// Creates directive with a list of \a Clauses.
4397 ///
4398 /// \param C AST context.
4399 /// \param StartLoc Starting location of the directive kind.
4400 /// \param EndLoc Ending Location of the directive.
4401 /// \param CollapsedNum Number of collapsed loops.
4402 /// \param Clauses List of clauses.
4403 /// \param AssociatedStmt Statement, associated with the directive.
4404 /// \param Exprs Helper expressions for CodeGen.
4405 ///
4406 static OMPDistributeDirective *
4407 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4408 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4409 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4410
4411 /// Creates an empty directive with the place
4412 /// for \a NumClauses clauses.
4413 ///
4414 /// \param C AST context.
4415 /// \param CollapsedNum Number of collapsed nested loops.
4416 /// \param NumClauses Number of clauses.
4417 ///
4418 static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
4419 unsigned NumClauses,
4420 unsigned CollapsedNum, EmptyShell);
4421
4422 static bool classof(const Stmt *T) {
4423 return T->getStmtClass() == OMPDistributeDirectiveClass;
4424 }
4425};
4426
4427/// This represents '#pragma omp target update' directive.
4428///
4429/// \code
4430/// #pragma omp target update to(a) from(b) device(1)
4431/// \endcode
4432/// In this example directive '#pragma omp target update' has clause 'to' with
4433/// argument 'a', clause 'from' with argument 'b' and clause 'device' with
4434/// argument '1'.
4435///
4437 friend class ASTStmtReader;
4439 /// Build directive with the given start and end location.
4440 ///
4441 /// \param StartLoc Starting location of the directive kind.
4442 /// \param EndLoc Ending Location of the directive.
4443 ///
4445 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
4446 llvm::omp::OMPD_target_update, StartLoc,
4447 EndLoc) {}
4448
4449 /// Build an empty directive.
4450 ///
4451 explicit OMPTargetUpdateDirective()
4452 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
4453 llvm::omp::OMPD_target_update, SourceLocation(),
4454 SourceLocation()) {}
4455
4456public:
4457 /// Creates directive with a list of \a Clauses.
4458 ///
4459 /// \param C AST context.
4460 /// \param StartLoc Starting location of the directive kind.
4461 /// \param EndLoc Ending Location of the directive.
4462 /// \param Clauses List of clauses.
4463 /// \param AssociatedStmt Statement, associated with the directive.
4464 ///
4465 static OMPTargetUpdateDirective *
4466 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4467 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
4468
4469 /// Creates an empty directive with the place for \a NumClauses
4470 /// clauses.
4471 ///
4472 /// \param C AST context.
4473 /// \param NumClauses The number of clauses.
4474 ///
4475 static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C,
4476 unsigned NumClauses, EmptyShell);
4477
4478 static bool classof(const Stmt *T) {
4479 return T->getStmtClass() == OMPTargetUpdateDirectiveClass;
4480 }
4481};
4482
4483/// This represents '#pragma omp distribute parallel for' composite
4484/// directive.
4485///
4486/// \code
4487/// #pragma omp distribute parallel for private(a,b)
4488/// \endcode
4489/// In this example directive '#pragma omp distribute parallel for' has clause
4490/// 'private' with the variables 'a' and 'b'
4491///
4493 friend class ASTStmtReader;
4495 /// true if the construct has inner cancel directive.
4496 bool HasCancel = false;
4497
4498 /// Build directive with the given start and end location.
4499 ///
4500 /// \param StartLoc Starting location of the directive kind.
4501 /// \param EndLoc Ending location of the directive.
4502 /// \param CollapsedNum Number of collapsed nested loops.
4503 ///
4505 SourceLocation EndLoc,
4506 unsigned CollapsedNum)
4507 : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4508 llvm::omp::OMPD_distribute_parallel_for, StartLoc,
4509 EndLoc, CollapsedNum) {}
4510
4511 /// Build an empty directive.
4512 ///
4513 /// \param CollapsedNum Number of collapsed nested loops.
4514 ///
4515 explicit OMPDistributeParallelForDirective(unsigned CollapsedNum)
4516 : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4517 llvm::omp::OMPD_distribute_parallel_for,
4518 SourceLocation(), SourceLocation(), CollapsedNum) {}
4519
4520 /// Sets special task reduction descriptor.
4521 void setTaskReductionRefExpr(Expr *E) {
4523 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E;
4524 }
4525
4526 /// Set cancel state.
4527 void setHasCancel(bool Has) { HasCancel = Has; }
4528
4529public:
4530 /// Creates directive with a list of \a Clauses.
4531 ///
4532 /// \param C AST context.
4533 /// \param StartLoc Starting location of the directive kind.
4534 /// \param EndLoc Ending Location of the directive.
4535 /// \param CollapsedNum Number of collapsed loops.
4536 /// \param Clauses List of clauses.
4537 /// \param AssociatedStmt Statement, associated with the directive.
4538 /// \param Exprs Helper expressions for CodeGen.
4539 /// \param TaskRedRef Task reduction special reference expression to handle
4540 /// taskgroup descriptor.
4541 /// \param HasCancel true if this directive has inner cancel directive.
4542 ///
4543 static OMPDistributeParallelForDirective *
4544 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4545 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4546 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
4547 bool HasCancel);
4548
4549 /// Creates an empty directive with the place
4550 /// for \a NumClauses clauses.
4551 ///
4552 /// \param C AST context.
4553 /// \param CollapsedNum Number of collapsed nested loops.
4554 /// \param NumClauses Number of clauses.
4555 ///
4556 static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C,
4557 unsigned NumClauses,
4558 unsigned CollapsedNum,
4559 EmptyShell);
4560
4561 /// Returns special task reduction reference expression.
4563 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
4564 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]);
4565 }
4567 return const_cast<OMPDistributeParallelForDirective *>(this)
4569 }
4570
4571 /// Return true if current directive has inner cancel directive.
4572 bool hasCancel() const { return HasCancel; }
4573
4574 static bool classof(const Stmt *T) {
4575 return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
4576 }
4577};
4578
4579/// This represents '#pragma omp distribute parallel for simd' composite
4580/// directive.
4581///
4582/// \code
4583/// #pragma omp distribute parallel for simd private(x)
4584/// \endcode
4585/// In this example directive '#pragma omp distribute parallel for simd' has
4586/// clause 'private' with the variables 'x'
4587///
4589 friend class ASTStmtReader;
4591
4592 /// Build directive with the given start and end location.
4593 ///
4594 /// \param StartLoc Starting location of the directive kind.
4595 /// \param EndLoc Ending location of the directive.
4596 /// \param CollapsedNum Number of collapsed nested loops.
4597 ///
4599 SourceLocation EndLoc,
4600 unsigned CollapsedNum)
4601 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4602 llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc,
4603 EndLoc, CollapsedNum) {}
4604
4605 /// Build an empty directive.
4606 ///
4607 /// \param CollapsedNum Number of collapsed nested loops.
4608 ///
4609 explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum)
4610 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4611 llvm::omp::OMPD_distribute_parallel_for_simd,
4612 SourceLocation(), SourceLocation(), CollapsedNum) {}
4613
4614public:
4615 /// Creates directive with a list of \a Clauses.
4616 ///
4617 /// \param C AST context.
4618 /// \param StartLoc Starting location of the directive kind.
4619 /// \param EndLoc Ending Location of the directive.
4620 /// \param CollapsedNum Number of collapsed loops.
4621 /// \param Clauses List of clauses.
4622 /// \param AssociatedStmt Statement, associated with the directive.
4623 /// \param Exprs Helper expressions for CodeGen.
4624 ///
4625 static OMPDistributeParallelForSimdDirective *Create(
4626 const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4627 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4628 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4629
4630 /// Creates an empty directive with the place for \a NumClauses clauses.
4631 ///
4632 /// \param C AST context.
4633 /// \param CollapsedNum Number of collapsed nested loops.
4634 /// \param NumClauses Number of clauses.
4635 ///
4636 static OMPDistributeParallelForSimdDirective *CreateEmpty(
4637 const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4638 EmptyShell);
4639
4640 static bool classof(const Stmt *T) {
4641 return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass;
4642 }
4643};
4644
4645/// This represents '#pragma omp distribute simd' composite directive.
4646///
4647/// \code
4648/// #pragma omp distribute simd private(x)
4649/// \endcode
4650/// In this example directive '#pragma omp distribute simd' has clause
4651/// 'private' with the variables 'x'
4652///
4654 friend class ASTStmtReader;
4656
4657 /// Build directive with the given start and end location.
4658 ///
4659 /// \param StartLoc Starting location of the directive kind.
4660 /// \param EndLoc Ending location of the directive.
4661 /// \param CollapsedNum Number of collapsed nested loops.
4662 ///
4664 unsigned CollapsedNum)
4665 : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4666 llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc,
4667 CollapsedNum) {}
4668
4669 /// Build an empty directive.
4670 ///
4671 /// \param CollapsedNum Number of collapsed nested loops.
4672 ///
4673 explicit OMPDistributeSimdDirective(unsigned CollapsedNum)
4674 : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4675 llvm::omp::OMPD_distribute_simd, SourceLocation(),
4676 SourceLocation(), CollapsedNum) {}
4677
4678public:
4679 /// Creates directive with a list of \a Clauses.
4680 ///
4681 /// \param C AST context.
4682 /// \param StartLoc Starting location of the directive kind.
4683 /// \param EndLoc Ending Location of the directive.
4684 /// \param CollapsedNum Number of collapsed loops.
4685 /// \param Clauses List of clauses.
4686 /// \param AssociatedStmt Statement, associated with the directive.
4687 /// \param Exprs Helper expressions for CodeGen.
4688 ///
4689 static OMPDistributeSimdDirective *
4690 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4691 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4692 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4693
4694 /// Creates an empty directive with the place for \a NumClauses clauses.
4695 ///
4696 /// \param C AST context.
4697 /// \param CollapsedNum Number of collapsed nested loops.
4698 /// \param NumClauses Number of clauses.
4699 ///
4700 static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C,
4701 unsigned NumClauses,
4702 unsigned CollapsedNum,
4703 EmptyShell);
4704
4705 static bool classof(const Stmt *T) {
4706 return T->getStmtClass() == OMPDistributeSimdDirectiveClass;
4707 }
4708};
4709
4710/// This represents '#pragma omp target parallel for simd' directive.
4711///
4712/// \code
4713/// #pragma omp target parallel for simd private(a) map(b) safelen(c)
4714/// \endcode
4715/// In this example directive '#pragma omp target parallel for simd' has clauses
4716/// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen'
4717/// with the variable 'c'.
4718///
4720 friend class ASTStmtReader;
4722
4723 /// Build directive with the given start and end location.
4724 ///
4725 /// \param StartLoc Starting location of the directive kind.
4726 /// \param EndLoc Ending location of the directive.
4727 /// \param CollapsedNum Number of collapsed nested loops.
4728 ///
4730 SourceLocation EndLoc,
4731 unsigned CollapsedNum)
4732 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4733 llvm::omp::OMPD_target_parallel_for_simd, StartLoc,
4734 EndLoc, CollapsedNum) {}
4735
4736 /// Build an empty directive.
4737 ///
4738 /// \param CollapsedNum Number of collapsed nested loops.
4739 ///
4740 explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum)
4741 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4742 llvm::omp::OMPD_target_parallel_for_simd,
4743 SourceLocation(), SourceLocation(), CollapsedNum) {}
4744
4745public:
4746 /// Creates directive with a list of \a Clauses.
4747 ///
4748 /// \param C AST context.
4749 /// \param StartLoc Starting location of the directive kind.
4750 /// \param EndLoc Ending Location of the directive.
4751 /// \param CollapsedNum Number of collapsed loops.
4752 /// \param Clauses List of clauses.
4753 /// \param AssociatedStmt Statement, associated with the directive.
4754 /// \param Exprs Helper expressions for CodeGen.
4755 ///
4756 static OMPTargetParallelForSimdDirective *
4757 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4758 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4759 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4760
4761 /// Creates an empty directive with the place for \a NumClauses clauses.
4762 ///
4763 /// \param C AST context.
4764 /// \param CollapsedNum Number of collapsed nested loops.
4765 /// \param NumClauses Number of clauses.
4766 ///
4767 static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C,
4768 unsigned NumClauses,
4769 unsigned CollapsedNum,
4770 EmptyShell);
4771
4772 static bool classof(const Stmt *T) {
4773 return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
4774 }
4775};
4776
4777/// This represents '#pragma omp target simd' directive.
4778///
4779/// \code
4780/// #pragma omp target simd private(a) map(b) safelen(c)
4781/// \endcode
4782/// In this example directive '#pragma omp target simd' has clauses 'private'
4783/// with the variable 'a', 'map' with the variable 'b' and 'safelen' with
4784/// the variable 'c'.
4785///
4787 friend class ASTStmtReader;
4789
4790 /// Build directive with the given start and end location.
4791 ///
4792 /// \param StartLoc Starting location of the directive kind.
4793 /// \param EndLoc Ending location of the directive.
4794 /// \param CollapsedNum Number of collapsed nested loops.
4795 ///
4797 unsigned CollapsedNum)
4798 : OMPLoopDirective(OMPTargetSimdDirectiveClass,
4799 llvm::omp::OMPD_target_simd, StartLoc, EndLoc,
4800 CollapsedNum) {}
4801
4802 /// Build an empty directive.
4803 ///
4804 /// \param CollapsedNum Number of collapsed nested loops.
4805 ///
4806 explicit OMPTargetSimdDirective(unsigned CollapsedNum)
4807 : OMPLoopDirective(OMPTargetSimdDirectiveClass,
4808 llvm::omp::OMPD_target_simd, SourceLocation(),
4809 SourceLocation(), CollapsedNum) {}
4810
4811public:
4812 /// Creates directive with a list of \a Clauses.
4813 ///
4814 /// \param C AST context.
4815 /// \param StartLoc Starting location of the directive kind.
4816 /// \param EndLoc Ending Location of the directive.
4817 /// \param CollapsedNum Number of collapsed loops.
4818 /// \param Clauses List of clauses.
4819 /// \param AssociatedStmt Statement, associated with the directive.
4820 /// \param Exprs Helper expressions for CodeGen.
4821 ///
4822 static OMPTargetSimdDirective *
4823 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4824 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4825 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4826
4827 /// Creates an empty directive with the place for \a NumClauses clauses.
4828 ///
4829 /// \param C AST context.
4830 /// \param CollapsedNum Number of collapsed nested loops.
4831 /// \param NumClauses Number of clauses.
4832 ///
4833 static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C,
4834 unsigned NumClauses,
4835 unsigned CollapsedNum,
4836 EmptyShell);
4837
4838 static bool classof(const Stmt *T) {
4839 return T->getStmtClass() == OMPTargetSimdDirectiveClass;
4840 }
4841};
4842
4843/// This represents '#pragma omp teams distribute' directive.
4844///
4845/// \code
4846/// #pragma omp teams distribute private(a,b)
4847/// \endcode
4848/// In this example directive '#pragma omp teams distribute' has clauses
4849/// 'private' with the variables 'a' and 'b'
4850///
4852 friend class ASTStmtReader;
4854
4855 /// Build directive with the given start and end location.
4856 ///
4857 /// \param StartLoc Starting location of the directive kind.
4858 /// \param EndLoc Ending location of the directive.
4859 /// \param CollapsedNum Number of collapsed nested loops.
4860 ///
4862 unsigned CollapsedNum)
4863 : OMPLoopDirective(OMPTeamsDistributeDirectiveClass,
4864 llvm::omp::OMPD_teams_distribute, StartLoc, EndLoc,
4865 CollapsedNum) {}
4866
4867 /// Build an empty directive.
4868 ///
4869 /// \param CollapsedNum Number of collapsed nested loops.
4870 ///
4871 explicit OMPTeamsDistributeDirective(unsigned CollapsedNum)
4872 : OMPLoopDirective(OMPTeamsDistributeDirectiveClass,
4873 llvm::omp::OMPD_teams_distribute, SourceLocati