clang 18.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
284 /// Was this directive mapped from an another directive?
285 /// e.g. 1) omp loop bind(parallel) is mapped to OMPD_for
286 /// 2) omp loop bind(teams) is mapped to OMPD_distribute
287 /// 3) omp loop bind(thread) is mapped to OMPD_simd
288 /// It was necessary to note it down in the Directive because of
289 /// clang::TreeTransform::TransformOMPExecutableDirective() pass in
290 /// the frontend.
291 OpenMPDirectiveKind PrevMappedDirective = llvm::omp::OMPD_unknown;
292
293protected:
294 /// Data, associated with the directive.
295 OMPChildren *Data = nullptr;
296
297 /// Build instance of directive of class \a K.
298 ///
299 /// \param SC Statement class.
300 /// \param K Kind of OpenMP directive.
301 /// \param StartLoc Starting location of the directive (directive keyword).
302 /// \param EndLoc Ending location of the directive.
303 ///
305 SourceLocation StartLoc, SourceLocation EndLoc)
306 : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
307 EndLoc(std::move(EndLoc)) {}
308
309 template <typename T, typename... Params>
311 Stmt *AssociatedStmt, unsigned NumChildren,
312 Params &&... P) {
313 void *Mem =
314 C.Allocate(sizeof(T) + OMPChildren::size(Clauses.size(), AssociatedStmt,
315 NumChildren),
316 alignof(T));
317
318 auto *Data = OMPChildren::Create(reinterpret_cast<T *>(Mem) + 1, Clauses,
319 AssociatedStmt, NumChildren);
320 auto *Inst = new (Mem) T(std::forward<Params>(P)...);
321 Inst->Data = Data;
322 return Inst;
323 }
324
325 template <typename T, typename... Params>
326 static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses,
327 bool HasAssociatedStmt, unsigned NumChildren,
328 Params &&... P) {
329 void *Mem =
330 C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt,
331 NumChildren),
332 alignof(T));
333 auto *Data =
334 OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses,
335 HasAssociatedStmt, NumChildren);
336 auto *Inst = new (Mem) T(std::forward<Params>(P)...);
337 Inst->Data = Data;
338 return Inst;
339 }
340
341 template <typename T>
342 static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses,
343 bool HasAssociatedStmt = false,
344 unsigned NumChildren = 0) {
345 void *Mem =
346 C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt,
347 NumChildren),
348 alignof(T));
349 auto *Data =
350 OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses,
351 HasAssociatedStmt, NumChildren);
352 auto *Inst = new (Mem) T;
353 Inst->Data = Data;
354 return Inst;
355 }
356
358 PrevMappedDirective = MappedDirective;
359 }
360
361public:
362 /// Iterates over expressions/statements used in the construct.
364 : public llvm::iterator_adaptor_base<
365 used_clauses_child_iterator, ArrayRef<OMPClause *>::iterator,
366 std::forward_iterator_tag, Stmt *, ptrdiff_t, Stmt *, Stmt *> {
368 OMPClause::child_iterator ChildI, ChildEnd;
369
370 void MoveToNext() {
371 if (ChildI != ChildEnd)
372 return;
373 while (this->I != End) {
374 ++this->I;
375 if (this->I != End) {
376 ChildI = (*this->I)->used_children().begin();
377 ChildEnd = (*this->I)->used_children().end();
378 if (ChildI != ChildEnd)
379 return;
380 }
381 }
382 }
383
384 public:
386 : used_clauses_child_iterator::iterator_adaptor_base(Clauses.begin()),
387 End(Clauses.end()) {
388 if (this->I != End) {
389 ChildI = (*this->I)->used_children().begin();
390 ChildEnd = (*this->I)->used_children().end();
391 MoveToNext();
392 }
393 }
394 Stmt *operator*() const { return *ChildI; }
395 Stmt *operator->() const { return **this; }
396
398 ++ChildI;
399 if (ChildI != ChildEnd)
400 return *this;
401 if (this->I != End) {
402 ++this->I;
403 if (this->I != End) {
404 ChildI = (*this->I)->used_children().begin();
405 ChildEnd = (*this->I)->used_children().end();
406 }
407 }
408 MoveToNext();
409 return *this;
410 }
411 };
412
413 static llvm::iterator_range<used_clauses_child_iterator>
415 return {
417 used_clauses_child_iterator(llvm::ArrayRef(Clauses.end(), (size_t)0))};
418 }
419
420 /// Iterates over a filtered subrange of clauses applied to a
421 /// directive.
422 ///
423 /// This iterator visits only clauses of type SpecificClause.
424 template <typename SpecificClause>
426 : public llvm::iterator_adaptor_base<
427 specific_clause_iterator<SpecificClause>,
428 ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag,
429 const SpecificClause *, ptrdiff_t, const SpecificClause *,
430 const SpecificClause *> {
432
433 void SkipToNextClause() {
434 while (this->I != End && !isa<SpecificClause>(*this->I))
435 ++this->I;
436 }
437
438 public:
440 : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()),
441 End(Clauses.end()) {
442 SkipToNextClause();
443 }
444
445 const SpecificClause *operator*() const {
446 return cast<SpecificClause>(*this->I);
447 }
448 const SpecificClause *operator->() const { return **this; }
449
451 ++this->I;
452 SkipToNextClause();
453 return *this;
454 }
455 };
456
457 template <typename SpecificClause>
458 static llvm::iterator_range<specific_clause_iterator<SpecificClause>>
462 llvm::ArrayRef(Clauses.end(), (size_t)0))};
463 }
464
465 template <typename SpecificClause>
466 llvm::iterator_range<specific_clause_iterator<SpecificClause>>
468 return getClausesOfKind<SpecificClause>(clauses());
469 }
470
471 /// Gets a single clause of the specified kind associated with the
472 /// current directive iff there is only one clause of this kind (and assertion
473 /// is fired if there is more than one clause is associated with the
474 /// directive). Returns nullptr if no clause of this kind is associated with
475 /// the directive.
476 template <typename SpecificClause>
477 static const SpecificClause *getSingleClause(ArrayRef<OMPClause *> Clauses) {
478 auto ClausesOfKind = getClausesOfKind<SpecificClause>(Clauses);
479
480 if (ClausesOfKind.begin() != ClausesOfKind.end()) {
481 assert(std::next(ClausesOfKind.begin()) == ClausesOfKind.end() &&
482 "There are at least 2 clauses of the specified kind");
483 return *ClausesOfKind.begin();
484 }
485 return nullptr;
486 }
487
488 template <typename SpecificClause>
489 const SpecificClause *getSingleClause() const {
490 return getSingleClause<SpecificClause>(clauses());
491 }
492
493 /// Returns true if the current directive has one or more clauses of a
494 /// specific kind.
495 template <typename SpecificClause>
496 bool hasClausesOfKind() const {
497 auto Clauses = getClausesOfKind<SpecificClause>();
498 return Clauses.begin() != Clauses.end();
499 }
500
501 /// Returns starting location of directive kind.
502 SourceLocation getBeginLoc() const { return StartLoc; }
503 /// Returns ending location of directive.
504 SourceLocation getEndLoc() const { return EndLoc; }
505
506 /// Set starting location of directive kind.
507 ///
508 /// \param Loc New starting location of directive.
509 ///
510 void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
511 /// Set ending location of directive.
512 ///
513 /// \param Loc New ending location of directive.
514 ///
515 void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
516
517 /// Get number of clauses.
518 unsigned getNumClauses() const {
519 if (!Data)
520 return 0;
521 return Data->getNumClauses();
522 }
523
524 /// Returns specified clause.
525 ///
526 /// \param I Number of clause.
527 ///
528 OMPClause *getClause(unsigned I) const { return clauses()[I]; }
529
530 /// Returns true if directive has associated statement.
531 bool hasAssociatedStmt() const { return Data && Data->hasAssociatedStmt(); }
532
533 /// Returns statement associated with the directive.
534 const Stmt *getAssociatedStmt() const {
535 return const_cast<OMPExecutableDirective *>(this)->getAssociatedStmt();
536 }
538 assert(hasAssociatedStmt() &&
539 "Expected directive with the associated statement.");
540 return Data->getAssociatedStmt();
541 }
542
543 /// Returns the captured statement associated with the
544 /// component region within the (combined) directive.
545 ///
546 /// \param RegionKind Component region kind.
548 assert(hasAssociatedStmt() &&
549 "Expected directive with the associated statement.");
551 getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
552 return Data->getCapturedStmt(RegionKind, CaptureRegions);
553 }
554
555 /// Get innermost captured statement for the construct.
557 assert(hasAssociatedStmt() &&
558 "Expected directive with the associated statement.");
560 getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
561 return Data->getInnermostCapturedStmt(CaptureRegions);
562 }
563
565 return const_cast<OMPExecutableDirective *>(this)
567 }
568
569 OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
570
571 static bool classof(const Stmt *S) {
572 return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
573 S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
574 }
575
577 if (!Data)
580 }
581
583 return const_cast<OMPExecutableDirective *>(this)->children();
584 }
585
587 if (!Data)
588 return std::nullopt;
589 return Data->getClauses();
590 }
591
592 /// Returns whether or not this is a Standalone directive.
593 ///
594 /// Stand-alone directives are executable directives
595 /// that have no associated user code.
596 bool isStandaloneDirective() const;
597
598 /// Returns the AST node representing OpenMP structured-block of this
599 /// OpenMP executable directive,
600 /// Prerequisite: Executable Directive must not be Standalone directive.
601 const Stmt *getStructuredBlock() const {
602 return const_cast<OMPExecutableDirective *>(this)->getStructuredBlock();
603 }
605
606 const Stmt *getRawStmt() const {
607 return const_cast<OMPExecutableDirective *>(this)->getRawStmt();
608 }
610 assert(hasAssociatedStmt() &&
611 "Expected directive with the associated statement.");
612 return Data->getRawStmt();
613 }
614
615 OpenMPDirectiveKind getMappedDirective() const { return PrevMappedDirective; }
616};
617
618/// This represents '#pragma omp parallel' directive.
619///
620/// \code
621/// #pragma omp parallel private(a,b) reduction(+: c,d)
622/// \endcode
623/// In this example directive '#pragma omp parallel' has clauses 'private'
624/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
625/// variables 'c' and 'd'.
626///
628 friend class ASTStmtReader;
630 /// true if the construct has inner cancel directive.
631 bool HasCancel = false;
632
633 /// Build directive with the given start and end location.
634 ///
635 /// \param StartLoc Starting location of the directive (directive keyword).
636 /// \param EndLoc Ending Location of the directive.
637 ///
639 : OMPExecutableDirective(OMPParallelDirectiveClass,
640 llvm::omp::OMPD_parallel, StartLoc, EndLoc) {}
641
642 /// Build an empty directive.
643 ///
644 explicit OMPParallelDirective()
645 : OMPExecutableDirective(OMPParallelDirectiveClass,
646 llvm::omp::OMPD_parallel, SourceLocation(),
647 SourceLocation()) {}
648
649 /// Sets special task reduction descriptor.
650 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
651
652 /// Set cancel state.
653 void setHasCancel(bool Has) { HasCancel = Has; }
654
655public:
656 /// Creates directive with a list of \a Clauses.
657 ///
658 /// \param C AST context.
659 /// \param StartLoc Starting location of the directive kind.
660 /// \param EndLoc Ending Location of the directive.
661 /// \param Clauses List of clauses.
662 /// \param AssociatedStmt Statement associated with the directive.
663 /// \param TaskRedRef Task reduction special reference expression to handle
664 /// taskgroup descriptor.
665 /// \param HasCancel true if this directive has inner cancel directive.
666 ///
667 static OMPParallelDirective *
668 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
669 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
670 bool HasCancel);
671
672 /// Creates an empty directive with the place for \a N clauses.
673 ///
674 /// \param C AST context.
675 /// \param NumClauses Number of clauses.
676 ///
677 static OMPParallelDirective *CreateEmpty(const ASTContext &C,
678 unsigned NumClauses, EmptyShell);
679
680 /// Returns special task reduction reference expression.
682 return cast_or_null<Expr>(Data->getChildren()[0]);
683 }
685 return const_cast<OMPParallelDirective *>(this)->getTaskReductionRefExpr();
686 }
687
688 /// Return true if current directive has inner cancel directive.
689 bool hasCancel() const { return HasCancel; }
690
691 static bool classof(const Stmt *T) {
692 return T->getStmtClass() == OMPParallelDirectiveClass;
693 }
694};
695
696/// The base class for all loop-based directives, including loop transformation
697/// directives.
699 friend class ASTStmtReader;
700
701protected:
702 /// Number of collapsed loops as specified by 'collapse' clause.
703 unsigned NumAssociatedLoops = 0;
704
705 /// Build instance of loop directive of class \a Kind.
706 ///
707 /// \param SC Statement class.
708 /// \param Kind Kind of OpenMP directive.
709 /// \param StartLoc Starting location of the directive (directive keyword).
710 /// \param EndLoc Ending location of the directive.
711 /// \param NumAssociatedLoops Number of loops associated with the construct.
712 ///
714 SourceLocation StartLoc, SourceLocation EndLoc,
715 unsigned NumAssociatedLoops)
716 : OMPExecutableDirective(SC, Kind, StartLoc, EndLoc),
718
719public:
720 /// The expressions built to support OpenMP loops in combined/composite
721 /// pragmas (e.g. pragma omp distribute parallel for)
723 /// DistributeLowerBound - used when composing 'omp distribute' with
724 /// 'omp for' in a same construct.
726 /// DistributeUpperBound - used when composing 'omp distribute' with
727 /// 'omp for' in a same construct.
729 /// DistributeEnsureUpperBound - used when composing 'omp distribute'
730 /// with 'omp for' in a same construct, EUB depends on DistUB
732 /// Distribute loop iteration variable init used when composing 'omp
733 /// distribute'
734 /// with 'omp for' in a same construct
736 /// Distribute Loop condition used when composing 'omp distribute'
737 /// with 'omp for' in a same construct
739 /// Update of LowerBound for statically scheduled omp loops for
740 /// outer loop in combined constructs (e.g. 'distribute parallel for')
742 /// Update of UpperBound for statically scheduled omp loops for
743 /// outer loop in combined constructs (e.g. 'distribute parallel for')
745 /// Distribute Loop condition used when composing 'omp distribute'
746 /// with 'omp for' in a same construct when schedule is chunked.
748 /// 'omp parallel for' loop condition used when composed with
749 /// 'omp distribute' in the same construct and when schedule is
750 /// chunked and the chunk size is 1.
752 };
753
754 /// The expressions built for the OpenMP loop CodeGen for the
755 /// whole collapsed loop nest.
756 struct HelperExprs {
757 /// Loop iteration variable.
759 /// Loop last iteration number.
761 /// Loop number of iterations.
763 /// Calculation of last iteration.
765 /// Loop pre-condition.
767 /// Loop condition.
769 /// Loop iteration variable init.
771 /// Loop increment.
773 /// IsLastIteration - local flag variable passed to runtime.
775 /// LowerBound - local variable passed to runtime.
777 /// UpperBound - local variable passed to runtime.
779 /// Stride - local variable passed to runtime.
781 /// EnsureUpperBound -- expression UB = min(UB, NumIterations).
783 /// Update of LowerBound for statically scheduled 'omp for' loops.
785 /// Update of UpperBound for statically scheduled 'omp for' loops.
787 /// PreviousLowerBound - local variable passed to runtime in the
788 /// enclosing schedule or null if that does not apply.
790 /// PreviousUpperBound - local variable passed to runtime in the
791 /// enclosing schedule or null if that does not apply.
793 /// DistInc - increment expression for distribute loop when found
794 /// combined with a further loop level (e.g. in 'distribute parallel for')
795 /// expression IV = IV + ST
797 /// PrevEUB - expression similar to EUB but to be used when loop
798 /// scheduling uses PrevLB and PrevUB (e.g. in 'distribute parallel for'
799 /// when ensuring that the UB is either the calculated UB by the runtime or
800 /// the end of the assigned distribute chunk)
801 /// expression UB = min (UB, PrevUB)
803 /// Counters Loop counters.
805 /// PrivateCounters Loop counters.
807 /// Expressions for loop counters inits for CodeGen.
809 /// Expressions for loop counters update for CodeGen.
811 /// Final loop counter values for GodeGen.
813 /// List of counters required for the generation of the non-rectangular
814 /// loops.
816 /// List of initializers required for the generation of the non-rectangular
817 /// loops.
819 /// List of final conditions required for the generation of the
820 /// non-rectangular loops.
822 /// Init statement for all captured expressions.
824
825 /// Expressions used when combining OpenMP loop pragmas
827
828 /// Check if all the expressions are built (does not check the
829 /// worksharing ones).
830 bool builtAll() {
831 return IterationVarRef != nullptr && LastIteration != nullptr &&
832 NumIterations != nullptr && PreCond != nullptr &&
833 Cond != nullptr && Init != nullptr && Inc != nullptr;
834 }
835
836 /// Initialize all the fields to null.
837 /// \param Size Number of elements in the
838 /// counters/finals/updates/dependent_counters/dependent_inits/finals_conditions
839 /// arrays.
840 void clear(unsigned Size) {
841 IterationVarRef = nullptr;
842 LastIteration = nullptr;
843 CalcLastIteration = nullptr;
844 PreCond = nullptr;
845 Cond = nullptr;
846 Init = nullptr;
847 Inc = nullptr;
848 IL = nullptr;
849 LB = nullptr;
850 UB = nullptr;
851 ST = nullptr;
852 EUB = nullptr;
853 NLB = nullptr;
854 NUB = nullptr;
855 NumIterations = nullptr;
856 PrevLB = nullptr;
857 PrevUB = nullptr;
858 DistInc = nullptr;
859 PrevEUB = nullptr;
860 Counters.resize(Size);
861 PrivateCounters.resize(Size);
862 Inits.resize(Size);
863 Updates.resize(Size);
864 Finals.resize(Size);
865 DependentCounters.resize(Size);
866 DependentInits.resize(Size);
867 FinalsConditions.resize(Size);
868 for (unsigned I = 0; I < Size; ++I) {
869 Counters[I] = nullptr;
870 PrivateCounters[I] = nullptr;
871 Inits[I] = nullptr;
872 Updates[I] = nullptr;
873 Finals[I] = nullptr;
874 DependentCounters[I] = nullptr;
875 DependentInits[I] = nullptr;
876 FinalsConditions[I] = nullptr;
877 }
878 PreInits = nullptr;
879 DistCombinedFields.LB = nullptr;
880 DistCombinedFields.UB = nullptr;
881 DistCombinedFields.EUB = nullptr;
882 DistCombinedFields.Init = nullptr;
883 DistCombinedFields.Cond = nullptr;
884 DistCombinedFields.NLB = nullptr;
885 DistCombinedFields.NUB = nullptr;
888 }
889 };
890
891 /// Get number of collapsed loops.
892 unsigned getLoopsNumber() const { return NumAssociatedLoops; }
893
894 /// Try to find the next loop sub-statement in the specified statement \p
895 /// CurStmt.
896 /// \param TryImperfectlyNestedLoops true, if we need to try to look for the
897 /// imperfectly nested loop.
898 static Stmt *tryToFindNextInnerLoop(Stmt *CurStmt,
899 bool TryImperfectlyNestedLoops);
900 static const Stmt *tryToFindNextInnerLoop(const Stmt *CurStmt,
901 bool TryImperfectlyNestedLoops) {
902 return tryToFindNextInnerLoop(const_cast<Stmt *>(CurStmt),
903 TryImperfectlyNestedLoops);
904 }
905
906 /// Calls the specified callback function for all the loops in \p CurStmt,
907 /// from the outermost to the innermost.
908 static bool
909 doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
910 unsigned NumLoops,
911 llvm::function_ref<bool(unsigned, Stmt *)> Callback,
912 llvm::function_ref<void(OMPLoopTransformationDirective *)>
913 OnTransformationCallback);
914 static bool
915 doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
916 unsigned NumLoops,
917 llvm::function_ref<bool(unsigned, const Stmt *)> Callback,
918 llvm::function_ref<void(const OMPLoopTransformationDirective *)>
919 OnTransformationCallback) {
920 auto &&NewCallback = [Callback](unsigned Cnt, Stmt *CurStmt) {
921 return Callback(Cnt, CurStmt);
922 };
923 auto &&NewTransformCb =
924 [OnTransformationCallback](OMPLoopTransformationDirective *A) {
925 OnTransformationCallback(A);
926 };
927 return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
928 NumLoops, NewCallback, NewTransformCb);
929 }
930
931 /// Calls the specified callback function for all the loops in \p CurStmt,
932 /// from the outermost to the innermost.
933 static bool
934 doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
935 unsigned NumLoops,
936 llvm::function_ref<bool(unsigned, Stmt *)> Callback) {
937 auto &&TransformCb = [](OMPLoopTransformationDirective *) {};
938 return doForAllLoops(CurStmt, TryImperfectlyNestedLoops, NumLoops, Callback,
939 TransformCb);
940 }
941 static bool
942 doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
943 unsigned NumLoops,
944 llvm::function_ref<bool(unsigned, const Stmt *)> Callback) {
945 auto &&NewCallback = [Callback](unsigned Cnt, const Stmt *CurStmt) {
946 return Callback(Cnt, CurStmt);
947 };
948 return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
949 NumLoops, NewCallback);
950 }
951
952 /// Calls the specified callback function for all the loop bodies in \p
953 /// CurStmt, from the outermost loop to the innermost.
954 static void doForAllLoopsBodies(
955 Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops,
956 llvm::function_ref<void(unsigned, Stmt *, Stmt *)> Callback);
958 const Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops,
959 llvm::function_ref<void(unsigned, const Stmt *, const Stmt *)> Callback) {
960 auto &&NewCallback = [Callback](unsigned Cnt, Stmt *Loop, Stmt *Body) {
961 Callback(Cnt, Loop, Body);
962 };
963 doForAllLoopsBodies(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
964 NumLoops, NewCallback);
965 }
966
967 static bool classof(const Stmt *T) {
968 if (auto *D = dyn_cast<OMPExecutableDirective>(T))
969 return isOpenMPLoopDirective(D->getDirectiveKind());
970 return false;
971 }
972};
973
974/// The base class for all loop transformation directives.
976 friend class ASTStmtReader;
977
978 /// Number of loops generated by this loop transformation.
979 unsigned NumGeneratedLoops = 0;
980
981protected:
984 SourceLocation StartLoc,
985 SourceLocation EndLoc,
986 unsigned NumAssociatedLoops)
987 : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, NumAssociatedLoops) {}
988
989 /// Set the number of loops generated by this loop transformation.
990 void setNumGeneratedLoops(unsigned Num) { NumGeneratedLoops = Num; }
991
992public:
993 /// Return the number of associated (consumed) loops.
994 unsigned getNumAssociatedLoops() const { return getLoopsNumber(); }
995
996 /// Return the number of loops generated by this loop transformation.
997 unsigned getNumGeneratedLoops() const { return NumGeneratedLoops; }
998
999 /// Get the de-sugared statements after the loop transformation.
1000 ///
1001 /// Might be nullptr if either the directive generates no loops and is handled
1002 /// directly in CodeGen, or resolving a template-dependence context is
1003 /// required.
1004 Stmt *getTransformedStmt() const;
1005
1006 /// Return preinits statement.
1007 Stmt *getPreInits() const;
1008
1009 static bool classof(const Stmt *T) {
1010 return T->getStmtClass() == OMPTileDirectiveClass ||
1011 T->getStmtClass() == OMPUnrollDirectiveClass;
1012 }
1013};
1014
1015/// This is a common base class for loop directives ('omp simd', 'omp
1016/// for', 'omp for simd' etc.). It is responsible for the loop code generation.
1017///
1019 friend class ASTStmtReader;
1020
1021 /// Offsets to the stored exprs.
1022 /// This enumeration contains offsets to all the pointers to children
1023 /// expressions stored in OMPLoopDirective.
1024 /// The first 9 children are necessary for all the loop directives,
1025 /// the next 8 are specific to the worksharing ones, and the next 11 are
1026 /// used for combined constructs containing two pragmas associated to loops.
1027 /// After the fixed children, three arrays of length NumAssociatedLoops are
1028 /// allocated: loop counters, their updates and final values.
1029 /// PrevLowerBound and PrevUpperBound are used to communicate blocking
1030 /// information in composite constructs which require loop blocking
1031 /// DistInc is used to generate the increment expression for the distribute
1032 /// loop when combined with a further nested loop
1033 /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the
1034 /// for loop when combined with a previous distribute loop in the same pragma
1035 /// (e.g. 'distribute parallel for')
1036 ///
1037 enum {
1038 IterationVariableOffset = 0,
1039 LastIterationOffset = 1,
1040 CalcLastIterationOffset = 2,
1041 PreConditionOffset = 3,
1042 CondOffset = 4,
1043 InitOffset = 5,
1044 IncOffset = 6,
1045 PreInitsOffset = 7,
1046 // The '...End' enumerators do not correspond to child expressions - they
1047 // specify the offset to the end (and start of the following counters/
1048 // updates/finals/dependent_counters/dependent_inits/finals_conditions
1049 // arrays).
1050 DefaultEnd = 8,
1051 // The following 8 exprs are used by worksharing and distribute loops only.
1052 IsLastIterVariableOffset = 8,
1053 LowerBoundVariableOffset = 9,
1054 UpperBoundVariableOffset = 10,
1055 StrideVariableOffset = 11,
1056 EnsureUpperBoundOffset = 12,
1057 NextLowerBoundOffset = 13,
1058 NextUpperBoundOffset = 14,
1059 NumIterationsOffset = 15,
1060 // Offset to the end for worksharing loop directives.
1061 WorksharingEnd = 16,
1062 PrevLowerBoundVariableOffset = 16,
1063 PrevUpperBoundVariableOffset = 17,
1064 DistIncOffset = 18,
1065 PrevEnsureUpperBoundOffset = 19,
1066 CombinedLowerBoundVariableOffset = 20,
1067 CombinedUpperBoundVariableOffset = 21,
1068 CombinedEnsureUpperBoundOffset = 22,
1069 CombinedInitOffset = 23,
1070 CombinedConditionOffset = 24,
1071 CombinedNextLowerBoundOffset = 25,
1072 CombinedNextUpperBoundOffset = 26,
1073 CombinedDistConditionOffset = 27,
1074 CombinedParForInDistConditionOffset = 28,
1075 // Offset to the end (and start of the following
1076 // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions
1077 // arrays) for combined distribute loop directives.
1078 CombinedDistributeEnd = 29,
1079 };
1080
1081 /// Get the counters storage.
1082 MutableArrayRef<Expr *> getCounters() {
1083 auto **Storage = reinterpret_cast<Expr **>(
1085 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1086 }
1087
1088 /// Get the private counters storage.
1089 MutableArrayRef<Expr *> getPrivateCounters() {
1090 auto **Storage = reinterpret_cast<Expr **>(
1092 getLoopsNumber()]);
1093 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1094 }
1095
1096 /// Get the updates storage.
1097 MutableArrayRef<Expr *> getInits() {
1098 auto **Storage = reinterpret_cast<Expr **>(
1100 2 * getLoopsNumber()]);
1101 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1102 }
1103
1104 /// Get the updates storage.
1105 MutableArrayRef<Expr *> getUpdates() {
1106 auto **Storage = reinterpret_cast<Expr **>(
1108 3 * getLoopsNumber()]);
1109 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1110 }
1111
1112 /// Get the final counter updates storage.
1113 MutableArrayRef<Expr *> getFinals() {
1114 auto **Storage = reinterpret_cast<Expr **>(
1116 4 * getLoopsNumber()]);
1117 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1118 }
1119
1120 /// Get the dependent counters storage.
1121 MutableArrayRef<Expr *> getDependentCounters() {
1122 auto **Storage = reinterpret_cast<Expr **>(
1124 5 * getLoopsNumber()]);
1125 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1126 }
1127
1128 /// Get the dependent inits storage.
1129 MutableArrayRef<Expr *> getDependentInits() {
1130 auto **Storage = reinterpret_cast<Expr **>(
1132 6 * getLoopsNumber()]);
1133 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1134 }
1135
1136 /// Get the finals conditions storage.
1137 MutableArrayRef<Expr *> getFinalsConditions() {
1138 auto **Storage = reinterpret_cast<Expr **>(
1140 7 * getLoopsNumber()]);
1141 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1142 }
1143
1144protected:
1145 /// Build instance of loop directive of class \a Kind.
1146 ///
1147 /// \param SC Statement class.
1148 /// \param Kind Kind of OpenMP directive.
1149 /// \param StartLoc Starting location of the directive (directive keyword).
1150 /// \param EndLoc Ending location of the directive.
1151 /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
1152 ///
1154 SourceLocation StartLoc, SourceLocation EndLoc,
1155 unsigned CollapsedNum)
1156 : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, CollapsedNum) {}
1157
1158 /// Offset to the start of children expression arrays.
1159 static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
1161 return CombinedDistributeEnd;
1164 return WorksharingEnd;
1165 return DefaultEnd;
1166 }
1167
1168 /// Children number.
1169 static unsigned numLoopChildren(unsigned CollapsedNum,
1170 OpenMPDirectiveKind Kind) {
1171 return getArraysOffset(Kind) +
1172 8 * CollapsedNum; // Counters, PrivateCounters, Inits,
1173 // Updates, Finals, DependentCounters,
1174 // DependentInits, FinalsConditions.
1175 }
1176
1178 Data->getChildren()[IterationVariableOffset] = IV;
1179 }
1181 Data->getChildren()[LastIterationOffset] = LI;
1182 }
1184 Data->getChildren()[CalcLastIterationOffset] = CLI;
1185 }
1186 void setPreCond(Expr *PC) { Data->getChildren()[PreConditionOffset] = PC; }
1187 void setCond(Expr *Cond) { Data->getChildren()[CondOffset] = Cond; }
1188 void setInit(Expr *Init) { Data->getChildren()[InitOffset] = Init; }
1189 void setInc(Expr *Inc) { Data->getChildren()[IncOffset] = Inc; }
1190 void setPreInits(Stmt *PreInits) {
1191 Data->getChildren()[PreInitsOffset] = PreInits;
1192 }
1198 "expected worksharing loop directive");
1199 Data->getChildren()[IsLastIterVariableOffset] = IL;
1200 }
1206 "expected worksharing loop directive");
1207 Data->getChildren()[LowerBoundVariableOffset] = LB;
1208 }
1214 "expected worksharing loop directive");
1215 Data->getChildren()[UpperBoundVariableOffset] = UB;
1216 }
1222 "expected worksharing loop directive");
1223 Data->getChildren()[StrideVariableOffset] = ST;
1224 }
1230 "expected worksharing loop directive");
1231 Data->getChildren()[EnsureUpperBoundOffset] = EUB;
1232 }
1238 "expected worksharing loop directive");
1239 Data->getChildren()[NextLowerBoundOffset] = NLB;
1240 }
1246 "expected worksharing loop directive");
1247 Data->getChildren()[NextUpperBoundOffset] = NUB;
1248 }
1254 "expected worksharing loop directive");
1255 Data->getChildren()[NumIterationsOffset] = NI;
1256 }
1259 "expected loop bound sharing directive");
1260 Data->getChildren()[PrevLowerBoundVariableOffset] = PrevLB;
1261 }
1264 "expected loop bound sharing directive");
1265 Data->getChildren()[PrevUpperBoundVariableOffset] = PrevUB;
1266 }
1267 void setDistInc(Expr *DistInc) {
1269 "expected loop bound sharing directive");
1270 Data->getChildren()[DistIncOffset] = DistInc;
1271 }
1274 "expected loop bound sharing directive");
1275 Data->getChildren()[PrevEnsureUpperBoundOffset] = PrevEUB;
1276 }
1279 "expected loop bound sharing directive");
1280 Data->getChildren()[CombinedLowerBoundVariableOffset] = CombLB;
1281 }
1284 "expected loop bound sharing directive");
1285 Data->getChildren()[CombinedUpperBoundVariableOffset] = CombUB;
1286 }
1289 "expected loop bound sharing directive");
1290 Data->getChildren()[CombinedEnsureUpperBoundOffset] = CombEUB;
1291 }
1292 void setCombinedInit(Expr *CombInit) {
1294 "expected loop bound sharing directive");
1295 Data->getChildren()[CombinedInitOffset] = CombInit;
1296 }
1297 void setCombinedCond(Expr *CombCond) {
1299 "expected loop bound sharing directive");
1300 Data->getChildren()[CombinedConditionOffset] = CombCond;
1301 }
1304 "expected loop bound sharing directive");
1305 Data->getChildren()[CombinedNextLowerBoundOffset] = CombNLB;
1306 }
1309 "expected loop bound sharing directive");
1310 Data->getChildren()[CombinedNextUpperBoundOffset] = CombNUB;
1311 }
1312 void setCombinedDistCond(Expr *CombDistCond) {
1314 "expected loop bound distribute sharing directive");
1315 Data->getChildren()[CombinedDistConditionOffset] = CombDistCond;
1316 }
1317 void setCombinedParForInDistCond(Expr *CombParForInDistCond) {
1319 "expected loop bound distribute sharing directive");
1320 Data->getChildren()[CombinedParForInDistConditionOffset] =
1321 CombParForInDistCond;
1322 }
1325 void setInits(ArrayRef<Expr *> A);
1331
1332public:
1334 return cast<Expr>(Data->getChildren()[IterationVariableOffset]);
1335 }
1337 return cast<Expr>(Data->getChildren()[LastIterationOffset]);
1338 }
1340 return cast<Expr>(Data->getChildren()[CalcLastIterationOffset]);
1341 }
1342 Expr *getPreCond() const {
1343 return cast<Expr>(Data->getChildren()[PreConditionOffset]);
1344 }
1345 Expr *getCond() const { return cast<Expr>(Data->getChildren()[CondOffset]); }
1346 Expr *getInit() const { return cast<Expr>(Data->getChildren()[InitOffset]); }
1347 Expr *getInc() const { return cast<Expr>(Data->getChildren()[IncOffset]); }
1348 const Stmt *getPreInits() const {
1349 return Data->getChildren()[PreInitsOffset];
1350 }
1351 Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; }
1357 "expected worksharing loop directive");
1358 return cast<Expr>(Data->getChildren()[IsLastIterVariableOffset]);
1359 }
1365 "expected worksharing loop directive");
1366 return cast<Expr>(Data->getChildren()[LowerBoundVariableOffset]);
1367 }
1373 "expected worksharing loop directive");
1374 return cast<Expr>(Data->getChildren()[UpperBoundVariableOffset]);
1375 }
1381 "expected worksharing loop directive");
1382 return cast<Expr>(Data->getChildren()[StrideVariableOffset]);
1383 }
1389 "expected worksharing loop directive");
1390 return cast<Expr>(Data->getChildren()[EnsureUpperBoundOffset]);
1391 }
1397 "expected worksharing loop directive");
1398 return cast<Expr>(Data->getChildren()[NextLowerBoundOffset]);
1399 }
1405 "expected worksharing loop directive");
1406 return cast<Expr>(Data->getChildren()[NextUpperBoundOffset]);
1407 }
1413 "expected worksharing loop directive");
1414 return cast<Expr>(Data->getChildren()[NumIterationsOffset]);
1415 }
1418 "expected loop bound sharing directive");
1419 return cast<Expr>(Data->getChildren()[PrevLowerBoundVariableOffset]);
1420 }
1423 "expected loop bound sharing directive");
1424 return cast<Expr>(Data->getChildren()[PrevUpperBoundVariableOffset]);
1425 }
1426 Expr *getDistInc() const {
1428 "expected loop bound sharing directive");
1429 return cast<Expr>(Data->getChildren()[DistIncOffset]);
1430 }
1433 "expected loop bound sharing directive");
1434 return cast<Expr>(Data->getChildren()[PrevEnsureUpperBoundOffset]);
1435 }
1438 "expected loop bound sharing directive");
1439 return cast<Expr>(Data->getChildren()[CombinedLowerBoundVariableOffset]);
1440 }
1443 "expected loop bound sharing directive");
1444 return cast<Expr>(Data->getChildren()[CombinedUpperBoundVariableOffset]);
1445 }
1448 "expected loop bound sharing directive");
1449 return cast<Expr>(Data->getChildren()[CombinedEnsureUpperBoundOffset]);
1450 }
1453 "expected loop bound sharing directive");
1454 return cast<Expr>(Data->getChildren()[CombinedInitOffset]);
1455 }
1458 "expected loop bound sharing directive");
1459 return cast<Expr>(Data->getChildren()[CombinedConditionOffset]);
1460 }
1463 "expected loop bound sharing directive");
1464 return cast<Expr>(Data->getChildren()[CombinedNextLowerBoundOffset]);
1465 }
1468 "expected loop bound sharing directive");
1469 return cast<Expr>(Data->getChildren()[CombinedNextUpperBoundOffset]);
1470 }
1473 "expected loop bound distribute sharing directive");
1474 return cast<Expr>(Data->getChildren()[CombinedDistConditionOffset]);
1475 }
1478 "expected loop bound distribute sharing directive");
1479 return cast<Expr>(Data->getChildren()[CombinedParForInDistConditionOffset]);
1480 }
1481 Stmt *getBody();
1482 const Stmt *getBody() const {
1483 return const_cast<OMPLoopDirective *>(this)->getBody();
1484 }
1485
1486 ArrayRef<Expr *> counters() { return getCounters(); }
1487
1489 return const_cast<OMPLoopDirective *>(this)->getCounters();
1490 }
1491
1492 ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
1493
1495 return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
1496 }
1497
1498 ArrayRef<Expr *> inits() { return getInits(); }
1499
1501 return const_cast<OMPLoopDirective *>(this)->getInits();
1502 }
1503
1504 ArrayRef<Expr *> updates() { return getUpdates(); }
1505
1507 return const_cast<OMPLoopDirective *>(this)->getUpdates();
1508 }
1509
1510 ArrayRef<Expr *> finals() { return getFinals(); }
1511
1513 return const_cast<OMPLoopDirective *>(this)->getFinals();
1514 }
1515
1516 ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); }
1517
1519 return const_cast<OMPLoopDirective *>(this)->getDependentCounters();
1520 }
1521
1522 ArrayRef<Expr *> dependent_inits() { return getDependentInits(); }
1523
1525 return const_cast<OMPLoopDirective *>(this)->getDependentInits();
1526 }
1527
1528 ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); }
1529
1531 return const_cast<OMPLoopDirective *>(this)->getFinalsConditions();
1532 }
1533
1534 static bool classof(const Stmt *T) {
1535 return T->getStmtClass() == OMPSimdDirectiveClass ||
1536 T->getStmtClass() == OMPForDirectiveClass ||
1537 T->getStmtClass() == OMPForSimdDirectiveClass ||
1538 T->getStmtClass() == OMPParallelForDirectiveClass ||
1539 T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
1540 T->getStmtClass() == OMPTaskLoopDirectiveClass ||
1541 T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
1542 T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass ||
1543 T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass ||
1544 T->getStmtClass() == OMPMasterTaskLoopDirectiveClass ||
1545 T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass ||
1546 T->getStmtClass() == OMPGenericLoopDirectiveClass ||
1547 T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass ||
1548 T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass ||
1549 T->getStmtClass() == OMPParallelGenericLoopDirectiveClass ||
1550 T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass ||
1551 T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass ||
1552 T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass ||
1553 T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass ||
1554 T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass ||
1555 T->getStmtClass() == OMPDistributeDirectiveClass ||
1556 T->getStmtClass() == OMPTargetParallelForDirectiveClass ||
1557 T->getStmtClass() == OMPDistributeParallelForDirectiveClass ||
1558 T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass ||
1559 T->getStmtClass() == OMPDistributeSimdDirectiveClass ||
1560 T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass ||
1561 T->getStmtClass() == OMPTargetSimdDirectiveClass ||
1562 T->getStmtClass() == OMPTeamsDistributeDirectiveClass ||
1563 T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass ||
1564 T->getStmtClass() ==
1565 OMPTeamsDistributeParallelForSimdDirectiveClass ||
1566 T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass ||
1567 T->getStmtClass() ==
1568 OMPTargetTeamsDistributeParallelForDirectiveClass ||
1569 T->getStmtClass() ==
1570 OMPTargetTeamsDistributeParallelForSimdDirectiveClass ||
1571 T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass ||
1572 T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
1573 }
1574};
1575
1576/// This represents '#pragma omp simd' directive.
1577///
1578/// \code
1579/// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
1580/// \endcode
1581/// In this example directive '#pragma omp simd' has clauses 'private'
1582/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
1583/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
1584///
1586 friend class ASTStmtReader;
1588 /// Build directive with the given start and end location.
1589 ///
1590 /// \param StartLoc Starting location of the directive kind.
1591 /// \param EndLoc Ending location of the directive.
1592 /// \param CollapsedNum Number of collapsed nested loops.
1593 ///
1595 unsigned CollapsedNum)
1596 : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, StartLoc,
1597 EndLoc, CollapsedNum) {}
1598
1599 /// Build an empty directive.
1600 ///
1601 /// \param CollapsedNum Number of collapsed nested loops.
1602 ///
1603 explicit OMPSimdDirective(unsigned CollapsedNum)
1604 : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd,
1605 SourceLocation(), SourceLocation(), CollapsedNum) {}
1606
1607public:
1608 /// Creates directive with a list of \a Clauses.
1609 ///
1610 /// \param C AST context.
1611 /// \param StartLoc Starting location of the directive kind.
1612 /// \param EndLoc Ending Location of the directive.
1613 /// \param CollapsedNum Number of collapsed loops.
1614 /// \param Clauses List of clauses.
1615 /// \param AssociatedStmt Statement, associated with the directive.
1616 /// \param Exprs Helper expressions for CodeGen.
1617 ///
1618 static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1619 SourceLocation EndLoc, unsigned CollapsedNum,
1620 ArrayRef<OMPClause *> Clauses,
1621 Stmt *AssociatedStmt,
1622 const HelperExprs &Exprs,
1623 OpenMPDirectiveKind ParamPrevMappedDirective);
1624
1625 /// Creates an empty directive with the place
1626 /// for \a NumClauses clauses.
1627 ///
1628 /// \param C AST context.
1629 /// \param CollapsedNum Number of collapsed nested loops.
1630 /// \param NumClauses Number of clauses.
1631 ///
1632 static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1633 unsigned CollapsedNum, EmptyShell);
1634
1635 static bool classof(const Stmt *T) {
1636 return T->getStmtClass() == OMPSimdDirectiveClass;
1637 }
1638};
1639
1640/// This represents '#pragma omp for' directive.
1641///
1642/// \code
1643/// #pragma omp for private(a,b) reduction(+:c,d)
1644/// \endcode
1645/// In this example directive '#pragma omp for' has clauses 'private' with the
1646/// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
1647/// and 'd'.
1648///
1650 friend class ASTStmtReader;
1652 /// true if current directive has inner cancel directive.
1653 bool HasCancel = false;
1654
1655 /// Build directive with the given start and end location.
1656 ///
1657 /// \param StartLoc Starting location of the directive kind.
1658 /// \param EndLoc Ending location of the directive.
1659 /// \param CollapsedNum Number of collapsed nested loops.
1660 ///
1662 unsigned CollapsedNum)
1663 : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, StartLoc,
1664 EndLoc, CollapsedNum) {}
1665
1666 /// Build an empty directive.
1667 ///
1668 /// \param CollapsedNum Number of collapsed nested loops.
1669 ///
1670 explicit OMPForDirective(unsigned CollapsedNum)
1671 : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for,
1672 SourceLocation(), SourceLocation(), CollapsedNum) {}
1673
1674 /// Sets special task reduction descriptor.
1675 void setTaskReductionRefExpr(Expr *E) {
1676 Data->getChildren()[numLoopChildren(getLoopsNumber(),
1677 llvm::omp::OMPD_for)] = E;
1678 }
1679
1680 /// Set cancel state.
1681 void setHasCancel(bool Has) { HasCancel = Has; }
1682
1683public:
1684 /// Creates directive with a list of \a Clauses.
1685 ///
1686 /// \param C AST context.
1687 /// \param StartLoc Starting location of the directive kind.
1688 /// \param EndLoc Ending Location of the directive.
1689 /// \param CollapsedNum Number of collapsed loops.
1690 /// \param Clauses List of clauses.
1691 /// \param AssociatedStmt Statement, associated with the directive.
1692 /// \param Exprs Helper expressions for CodeGen.
1693 /// \param TaskRedRef Task reduction special reference expression to handle
1694 /// taskgroup descriptor.
1695 /// \param HasCancel true if current directive has inner cancel directive.
1696 ///
1697 static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1698 SourceLocation EndLoc, unsigned CollapsedNum,
1699 ArrayRef<OMPClause *> Clauses,
1700 Stmt *AssociatedStmt, const HelperExprs &Exprs,
1701 Expr *TaskRedRef, bool HasCancel,
1702 OpenMPDirectiveKind ParamPrevMappedDirective);
1703
1704 /// Creates an empty directive with the place
1705 /// for \a NumClauses clauses.
1706 ///
1707 /// \param C AST context.
1708 /// \param CollapsedNum Number of collapsed nested loops.
1709 /// \param NumClauses Number of clauses.
1710 ///
1711 static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1712 unsigned CollapsedNum, EmptyShell);
1713
1714 /// Returns special task reduction reference expression.
1716 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
1717 getLoopsNumber(), llvm::omp::OMPD_for)]);
1718 }
1720 return const_cast<OMPForDirective *>(this)->getTaskReductionRefExpr();
1721 }
1722
1723 /// Return true if current directive has inner cancel directive.
1724 bool hasCancel() const { return HasCancel; }
1725
1726 static bool classof(const Stmt *T) {
1727 return T->getStmtClass() == OMPForDirectiveClass;
1728 }
1729};
1730
1731/// This represents '#pragma omp for simd' directive.
1732///
1733/// \code
1734/// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
1735/// \endcode
1736/// In this example directive '#pragma omp for simd' has clauses 'private'
1737/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
1738/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
1739///
1741 friend class ASTStmtReader;
1743 /// Build directive with the given start and end location.
1744 ///
1745 /// \param StartLoc Starting location of the directive kind.
1746 /// \param EndLoc Ending location of the directive.
1747 /// \param CollapsedNum Number of collapsed nested loops.
1748 ///
1750 unsigned CollapsedNum)
1751 : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
1752 StartLoc, EndLoc, CollapsedNum) {}
1753
1754 /// Build an empty directive.
1755 ///
1756 /// \param CollapsedNum Number of collapsed nested loops.
1757 ///
1758 explicit OMPForSimdDirective(unsigned CollapsedNum)
1759 : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
1760 SourceLocation(), SourceLocation(), CollapsedNum) {}
1761
1762public:
1763 /// Creates directive with a list of \a Clauses.
1764 ///
1765 /// \param C AST context.
1766 /// \param StartLoc Starting location of the directive kind.
1767 /// \param EndLoc Ending Location of the directive.
1768 /// \param CollapsedNum Number of collapsed loops.
1769 /// \param Clauses List of clauses.
1770 /// \param AssociatedStmt Statement, associated with the directive.
1771 /// \param Exprs Helper expressions for CodeGen.
1772 ///
1773 static OMPForSimdDirective *
1774 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1775 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1776 Stmt *AssociatedStmt, const HelperExprs &Exprs);
1777
1778 /// Creates an empty directive with the place
1779 /// for \a NumClauses clauses.
1780 ///
1781 /// \param C AST context.
1782 /// \param CollapsedNum Number of collapsed nested loops.
1783 /// \param NumClauses Number of clauses.
1784 ///
1785 static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
1786 unsigned NumClauses,
1787 unsigned CollapsedNum, EmptyShell);
1788
1789 static bool classof(const Stmt *T) {
1790 return T->getStmtClass() == OMPForSimdDirectiveClass;
1791 }
1792};
1793
1794/// This represents '#pragma omp sections' directive.
1795///
1796/// \code
1797/// #pragma omp sections private(a,b) reduction(+:c,d)
1798/// \endcode
1799/// In this example directive '#pragma omp sections' has clauses 'private' with
1800/// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
1801/// 'c' and 'd'.
1802///
1804 friend class ASTStmtReader;
1806
1807 /// true if current directive has inner cancel directive.
1808 bool HasCancel = false;
1809
1810 /// Build directive with the given start and end location.
1811 ///
1812 /// \param StartLoc Starting location of the directive kind.
1813 /// \param EndLoc Ending location of the directive.
1814 ///
1816 : OMPExecutableDirective(OMPSectionsDirectiveClass,
1817 llvm::omp::OMPD_sections, StartLoc, EndLoc) {}
1818
1819 /// Build an empty directive.
1820 ///
1821 explicit OMPSectionsDirective()
1822 : OMPExecutableDirective(OMPSectionsDirectiveClass,
1823 llvm::omp::OMPD_sections, SourceLocation(),
1824 SourceLocation()) {}
1825
1826 /// Sets special task reduction descriptor.
1827 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
1828
1829 /// Set cancel state.
1830 void setHasCancel(bool Has) { HasCancel = Has; }
1831
1832public:
1833 /// Creates directive with a list of \a Clauses.
1834 ///
1835 /// \param C AST context.
1836 /// \param StartLoc Starting location of the directive kind.
1837 /// \param EndLoc Ending Location of the directive.
1838 /// \param Clauses List of clauses.
1839 /// \param AssociatedStmt Statement, associated with the directive.
1840 /// \param TaskRedRef Task reduction special reference expression to handle
1841 /// taskgroup descriptor.
1842 /// \param HasCancel true if current directive has inner directive.
1843 ///
1844 static OMPSectionsDirective *
1845 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1846 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
1847 bool HasCancel);
1848
1849 /// Creates an empty directive with the place for \a NumClauses
1850 /// clauses.
1851 ///
1852 /// \param C AST context.
1853 /// \param NumClauses Number of clauses.
1854 ///
1855 static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
1856 unsigned NumClauses, EmptyShell);
1857
1858 /// Returns special task reduction reference expression.
1860 return cast_or_null<Expr>(Data->getChildren()[0]);
1861 }
1863 return const_cast<OMPSectionsDirective *>(this)->getTaskReductionRefExpr();
1864 }
1865
1866 /// Return true if current directive has inner cancel directive.
1867 bool hasCancel() const { return HasCancel; }
1868
1869 static bool classof(const Stmt *T) {
1870 return T->getStmtClass() == OMPSectionsDirectiveClass;
1871 }
1872};
1873
1874/// This represents '#pragma omp section' directive.
1875///
1876/// \code
1877/// #pragma omp section
1878/// \endcode
1879///
1881 friend class ASTStmtReader;
1883
1884 /// true if current directive has inner cancel directive.
1885 bool HasCancel = false;
1886
1887 /// Build directive with the given start and end location.
1888 ///
1889 /// \param StartLoc Starting location of the directive kind.
1890 /// \param EndLoc Ending location of the directive.
1891 ///
1893 : OMPExecutableDirective(OMPSectionDirectiveClass,
1894 llvm::omp::OMPD_section, StartLoc, EndLoc) {}
1895
1896 /// Build an empty directive.
1897 ///
1898 explicit OMPSectionDirective()
1899 : OMPExecutableDirective(OMPSectionDirectiveClass,
1900 llvm::omp::OMPD_section, SourceLocation(),
1901 SourceLocation()) {}
1902
1903public:
1904 /// Creates directive.
1905 ///
1906 /// \param C AST context.
1907 /// \param StartLoc Starting location of the directive kind.
1908 /// \param EndLoc Ending Location of the directive.
1909 /// \param AssociatedStmt Statement, associated with the directive.
1910 /// \param HasCancel true if current directive has inner directive.
1911 ///
1912 static OMPSectionDirective *Create(const ASTContext &C,
1913 SourceLocation StartLoc,
1914 SourceLocation EndLoc,
1915 Stmt *AssociatedStmt, bool HasCancel);
1916
1917 /// Creates an empty directive.
1918 ///
1919 /// \param C AST context.
1920 ///
1921 static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1922
1923 /// Set cancel state.
1924 void setHasCancel(bool Has) { HasCancel = Has; }
1925
1926 /// Return true if current directive has inner cancel directive.
1927 bool hasCancel() const { return HasCancel; }
1928
1929 static bool classof(const Stmt *T) {
1930 return T->getStmtClass() == OMPSectionDirectiveClass;
1931 }
1932};
1933
1934/// This represents '#pragma omp scope' directive.
1935/// \code
1936/// #pragma omp scope private(a,b) nowait
1937/// \endcode
1938/// In this example directive '#pragma omp scope' has clauses 'private' with
1939/// the variables 'a' and 'b' and nowait.
1940///
1942 friend class ASTStmtReader;
1944
1945 /// Build directive with the given start and end location.
1946 ///
1947 /// \param StartLoc Starting location of the directive kind.
1948 /// \param EndLoc Ending location of the directive.
1949 ///
1951 : OMPExecutableDirective(OMPScopeDirectiveClass, llvm::omp::OMPD_scope,
1952 StartLoc, EndLoc) {}
1953
1954 /// Build an empty directive.
1955 ///
1956 explicit OMPScopeDirective()
1957 : OMPExecutableDirective(OMPScopeDirectiveClass, llvm::omp::OMPD_scope,
1959
1960public:
1961 /// Creates directive.
1962 ///
1963 /// \param C AST context.
1964 /// \param StartLoc Starting location of the directive kind.
1965 /// \param EndLoc Ending Location of the directive.
1966 /// \param AssociatedStmt Statement, associated with the directive.
1967 ///
1968 static OMPScopeDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1969 SourceLocation EndLoc,
1970 ArrayRef<OMPClause *> Clauses,
1971 Stmt *AssociatedStmt);
1972
1973 /// Creates an empty directive.
1974 ///
1975 /// \param C AST context.
1976 ///
1977 static OMPScopeDirective *CreateEmpty(const ASTContext &C,
1978 unsigned NumClauses, EmptyShell);
1979
1980 static bool classof(const Stmt *T) {
1981 return T->getStmtClass() == OMPScopeDirectiveClass;
1982 }
1983};
1984
1985/// This represents '#pragma omp single' directive.
1986///
1987/// \code
1988/// #pragma omp single private(a,b) copyprivate(c,d)
1989/// \endcode
1990/// In this example directive '#pragma omp single' has clauses 'private' with
1991/// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
1992///
1994 friend class ASTStmtReader;
1996 /// Build directive with the given start and end location.
1997 ///
1998 /// \param StartLoc Starting location of the directive kind.
1999 /// \param EndLoc Ending location of the directive.
2000 ///
2002 : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
2003 StartLoc, EndLoc) {}
2004
2005 /// Build an empty directive.
2006 ///
2007 explicit OMPSingleDirective()
2008 : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
2010
2011public:
2012 /// Creates directive with a list of \a Clauses.
2013 ///
2014 /// \param C AST context.
2015 /// \param StartLoc Starting location of the directive kind.
2016 /// \param EndLoc Ending Location of the directive.
2017 /// \param Clauses List of clauses.
2018 /// \param AssociatedStmt Statement, associated with the directive.
2019 ///
2020 static OMPSingleDirective *
2021 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2022 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2023
2024 /// Creates an empty directive with the place for \a NumClauses
2025 /// clauses.
2026 ///
2027 /// \param C AST context.
2028 /// \param NumClauses Number of clauses.
2029 ///
2030 static OMPSingleDirective *CreateEmpty(const ASTContext &C,
2031 unsigned NumClauses, EmptyShell);
2032
2033 static bool classof(const Stmt *T) {
2034 return T->getStmtClass() == OMPSingleDirectiveClass;
2035 }
2036};
2037
2038/// This represents '#pragma omp master' directive.
2039///
2040/// \code
2041/// #pragma omp master
2042/// \endcode
2043///
2045 friend class ASTStmtReader;
2047 /// Build directive with the given start and end location.
2048 ///
2049 /// \param StartLoc Starting location of the directive kind.
2050 /// \param EndLoc Ending location of the directive.
2051 ///
2053 : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
2054 StartLoc, EndLoc) {}
2055
2056 /// Build an empty directive.
2057 ///
2058 explicit OMPMasterDirective()
2059 : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
2061
2062public:
2063 /// Creates directive.
2064 ///
2065 /// \param C AST context.
2066 /// \param StartLoc Starting location of the directive kind.
2067 /// \param EndLoc Ending Location of the directive.
2068 /// \param AssociatedStmt Statement, associated with the directive.
2069 ///
2070 static OMPMasterDirective *Create(const ASTContext &C,
2071 SourceLocation StartLoc,
2072 SourceLocation EndLoc,
2073 Stmt *AssociatedStmt);
2074
2075 /// Creates an empty directive.
2076 ///
2077 /// \param C AST context.
2078 ///
2079 static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2080
2081 static bool classof(const Stmt *T) {
2082 return T->getStmtClass() == OMPMasterDirectiveClass;
2083 }
2084};
2085
2086/// This represents '#pragma omp critical' directive.
2087///
2088/// \code
2089/// #pragma omp critical
2090/// \endcode
2091///
2093 friend class ASTStmtReader;
2095 /// Name of the directive.
2096 DeclarationNameInfo DirName;
2097 /// Build directive with the given start and end location.
2098 ///
2099 /// \param Name Name of the directive.
2100 /// \param StartLoc Starting location of the directive kind.
2101 /// \param EndLoc Ending location of the directive.
2102 ///
2104 SourceLocation EndLoc)
2105 : OMPExecutableDirective(OMPCriticalDirectiveClass,
2106 llvm::omp::OMPD_critical, StartLoc, EndLoc),
2107 DirName(Name) {}
2108
2109 /// Build an empty directive.
2110 ///
2111 explicit OMPCriticalDirective()
2112 : OMPExecutableDirective(OMPCriticalDirectiveClass,
2113 llvm::omp::OMPD_critical, SourceLocation(),
2114 SourceLocation()) {}
2115
2116 /// Set name of the directive.
2117 ///
2118 /// \param Name Name of the directive.
2119 ///
2120 void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
2121
2122public:
2123 /// Creates directive.
2124 ///
2125 /// \param C AST context.
2126 /// \param Name Name of the directive.
2127 /// \param StartLoc Starting location of the directive kind.
2128 /// \param EndLoc Ending Location of the directive.
2129 /// \param Clauses List of clauses.
2130 /// \param AssociatedStmt Statement, associated with the directive.
2131 ///
2132 static OMPCriticalDirective *
2133 Create(const ASTContext &C, const DeclarationNameInfo &Name,
2134 SourceLocation StartLoc, SourceLocation EndLoc,
2135 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2136
2137 /// Creates an empty directive.
2138 ///
2139 /// \param C AST context.
2140 /// \param NumClauses Number of clauses.
2141 ///
2142 static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
2143 unsigned NumClauses, EmptyShell);
2144
2145 /// Return name of the directive.
2146 ///
2147 DeclarationNameInfo getDirectiveName() const { return DirName; }
2148
2149 static bool classof(const Stmt *T) {
2150 return T->getStmtClass() == OMPCriticalDirectiveClass;
2151 }
2152};
2153
2154/// This represents '#pragma omp parallel for' directive.
2155///
2156/// \code
2157/// #pragma omp parallel for private(a,b) reduction(+:c,d)
2158/// \endcode
2159/// In this example directive '#pragma omp parallel for' has clauses 'private'
2160/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
2161/// variables 'c' and 'd'.
2162///
2164 friend class ASTStmtReader;
2166
2167 /// true if current region has inner cancel directive.
2168 bool HasCancel = false;
2169
2170 /// Build directive with the given start and end location.
2171 ///
2172 /// \param StartLoc Starting location of the directive kind.
2173 /// \param EndLoc Ending location of the directive.
2174 /// \param CollapsedNum Number of collapsed nested loops.
2175 ///
2177 unsigned CollapsedNum)
2178 : OMPLoopDirective(OMPParallelForDirectiveClass,
2179 llvm::omp::OMPD_parallel_for, StartLoc, EndLoc,
2180 CollapsedNum) {}
2181
2182 /// Build an empty directive.
2183 ///
2184 /// \param CollapsedNum Number of collapsed nested loops.
2185 ///
2186 explicit OMPParallelForDirective(unsigned CollapsedNum)
2187 : OMPLoopDirective(OMPParallelForDirectiveClass,
2188 llvm::omp::OMPD_parallel_for, SourceLocation(),
2189 SourceLocation(), CollapsedNum) {}
2190
2191 /// Sets special task reduction descriptor.
2192 void setTaskReductionRefExpr(Expr *E) {
2193 Data->getChildren()[numLoopChildren(getLoopsNumber(),
2194 llvm::omp::OMPD_parallel_for)] = E;
2195 }
2196
2197 /// Set cancel state.
2198 void setHasCancel(bool Has) { HasCancel = Has; }
2199
2200public:
2201 /// Creates directive with a list of \a Clauses.
2202 ///
2203 /// \param C AST context.
2204 /// \param StartLoc Starting location of the directive kind.
2205 /// \param EndLoc Ending Location of the directive.
2206 /// \param CollapsedNum Number of collapsed loops.
2207 /// \param Clauses List of clauses.
2208 /// \param AssociatedStmt Statement, associated with the directive.
2209 /// \param Exprs Helper expressions for CodeGen.
2210 /// \param TaskRedRef Task reduction special reference expression to handle
2211 /// taskgroup descriptor.
2212 /// \param HasCancel true if current directive has inner cancel directive.
2213 ///
2214 static OMPParallelForDirective *
2215 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2216 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2217 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
2218 bool HasCancel);
2219
2220 /// Creates an empty directive with the place
2221 /// for \a NumClauses clauses.
2222 ///
2223 /// \param C AST context.
2224 /// \param CollapsedNum Number of collapsed nested loops.
2225 /// \param NumClauses Number of clauses.
2226 ///
2227 static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
2228 unsigned NumClauses,
2229 unsigned CollapsedNum,
2230 EmptyShell);
2231
2232 /// Returns special task reduction reference expression.
2234 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
2235 getLoopsNumber(), llvm::omp::OMPD_parallel_for)]);
2236 }
2238 return const_cast<OMPParallelForDirective *>(this)
2240 }
2241
2242 /// Return true if current directive has inner cancel directive.
2243 bool hasCancel() const { return HasCancel; }
2244
2245 static bool classof(const Stmt *T) {
2246 return T->getStmtClass() == OMPParallelForDirectiveClass;
2247 }
2248};
2249
2250/// This represents '#pragma omp parallel for simd' directive.
2251///
2252/// \code
2253/// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
2254/// \endcode
2255/// In this example directive '#pragma omp parallel for simd' has clauses
2256/// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
2257/// and linear step 's', 'reduction' with operator '+' and variables 'c' and
2258/// 'd'.
2259///
2261 friend class ASTStmtReader;
2263 /// Build directive with the given start and end location.
2264 ///
2265 /// \param StartLoc Starting location of the directive kind.
2266 /// \param EndLoc Ending location of the directive.
2267 /// \param CollapsedNum Number of collapsed nested loops.
2268 ///
2270 unsigned CollapsedNum)
2271 : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
2272 llvm::omp::OMPD_parallel_for_simd, StartLoc, EndLoc,
2273 CollapsedNum) {}
2274
2275 /// Build an empty directive.
2276 ///
2277 /// \param CollapsedNum Number of collapsed nested loops.
2278 ///
2279 explicit OMPParallelForSimdDirective(unsigned CollapsedNum)
2280 : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
2281 llvm::omp::OMPD_parallel_for_simd, SourceLocation(),
2282 SourceLocation(), CollapsedNum) {}
2283
2284public:
2285 /// Creates directive with a list of \a Clauses.
2286 ///
2287 /// \param C AST context.
2288 /// \param StartLoc Starting location of the directive kind.
2289 /// \param EndLoc Ending Location of the directive.
2290 /// \param CollapsedNum Number of collapsed loops.
2291 /// \param Clauses List of clauses.
2292 /// \param AssociatedStmt Statement, associated with the directive.
2293 /// \param Exprs Helper expressions for CodeGen.
2294 ///
2295 static OMPParallelForSimdDirective *
2296 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2297 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2298 Stmt *AssociatedStmt, const HelperExprs &Exprs);
2299
2300 /// Creates an empty directive with the place
2301 /// for \a NumClauses clauses.
2302 ///
2303 /// \param C AST context.
2304 /// \param CollapsedNum Number of collapsed nested loops.
2305 /// \param NumClauses Number of clauses.
2306 ///
2307 static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
2308 unsigned NumClauses,
2309 unsigned CollapsedNum,
2310 EmptyShell);
2311
2312 static bool classof(const Stmt *T) {
2313 return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
2314 }
2315};
2316
2317/// This represents '#pragma omp parallel master' directive.
2318///
2319/// \code
2320/// #pragma omp parallel master private(a,b)
2321/// \endcode
2322/// In this example directive '#pragma omp parallel master' has clauses
2323/// 'private' with the variables 'a' and 'b'
2324///
2326 friend class ASTStmtReader;
2328
2330 : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
2331 llvm::omp::OMPD_parallel_master, StartLoc,
2332 EndLoc) {}
2333
2335 : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
2336 llvm::omp::OMPD_parallel_master,
2338
2339 /// Sets special task reduction descriptor.
2340 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2341
2342public:
2343 /// Creates directive with a list of \a Clauses.
2344 ///
2345 /// \param C AST context.
2346 /// \param StartLoc Starting location of the directive kind.
2347 /// \param EndLoc Ending Location of the directive.
2348 /// \param Clauses List of clauses.
2349 /// \param AssociatedStmt Statement, associated with the directive.
2350 /// \param TaskRedRef Task reduction special reference expression to handle
2351 /// taskgroup descriptor.
2352 ///
2353 static OMPParallelMasterDirective *
2354 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2355 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
2356
2357 /// Creates an empty directive with the place for \a NumClauses
2358 /// clauses.
2359 ///
2360 /// \param C AST context.
2361 /// \param NumClauses Number of clauses.
2362 ///
2363 static OMPParallelMasterDirective *
2364 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2365
2366 /// Returns special task reduction reference expression.
2368 return cast_or_null<Expr>(Data->getChildren()[0]);
2369 }
2371 return const_cast<OMPParallelMasterDirective *>(this)
2373 }
2374
2375 static bool classof(const Stmt *T) {
2376 return T->getStmtClass() == OMPParallelMasterDirectiveClass;
2377 }
2378};
2379
2380/// This represents '#pragma omp parallel masked' directive.
2381///
2382/// \code
2383/// #pragma omp parallel masked filter(tid)
2384/// \endcode
2385/// In this example directive '#pragma omp parallel masked' has a clause
2386/// 'filter' with the variable tid
2387///
2389 friend class ASTStmtReader;
2391
2393 : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
2394 llvm::omp::OMPD_parallel_masked, StartLoc,
2395 EndLoc) {}
2396
2398 : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
2399 llvm::omp::OMPD_parallel_masked,
2401
2402 /// Sets special task reduction descriptor.
2403 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2404
2405public:
2406 /// Creates directive with a list of \a Clauses.
2407 ///
2408 /// \param C AST context.
2409 /// \param StartLoc Starting location of the directive kind.
2410 /// \param EndLoc Ending Location of the directive.
2411 /// \param Clauses List of clauses.
2412 /// \param AssociatedStmt Statement, associated with the directive.
2413 /// \param TaskRedRef Task reduction special reference expression to handle
2414 /// taskgroup descriptor.
2415 ///
2416 static OMPParallelMaskedDirective *
2417 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2418 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
2419
2420 /// Creates an empty directive with the place for \a NumClauses
2421 /// clauses.
2422 ///
2423 /// \param C AST context.
2424 /// \param NumClauses Number of clauses.
2425 ///
2426 static OMPParallelMaskedDirective *
2427 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2428
2429 /// Returns special task reduction reference expression.
2431 return cast_or_null<Expr>(Data->getChildren()[0]);
2432 }
2434 return const_cast<OMPParallelMaskedDirective *>(this)
2436 }
2437
2438 static bool classof(const Stmt *T) {
2439 return T->getStmtClass() == OMPParallelMaskedDirectiveClass;
2440 }
2441};
2442
2443/// This represents '#pragma omp parallel sections' directive.
2444///
2445/// \code
2446/// #pragma omp parallel sections private(a,b) reduction(+:c,d)
2447/// \endcode
2448/// In this example directive '#pragma omp parallel sections' has clauses
2449/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
2450/// and variables 'c' and 'd'.
2451///
2453 friend class ASTStmtReader;
2455
2456 /// true if current directive has inner cancel directive.
2457 bool HasCancel = false;
2458
2459 /// Build directive with the given start and end location.
2460 ///
2461 /// \param StartLoc Starting location of the directive kind.
2462 /// \param EndLoc Ending location of the directive.
2463 ///
2465 : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
2466 llvm::omp::OMPD_parallel_sections, StartLoc,
2467 EndLoc) {}
2468
2469 /// Build an empty directive.
2470 ///
2472 : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
2473 llvm::omp::OMPD_parallel_sections,
2475
2476 /// Sets special task reduction descriptor.
2477 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2478
2479 /// Set cancel state.
2480 void setHasCancel(bool Has) { HasCancel = Has; }
2481
2482public:
2483 /// Creates directive with a list of \a Clauses.
2484 ///
2485 /// \param C AST context.
2486 /// \param StartLoc Starting location of the directive kind.
2487 /// \param EndLoc Ending Location of the directive.
2488 /// \param Clauses List of clauses.
2489 /// \param AssociatedStmt Statement, associated with the directive.
2490 /// \param TaskRedRef Task reduction special reference expression to handle
2491 /// taskgroup descriptor.
2492 /// \param HasCancel true if current directive has inner cancel directive.
2493 ///
2494 static OMPParallelSectionsDirective *
2495 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2496 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
2497 bool HasCancel);
2498
2499 /// Creates an empty directive with the place for \a NumClauses
2500 /// clauses.
2501 ///
2502 /// \param C AST context.
2503 /// \param NumClauses Number of clauses.
2504 ///
2505 static OMPParallelSectionsDirective *
2506 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2507
2508 /// Returns special task reduction reference expression.
2510 return cast_or_null<Expr>(Data->getChildren()[0]);
2511 }
2513 return const_cast<OMPParallelSectionsDirective *>(this)
2515 }
2516
2517 /// Return true if current directive has inner cancel directive.
2518 bool hasCancel() const { return HasCancel; }
2519
2520 static bool classof(const Stmt *T) {
2521 return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
2522 }
2523};
2524
2525/// This represents '#pragma omp task' directive.
2526///
2527/// \code
2528/// #pragma omp task private(a,b) final(d)
2529/// \endcode
2530/// In this example directive '#pragma omp task' has clauses 'private' with the
2531/// variables 'a' and 'b' and 'final' with condition 'd'.
2532///
2534 friend class ASTStmtReader;
2536 /// true if this directive has inner cancel directive.
2537 bool HasCancel = false;
2538
2539 /// Build directive with the given start and end location.
2540 ///
2541 /// \param StartLoc Starting location of the directive kind.
2542 /// \param EndLoc Ending location of the directive.
2543 ///
2545 : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
2546 StartLoc, EndLoc) {}
2547
2548 /// Build an empty directive.
2549 ///
2550 explicit OMPTaskDirective()
2551 : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
2553
2554 /// Set cancel state.
2555 void setHasCancel(bool Has) { HasCancel = Has; }
2556
2557public:
2558 /// Creates directive with a list of \a Clauses.
2559 ///
2560 /// \param C AST context.
2561 /// \param StartLoc Starting location of the directive kind.
2562 /// \param EndLoc Ending Location of the directive.
2563 /// \param Clauses List of clauses.
2564 /// \param AssociatedStmt Statement, associated with the directive.
2565 /// \param HasCancel true, if current directive has inner cancel directive.
2566 ///
2567 static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2568 SourceLocation EndLoc,
2569 ArrayRef<OMPClause *> Clauses,
2570 Stmt *AssociatedStmt, bool HasCancel);
2571
2572 /// Creates an empty directive with the place for \a NumClauses
2573 /// clauses.
2574 ///
2575 /// \param C AST context.
2576 /// \param NumClauses Number of clauses.
2577 ///
2578 static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
2579 EmptyShell);
2580
2581 /// Return true if current directive has inner cancel directive.
2582 bool hasCancel() const { return HasCancel; }
2583
2584 static bool classof(const Stmt *T) {
2585 return T->getStmtClass() == OMPTaskDirectiveClass;
2586 }
2587};
2588
2589/// This represents '#pragma omp taskyield' directive.
2590///
2591/// \code
2592/// #pragma omp taskyield
2593/// \endcode
2594///
2596 friend class ASTStmtReader;
2598 /// Build directive with the given start and end location.
2599 ///
2600 /// \param StartLoc Starting location of the directive kind.
2601 /// \param EndLoc Ending location of the directive.
2602 ///
2604 : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
2605 llvm::omp::OMPD_taskyield, StartLoc, EndLoc) {}
2606
2607 /// Build an empty directive.
2608 ///
2609 explicit OMPTaskyieldDirective()
2610 : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
2611 llvm::omp::OMPD_taskyield, SourceLocation(),
2612 SourceLocation()) {}
2613
2614public:
2615 /// Creates directive.
2616 ///
2617 /// \param C AST context.
2618 /// \param StartLoc Starting location of the directive kind.
2619 /// \param EndLoc Ending Location of the directive.
2620 ///
2621 static OMPTaskyieldDirective *
2622 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
2623
2624 /// Creates an empty directive.
2625 ///
2626 /// \param C AST context.
2627 ///
2628 static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2629
2630 static bool classof(const Stmt *T) {
2631 return T->getStmtClass() == OMPTaskyieldDirectiveClass;
2632 }
2633};
2634
2635/// This represents '#pragma omp barrier' directive.
2636///
2637/// \code
2638/// #pragma omp barrier
2639/// \endcode
2640///
2642 friend class ASTStmtReader;
2644 /// Build directive with the given start and end location.
2645 ///
2646 /// \param StartLoc Starting location of the directive kind.
2647 /// \param EndLoc Ending location of the directive.
2648 ///
2650 : OMPExecutableDirective(OMPBarrierDirectiveClass,
2651 llvm::omp::OMPD_barrier, StartLoc, EndLoc) {}
2652
2653 /// Build an empty directive.
2654 ///
2655 explicit OMPBarrierDirective()
2656 : OMPExecutableDirective(OMPBarrierDirectiveClass,
2657 llvm::omp::OMPD_barrier, SourceLocation(),
2658 SourceLocation()) {}
2659
2660public:
2661 /// Creates directive.
2662 ///
2663 /// \param C AST context.
2664 /// \param StartLoc Starting location of the directive kind.
2665 /// \param EndLoc Ending Location of the directive.
2666 ///
2667 static OMPBarrierDirective *
2668 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
2669
2670 /// Creates an empty directive.
2671 ///
2672 /// \param C AST context.
2673 ///
2674 static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2675
2676 static bool classof(const Stmt *T) {
2677 return T->getStmtClass() == OMPBarrierDirectiveClass;
2678 }
2679};
2680
2681/// This represents '#pragma omp taskwait' directive.
2682///
2683/// \code
2684/// #pragma omp taskwait
2685/// \endcode
2686///
2688 friend class ASTStmtReader;
2690 /// Build directive with the given start and end location.
2691 ///
2692 /// \param StartLoc Starting location of the directive kind.
2693 /// \param EndLoc Ending location of the directive.
2694 ///
2696 : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
2697 llvm::omp::OMPD_taskwait, StartLoc, EndLoc) {}
2698
2699 /// Build an empty directive.
2700 ///
2701 explicit OMPTaskwaitDirective()
2702 : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
2703 llvm::omp::OMPD_taskwait, SourceLocation(),
2704 SourceLocation()) {}
2705
2706public:
2707 /// Creates directive.
2708 ///
2709 /// \param C AST context.
2710 /// \param StartLoc Starting location of the directive kind.
2711 /// \param EndLoc Ending Location of the directive.
2712 /// \param Clauses List of clauses.
2713 ///
2714 static OMPTaskwaitDirective *Create(const ASTContext &C,
2715 SourceLocation StartLoc,
2716 SourceLocation EndLoc,
2717 ArrayRef<OMPClause *> Clauses);
2718
2719 /// Creates an empty directive.
2720 ///
2721 /// \param C AST context.
2722 /// \param NumClauses Number of clauses.
2723 ///
2724 static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C,
2725 unsigned NumClauses, EmptyShell);
2726
2727 static bool classof(const Stmt *T) {
2728 return T->getStmtClass() == OMPTaskwaitDirectiveClass;
2729 }
2730};
2731
2732/// This represents '#pragma omp taskgroup' directive.
2733///
2734/// \code
2735/// #pragma omp taskgroup
2736/// \endcode
2737///
2739 friend class ASTStmtReader;
2741 /// Build directive with the given start and end location.
2742 ///
2743 /// \param StartLoc Starting location of the directive kind.
2744 /// \param EndLoc Ending location of the directive.
2745 ///
2747 : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
2748 llvm::omp::OMPD_taskgroup, StartLoc, EndLoc) {}
2749
2750 /// Build an empty directive.
2751 ///
2752 explicit OMPTaskgroupDirective()
2753 : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
2754 llvm::omp::OMPD_taskgroup, SourceLocation(),
2755 SourceLocation()) {}
2756
2757 /// Sets the task_reduction return variable.
2758 void setReductionRef(Expr *RR) { Data->getChildren()[0] = RR; }
2759
2760public:
2761 /// Creates directive.
2762 ///
2763 /// \param C AST context.
2764 /// \param StartLoc Starting location of the directive kind.
2765 /// \param EndLoc Ending Location of the directive.
2766 /// \param Clauses List of clauses.
2767 /// \param AssociatedStmt Statement, associated with the directive.
2768 /// \param ReductionRef Reference to the task_reduction return variable.
2769 ///
2770 static OMPTaskgroupDirective *
2771 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2772 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
2773 Expr *ReductionRef);
2774
2775 /// Creates an empty directive.
2776 ///
2777 /// \param C AST context.
2778 /// \param NumClauses Number of clauses.
2779 ///
2780 static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C,
2781 unsigned NumClauses, EmptyShell);
2782
2783
2784 /// Returns reference to the task_reduction return variable.
2785 const Expr *getReductionRef() const {
2786 return const_cast<OMPTaskgroupDirective *>(this)->getReductionRef();
2787 }
2788 Expr *getReductionRef() { return cast_or_null<Expr>(Data->getChildren()[0]); }
2789
2790 static bool classof(const Stmt *T) {
2791 return T->getStmtClass() == OMPTaskgroupDirectiveClass;
2792 }
2793};
2794
2795/// This represents '#pragma omp flush' directive.
2796///
2797/// \code
2798/// #pragma omp flush(a,b)
2799/// \endcode
2800/// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
2801/// and 'b'.
2802/// 'omp flush' directive does not have clauses but have an optional list of
2803/// variables to flush. This list of variables is stored within some fake clause
2804/// FlushClause.
2806 friend class ASTStmtReader;
2808 /// Build directive with the given start and end location.
2809 ///
2810 /// \param StartLoc Starting location of the directive kind.
2811 /// \param EndLoc Ending location of the directive.
2812 ///
2814 : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
2815 StartLoc, EndLoc) {}
2816
2817 /// Build an empty directive.
2818 ///
2819 explicit OMPFlushDirective()
2820 : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
2822
2823public:
2824 /// Creates directive with a list of \a Clauses.
2825 ///
2826 /// \param C AST context.
2827 /// \param StartLoc Starting location of the directive kind.
2828 /// \param EndLoc Ending Location of the directive.
2829 /// \param Clauses List of clauses (only single OMPFlushClause clause is
2830 /// allowed).
2831 ///
2832 static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2833 SourceLocation EndLoc,
2834 ArrayRef<OMPClause *> Clauses);
2835
2836 /// Creates an empty directive with the place for \a NumClauses
2837 /// clauses.
2838 ///
2839 /// \param C AST context.
2840 /// \param NumClauses Number of clauses.
2841 ///
2842 static OMPFlushDirective *CreateEmpty(const ASTContext &C,
2843 unsigned NumClauses, EmptyShell);
2844
2845 static bool classof(const Stmt *T) {
2846 return T->getStmtClass() == OMPFlushDirectiveClass;
2847 }
2848};
2849
2850/// This represents '#pragma omp depobj' directive.
2851///
2852/// \code
2853/// #pragma omp depobj(a) depend(in:x,y)
2854/// \endcode
2855/// In this example directive '#pragma omp depobj' initializes a depobj object
2856/// 'a' with dependence type 'in' and a list with 'x' and 'y' locators.
2858 friend class ASTStmtReader;
2860
2861 /// Build directive with the given start and end location.
2862 ///
2863 /// \param StartLoc Starting location of the directive kind.
2864 /// \param EndLoc Ending location of the directive.
2865 ///
2867 : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
2868 StartLoc, EndLoc) {}
2869
2870 /// Build an empty directive.
2871 ///
2872 explicit OMPDepobjDirective()
2873 : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
2875
2876public:
2877 /// Creates directive with a list of \a Clauses.
2878 ///
2879 /// \param C AST context.
2880 /// \param StartLoc Starting location of the directive kind.
2881 /// \param EndLoc Ending Location of the directive.
2882 /// \param Clauses List of clauses.
2883 ///
2884 static OMPDepobjDirective *Create(const ASTContext &C,
2885 SourceLocation StartLoc,
2886 SourceLocation EndLoc,
2887 ArrayRef<OMPClause *> Clauses);
2888
2889 /// Creates an empty directive with the place for \a NumClauses
2890 /// clauses.
2891 ///
2892 /// \param C AST context.
2893 /// \param NumClauses Number of clauses.
2894 ///
2895 static OMPDepobjDirective *CreateEmpty(const ASTContext &C,
2896 unsigned NumClauses, EmptyShell);
2897
2898 static bool classof(const Stmt *T) {
2899 return T->getStmtClass() == OMPDepobjDirectiveClass;
2900 }
2901};
2902
2903/// This represents '#pragma omp ordered' directive.
2904///
2905/// \code
2906/// #pragma omp ordered
2907/// \endcode
2908///
2910 friend class ASTStmtReader;
2912 /// Build directive with the given start and end location.
2913 ///
2914 /// \param StartLoc Starting location of the directive kind.
2915 /// \param EndLoc Ending location of the directive.
2916 ///
2918 : OMPExecutableDirective(OMPOrderedDirectiveClass,
2919 llvm::omp::OMPD_ordered, StartLoc, EndLoc) {}
2920
2921 /// Build an empty directive.
2922 ///
2923 explicit OMPOrderedDirective()
2924 : OMPExecutableDirective(OMPOrderedDirectiveClass,
2925 llvm::omp::OMPD_ordered, SourceLocation(),
2926 SourceLocation()) {}
2927
2928public:
2929 /// Creates directive.
2930 ///
2931 /// \param C AST context.
2932 /// \param StartLoc Starting location of the directive kind.
2933 /// \param EndLoc Ending Location of the directive.
2934 /// \param Clauses List of clauses.
2935 /// \param AssociatedStmt Statement, associated with the directive.
2936 ///
2937 static OMPOrderedDirective *
2938 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2939 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2940
2941 /// Creates an empty directive.
2942 ///
2943 /// \param C AST context.
2944 /// \param NumClauses Number of clauses.
2945 /// \param IsStandalone true, if the standalone directive is created.
2946 ///
2947 static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
2948 unsigned NumClauses,
2949 bool IsStandalone, EmptyShell);
2950
2951 static bool classof(const Stmt *T) {
2952 return T->getStmtClass() == OMPOrderedDirectiveClass;
2953 }
2954};
2955
2956/// This represents '#pragma omp atomic' directive.
2957///
2958/// \code
2959/// #pragma omp atomic capture
2960/// \endcode
2961/// In this example directive '#pragma omp atomic' has clause 'capture'.
2962///
2964 friend class ASTStmtReader;
2966
2967 struct FlagTy {
2968 /// Used for 'atomic update' or 'atomic capture' constructs. They may
2969 /// have atomic expressions of forms:
2970 /// \code
2971 /// x = x binop expr;
2972 /// x = expr binop x;
2973 /// \endcode
2974 /// This field is 1 for the first form of the expression and 0 for the
2975 /// second. Required for correct codegen of non-associative operations (like
2976 /// << or >>).
2977 uint8_t IsXLHSInRHSPart : 1;
2978 /// Used for 'atomic update' or 'atomic capture' constructs. They may
2979 /// have atomic expressions of forms:
2980 /// \code
2981 /// v = x; <update x>;
2982 /// <update x>; v = x;
2983 /// \endcode
2984 /// This field is 1 for the first(postfix) form of the expression and 0
2985 /// otherwise.
2986 uint8_t IsPostfixUpdate : 1;
2987 /// 1 if 'v' is updated only when the condition is false (compare capture
2988 /// only).
2989 uint8_t IsFailOnly : 1;
2990 } Flags;
2991
2992 /// Build directive with the given start and end location.
2993 ///
2994 /// \param StartLoc Starting location of the directive kind.
2995 /// \param EndLoc Ending location of the directive.
2996 ///
2998 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
2999 StartLoc, EndLoc) {}
3000
3001 /// Build an empty directive.
3002 ///
3003 explicit OMPAtomicDirective()
3004 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
3005 SourceLocation(), SourceLocation()) {}
3006
3007 enum DataPositionTy : size_t {
3008 POS_X = 0,
3009 POS_V,
3010 POS_E,
3011 POS_UpdateExpr,
3012 POS_D,
3013 POS_Cond,
3014 POS_R,
3015 };
3016
3017 /// Set 'x' part of the associated expression/statement.
3018 void setX(Expr *X) { Data->getChildren()[DataPositionTy::POS_X] = X; }
3019 /// Set helper expression of the form
3020 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
3021 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3022 void setUpdateExpr(Expr *UE) {
3023 Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE;
3024 }
3025 /// Set 'v' part of the associated expression/statement.
3026 void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; }
3027 /// Set 'r' part of the associated expression/statement.
3028 void setR(Expr *R) { Data->getChildren()[DataPositionTy::POS_R] = R; }
3029 /// Set 'expr' part of the associated expression/statement.
3030 void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; }
3031 /// Set 'd' part of the associated expression/statement.
3032 void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; }
3033 /// Set conditional expression in `atomic compare`.
3034 void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; }
3035
3036public:
3038 /// 'x' part of the associated expression/statement.
3039 Expr *X = nullptr;
3040 /// 'v' part of the associated expression/statement.
3041 Expr *V = nullptr;
3042 // 'r' part of the associated expression/statement.
3043 Expr *R = nullptr;
3044 /// 'expr' part of the associated expression/statement.
3045 Expr *E = nullptr;
3046 /// UE Helper expression of the form:
3047 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
3048 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3049 Expr *UE = nullptr;
3050 /// 'd' part of the associated expression/statement.
3051 Expr *D = nullptr;
3052 /// Conditional expression in `atomic compare` construct.
3053 Expr *Cond = nullptr;
3054 /// True if UE has the first form and false if the second.
3056 /// True if original value of 'x' must be stored in 'v', not an updated one.
3058 /// True if 'v' is updated only when the condition is false (compare capture
3059 /// only).
3061 };
3062
3063 /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
3064 /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
3065 /// detailed description of 'x', 'v' and 'expr').
3066 ///
3067 /// \param C AST context.
3068 /// \param StartLoc Starting location of the directive kind.
3069 /// \param EndLoc Ending Location of the directive.
3070 /// \param Clauses List of clauses.
3071 /// \param AssociatedStmt Statement, associated with the directive.
3072 /// \param Exprs Associated expressions or statements.
3073 static OMPAtomicDirective *Create(const ASTContext &C,
3074 SourceLocation StartLoc,
3075 SourceLocation EndLoc,
3076 ArrayRef<OMPClause *> Clauses,
3077 Stmt *AssociatedStmt, Expressions Exprs);
3078
3079 /// Creates an empty directive with the place for \a NumClauses
3080 /// clauses.
3081 ///
3082 /// \param C AST context.
3083 /// \param NumClauses Number of clauses.
3084 ///
3086 unsigned NumClauses, EmptyShell);
3087
3088 /// Get 'x' part of the associated expression/statement.
3090 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
3091 }
3092 const Expr *getX() const {
3093 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
3094 }
3095 /// Get helper expression of the form
3096 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
3097 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3099 return cast_or_null<Expr>(
3100 Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
3101 }
3102 const Expr *getUpdateExpr() const {
3103 return cast_or_null<Expr>(
3104 Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
3105 }
3106 /// Return true if helper update expression has form
3107 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
3108 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3109 bool isXLHSInRHSPart() const { return Flags.IsXLHSInRHSPart; }
3110 /// Return true if 'v' expression must be updated to original value of
3111 /// 'x', false if 'v' must be updated to the new value of 'x'.
3112 bool isPostfixUpdate() const { return Flags.IsPostfixUpdate; }
3113 /// Return true if 'v' is updated only when the condition is evaluated false
3114 /// (compare capture only).
3115 bool isFailOnly() const { return Flags.IsFailOnly; }
3116 /// Get 'v' part of the associated expression/statement.
3118 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
3119 }
3120 const Expr *getV() const {
3121 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
3122 }
3123 /// Get 'r' part of the associated expression/statement.
3125 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
3126 }
3127 const Expr *getR() const {
3128 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
3129 }
3130 /// Get 'expr' part of the associated expression/statement.
3132 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
3133 }
3134 const Expr *getExpr() const {
3135 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
3136 }
3137 /// Get 'd' part of the associated expression/statement.
3139 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
3140 }
3141 Expr *getD() const {
3142 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
3143 }
3144 /// Get the 'cond' part of the source atomic expression.
3146 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
3147 }
3149 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
3150 }
3151
3152 static bool classof(const Stmt *T) {
3153 return T->getStmtClass() == OMPAtomicDirectiveClass;
3154 }
3155};
3156
3157/// This represents '#pragma omp target' directive.
3158///
3159/// \code
3160/// #pragma omp target if(a)
3161/// \endcode
3162/// In this example directive '#pragma omp target' has clause 'if' with
3163/// condition 'a'.
3164///
3166 friend class ASTStmtReader;
3168 /// Build directive with the given start and end location.
3169 ///
3170 /// \param StartLoc Starting location of the directive kind.
3171 /// \param EndLoc Ending location of the directive.
3172 ///
3174 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
3175 StartLoc, EndLoc) {}
3176
3177 /// Build an empty directive.
3178 ///
3179 explicit OMPTargetDirective()
3180 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
3182
3183public:
3184 /// Creates directive with a list of \a Clauses.
3185 ///
3186 /// \param C AST context.
3187 /// \param StartLoc Starting location of the directive kind.
3188 /// \param EndLoc Ending Location of the directive.
3189 /// \param Clauses List of clauses.
3190 /// \param AssociatedStmt Statement, associated with the directive.
3191 ///
3192 static OMPTargetDirective *
3193 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3194 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3195
3196 /// Creates an empty directive with the place for \a NumClauses
3197 /// clauses.
3198 ///
3199 /// \param C AST context.
3200 /// \param NumClauses Number of clauses.
3201 ///
3202 static OMPTargetDirective *CreateEmpty(const ASTContext &C,
3203 unsigned NumClauses, EmptyShell);
3204
3205 static bool classof(const Stmt *T) {
3206 return T->getStmtClass() == OMPTargetDirectiveClass;
3207 }
3208};
3209
3210/// This represents '#pragma omp target data' directive.
3211///
3212/// \code
3213/// #pragma omp target data device(0) if(a) map(b[:])
3214/// \endcode
3215/// In this example directive '#pragma omp target data' has clauses 'device'
3216/// with the value '0', 'if' with condition 'a' and 'map' with array
3217/// section 'b[:]'.
3218///
3220 friend class ASTStmtReader;
3222 /// Build directive with the given start and end location.
3223 ///
3224 /// \param StartLoc Starting location of the directive kind.
3225 /// \param EndLoc Ending Location of the directive.
3226 ///
3228 : OMPExecutableDirective(OMPTargetDataDirectiveClass,
3229 llvm::omp::OMPD_target_data, StartLoc, EndLoc) {}
3230
3231 /// Build an empty directive.
3232 ///
3233 explicit OMPTargetDataDirective()
3234 : OMPExecutableDirective(OMPTargetDataDirectiveClass,
3235 llvm::omp::OMPD_target_data, SourceLocation(),
3236 SourceLocation()) {}
3237
3238public:
3239 /// Creates directive with a list of \a Clauses.
3240 ///
3241 /// \param C AST context.
3242 /// \param StartLoc Starting location of the directive kind.
3243 /// \param EndLoc Ending Location of the directive.
3244 /// \param Clauses List of clauses.
3245 /// \param AssociatedStmt Statement, associated with the directive.
3246 ///
3247 static OMPTargetDataDirective *
3248 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3249 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3250
3251 /// Creates an empty directive with the place for \a N clauses.
3252 ///
3253 /// \param C AST context.
3254 /// \param N The number of clauses.
3255 ///
3256 static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
3257 EmptyShell);
3258
3259 static bool classof(const Stmt *T) {
3260 return T->getStmtClass() == OMPTargetDataDirectiveClass;
3261 }
3262};
3263
3264/// This represents '#pragma omp target enter data' directive.
3265///
3266/// \code
3267/// #pragma omp target enter data device(0) if(a) map(b[:])
3268/// \endcode
3269/// In this example directive '#pragma omp target enter data' has clauses
3270/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
3271/// section 'b[:]'.
3272///
3274 friend class ASTStmtReader;
3276 /// Build directive with the given start and end location.
3277 ///
3278 /// \param StartLoc Starting location of the directive kind.
3279 /// \param EndLoc Ending Location of the directive.
3280 ///
3282 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3283 llvm::omp::OMPD_target_enter_data, StartLoc,
3284 EndLoc) {}
3285
3286 /// Build an empty directive.
3287 ///
3289 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3290 llvm::omp::OMPD_target_enter_data,
3292
3293public:
3294 /// Creates directive with a list of \a Clauses.
3295 ///
3296 /// \param C AST context.
3297 /// \param StartLoc Starting location of the directive kind.
3298 /// \param EndLoc Ending Location of the directive.
3299 /// \param Clauses List of clauses.
3300 /// \param AssociatedStmt Statement, associated with the directive.
3301 ///
3302 static OMPTargetEnterDataDirective *
3303 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3304 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3305
3306 /// Creates an empty directive with the place for \a N clauses.
3307 ///
3308 /// \param C AST context.
3309 /// \param N The number of clauses.
3310 ///
3311 static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C,
3312 unsigned N, EmptyShell);
3313
3314 static bool classof(const Stmt *T) {
3315 return T->getStmtClass() == OMPTargetEnterDataDirectiveClass;
3316 }
3317};
3318
3319/// This represents '#pragma omp target exit data' directive.
3320///
3321/// \code
3322/// #pragma omp target exit data device(0) if(a) map(b[:])
3323/// \endcode
3324/// In this example directive '#pragma omp target exit data' has clauses
3325/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
3326/// section 'b[:]'.
3327///
3329 friend class ASTStmtReader;
3331 /// Build directive with the given start and end location.
3332 ///
3333 /// \param StartLoc Starting location of the directive kind.
3334 /// \param EndLoc Ending Location of the directive.
3335 ///
3337 : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3338 llvm::omp::OMPD_target_exit_data, StartLoc,
3339 EndLoc) {}
3340
3341 /// Build an empty directive.
3342 ///
3344 : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3345 llvm::omp::OMPD_target_exit_data,
3347
3348public:
3349 /// Creates directive with a list of \a Clauses.
3350 ///
3351 /// \param C AST context.
3352 /// \param StartLoc Starting location of the directive kind.
3353 /// \param EndLoc Ending Location of the directive.
3354 /// \param Clauses List of clauses.
3355 /// \param AssociatedStmt Statement, associated with the directive.
3356 ///
3357 static OMPTargetExitDataDirective *
3358 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3359 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3360
3361 /// Creates an empty directive with the place for \a N clauses.
3362 ///
3363 /// \param C AST context.
3364 /// \param N The number of clauses.
3365 ///
3366 static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
3367 unsigned N, EmptyShell);
3368
3369 static bool classof(const Stmt *T) {
3370 return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
3371 }
3372};
3373
3374/// This represents '#pragma omp target parallel' directive.
3375///
3376/// \code
3377/// #pragma omp target parallel if(a)
3378/// \endcode
3379/// In this example directive '#pragma omp target parallel' has clause 'if' with
3380/// condition 'a'.
3381///
3383 friend class ASTStmtReader;
3385 /// true if the construct has inner cancel directive.
3386 bool HasCancel = false;
3387
3388 /// Build directive with the given start and end location.
3389 ///
3390 /// \param StartLoc Starting location of the directive kind.
3391 /// \param EndLoc Ending location of the directive.
3392 ///
3394 : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3395 llvm::omp::OMPD_target_parallel, StartLoc,
3396 EndLoc) {}
3397
3398 /// Build an empty directive.
3399 ///
3401 : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3402 llvm::omp::OMPD_target_parallel,
3404
3405 /// Sets special task reduction descriptor.
3406 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
3407 /// Set cancel state.
3408 void setHasCancel(bool Has) { HasCancel = Has; }
3409
3410public:
3411 /// Creates directive with a list of \a Clauses.
3412 ///
3413 /// \param C AST context.
3414 /// \param StartLoc Starting location of the directive kind.
3415 /// \param EndLoc Ending Location of the directive.
3416 /// \param Clauses List of clauses.
3417 /// \param AssociatedStmt Statement, associated with the directive.
3418 /// \param TaskRedRef Task reduction special reference expression to handle
3419 /// taskgroup descriptor.
3420 /// \param HasCancel true if this directive has inner cancel directive.
3421 ///
3422 static OMPTargetParallelDirective *
3423 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3424 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
3425 bool HasCancel);
3426
3427 /// Creates an empty directive with the place for \a NumClauses
3428 /// clauses.
3429 ///
3430 /// \param C AST context.
3431 /// \param NumClauses Number of clauses.
3432 ///
3433 static OMPTargetParallelDirective *
3434 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
3435
3436 /// Returns special task reduction reference expression.
3438 return cast_or_null<Expr>(Data->getChildren()[0]);
3439 }
3441 return const_cast<OMPTargetParallelDirective *>(this)
3443 }
3444
3445 /// Return true if current directive has inner cancel directive.
3446 bool hasCancel() const { return HasCancel; }
3447
3448 static bool classof(const Stmt *T) {
3449 return T->getStmtClass() == OMPTargetParallelDirectiveClass;
3450 }
3451};
3452
3453/// This represents '#pragma omp target parallel for' directive.
3454///
3455/// \code
3456/// #pragma omp target parallel for private(a,b) reduction(+:c,d)
3457/// \endcode
3458/// In this example directive '#pragma omp target parallel for' has clauses
3459/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
3460/// and variables 'c' and 'd'.
3461///
3463 friend class ASTStmtReader;
3465
3466 /// true if current region has inner cancel directive.
3467 bool HasCancel = false;
3468
3469 /// Build directive with the given start and end location.
3470 ///
3471 /// \param StartLoc Starting location of the directive kind.
3472 /// \param EndLoc Ending location of the directive.
3473 /// \param CollapsedNum Number of collapsed nested loops.
3474 ///
3476 unsigned CollapsedNum)
3477 : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3478 llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc,
3479 CollapsedNum) {}
3480
3481 /// Build an empty directive.
3482 ///
3483 /// \param CollapsedNum Number of collapsed nested loops.
3484 ///
3485 explicit OMPTargetParallelForDirective(unsigned CollapsedNum)
3486 : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3487 llvm::omp::OMPD_target_parallel_for, SourceLocation(),
3488 SourceLocation(), CollapsedNum) {}
3489
3490 /// Sets special task reduction descriptor.
3491 void setTaskReductionRefExpr(Expr *E) {
3492 Data->getChildren()[numLoopChildren(
3493 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E;
3494 }
3495
3496 /// Set cancel state.
3497 void setHasCancel(bool Has) { HasCancel = Has; }
3498
3499public:
3500 /// Creates directive with a list of \a Clauses.
3501 ///
3502 /// \param C AST context.
3503 /// \param StartLoc Starting location of the directive kind.
3504 /// \param EndLoc Ending Location of the directive.
3505 /// \param CollapsedNum Number of collapsed loops.
3506 /// \param Clauses List of clauses.
3507 /// \param AssociatedStmt Statement, associated with the directive.
3508 /// \param Exprs Helper expressions for CodeGen.
3509 /// \param TaskRedRef Task reduction special reference expression to handle
3510 /// taskgroup descriptor.
3511 /// \param HasCancel true if current directive has inner cancel directive.
3512 ///
3513 static OMPTargetParallelForDirective *
3514 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3515 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3516 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
3517 bool HasCancel);
3518
3519 /// Creates an empty directive with the place
3520 /// for \a NumClauses clauses.
3521 ///
3522 /// \param C AST context.
3523 /// \param CollapsedNum Number of collapsed nested loops.
3524 /// \param NumClauses Number of clauses.
3525 ///
3526 static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C,
3527 unsigned NumClauses,
3528 unsigned CollapsedNum,
3529 EmptyShell);
3530
3531 /// Returns special task reduction reference expression.
3533 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
3534 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]);
3535 }
3537 return const_cast<OMPTargetParallelForDirective *>(this)
3539 }
3540
3541 /// Return true if current directive has inner cancel directive.
3542 bool hasCancel() const { return HasCancel; }
3543
3544 static bool classof(const Stmt *T) {
3545 return T->getStmtClass() == OMPTargetParallelForDirectiveClass;
3546 }
3547};
3548
3549/// This represents '#pragma omp teams' directive.
3550///
3551/// \code
3552/// #pragma omp teams if(a)
3553/// \endcode
3554/// In this example directive '#pragma omp teams' has clause 'if' with
3555/// condition 'a'.
3556///
3558 friend class ASTStmtReader;
3560 /// Build directive with the given start and end location.
3561 ///
3562 /// \param StartLoc Starting location of the directive kind.
3563 /// \param EndLoc Ending location of the directive.
3564 ///
3566 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3567 StartLoc, EndLoc) {}
3568
3569 /// Build an empty directive.
3570 ///
3571 explicit OMPTeamsDirective()
3572 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3574
3575public:
3576 /// Creates directive with a list of \a Clauses.
3577 ///
3578 /// \param C AST context.
3579 /// \param StartLoc Starting location of the directive kind.
3580 /// \param EndLoc Ending Location of the directive.
3581 /// \param Clauses List of clauses.
3582 /// \param AssociatedStmt Statement, associated with the directive.
3583 ///
3584 static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
3585 SourceLocation EndLoc,
3586 ArrayRef<OMPClause *> Clauses,
3587 Stmt *AssociatedStmt);
3588
3589 /// Creates an empty directive with the place for \a NumClauses
3590 /// clauses.
3591 ///
3592 /// \param C AST context.
3593 /// \param NumClauses Number of clauses.
3594 ///
3595 static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
3596 unsigned NumClauses, EmptyShell);
3597
3598 static bool classof(const Stmt *T) {
3599 return T->getStmtClass() == OMPTeamsDirectiveClass;
3600 }
3601};
3602
3603/// This represents '#pragma omp cancellation point' directive.
3604///
3605/// \code
3606/// #pragma omp cancellation point for
3607/// \endcode
3608///
3609/// In this example a cancellation point is created for innermost 'for' region.
3611 friend class ASTStmtReader;
3613 OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
3614 /// Build directive with the given start and end location.
3615 ///
3616 /// \param StartLoc Starting location of the directive kind.
3617 /// \param EndLoc Ending location of the directive.
3618 /// statements and child expressions.
3619 ///
3621 : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3622 llvm::omp::OMPD_cancellation_point, StartLoc,
3623 EndLoc) {}
3624
3625 /// Build an empty directive.
3627 : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3628 llvm::omp::OMPD_cancellation_point,
3630
3631 /// Set cancel region for current cancellation point.
3632 /// \param CR Cancellation region.
3633 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
3634
3635public:
3636 /// Creates directive.
3637 ///
3638 /// \param C AST context.
3639 /// \param StartLoc Starting location of the directive kind.
3640 /// \param EndLoc Ending Location of the directive.
3641 ///
3642 static OMPCancellationPointDirective *
3643 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3644 OpenMPDirectiveKind CancelRegion);
3645
3646 /// Creates an empty directive.
3647 ///
3648 /// \param C AST context.
3649 ///
3650 static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
3651 EmptyShell);
3652
3653 /// Get cancellation region for the current cancellation point.
3654 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
3655
3656 static bool classof(const Stmt *T) {
3657 return T->getStmtClass() == OMPCancellationPointDirectiveClass;
3658 }
3659};
3660
3661/// This represents '#pragma omp cancel' directive.
3662///
3663/// \code
3664/// #pragma omp cancel for
3665/// \endcode
3666///
3667/// In this example a cancel is created for innermost 'for' region.
3669 friend class ASTStmtReader;
3671 OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
3672 /// Build directive with the given start and end location.
3673 ///
3674 /// \param StartLoc Starting location of the directive kind.
3675 /// \param EndLoc Ending location of the directive.
3676 ///
3678 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3679 StartLoc, EndLoc) {}
3680
3681 /// Build an empty directive.
3682 ///
3683 explicit OMPCancelDirective()
3684 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3686
3687 /// Set cancel region for current cancellation point.
3688 /// \param CR Cancellation region.
3689 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
3690
3691public:
3692 /// Creates directive.
3693 ///
3694 /// \param C AST context.
3695 /// \param StartLoc Starting location of the directive kind.
3696 /// \param EndLoc Ending Location of the directive.
3697 /// \param Clauses List of clauses.
3698 ///
3699 static OMPCancelDirective *
3700 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3701 ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
3702
3703 /// Creates an empty directive.
3704 ///
3705 /// \param C AST context.
3706 /// \param NumClauses Number of clauses.
3707 ///
3708 static OMPCancelDirective *CreateEmpty(const ASTContext &C,
3709 unsigned NumClauses, EmptyShell);
3710
3711 /// Get cancellation region for the current cancellation point.
3712 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
3713
3714 static bool classof(const Stmt *T) {
3715 return T->getStmtClass() == OMPCancelDirectiveClass;
3716 }
3717};
3718
3719/// This represents '#pragma omp taskloop' directive.
3720///
3721/// \code
3722/// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
3723/// \endcode
3724/// In this example directive '#pragma omp taskloop' has clauses 'private'
3725/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
3726/// 'num_tasks' with expression 'num'.
3727///
3729 friend class ASTStmtReader;
3731 /// true if the construct has inner cancel directive.
3732 bool HasCancel = false;
3733
3734 /// Build directive with the given start and end location.
3735 ///
3736 /// \param StartLoc Starting location of the directive kind.
3737 /// \param EndLoc Ending location of the directive.
3738 /// \param CollapsedNum Number of collapsed nested loops.
3739 ///
3741 unsigned CollapsedNum)
3742 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3743 StartLoc, EndLoc, CollapsedNum) {}
3744
3745 /// Build an empty directive.
3746 ///
3747 /// \param CollapsedNum Number of collapsed nested loops.
3748 ///
3749 explicit OMPTaskLoopDirective(unsigned CollapsedNum)
3750 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3751 SourceLocation(), SourceLocation(), CollapsedNum) {}
3752
3753 /// Set cancel state.
3754 void setHasCancel(bool Has) { HasCancel = Has; }
3755
3756public:
3757 /// Creates directive with a list of \a Clauses.
3758 ///
3759 /// \param C AST context.
3760 /// \param StartLoc Starting location of the directive kind.
3761 /// \param EndLoc Ending Location of the directive.
3762 /// \param CollapsedNum Number of collapsed loops.
3763 /// \param Clauses List of clauses.
3764 /// \param AssociatedStmt Statement, associated with the directive.
3765 /// \param Exprs Helper expressions for CodeGen.
3766 /// \param HasCancel true if this directive has inner cancel directive.
3767 ///
3768 static OMPTaskLoopDirective *
3769 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3770 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3771 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
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 OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
3781 unsigned NumClauses,
3782 unsigned CollapsedNum, EmptyShell);
3783
3784 /// Return true if current directive has inner cancel directive.
3785 bool hasCancel() const { return HasCancel; }
3786
3787 static bool classof(const Stmt *T) {
3788 return T->getStmtClass() == OMPTaskLoopDirectiveClass;
3789 }
3790};
3791
3792/// This represents '#pragma omp taskloop simd' directive.
3793///
3794/// \code
3795/// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
3796/// \endcode
3797/// In this example directive '#pragma omp taskloop simd' has clauses 'private'
3798/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
3799/// 'num_tasks' with expression 'num'.
3800///
3802 friend class ASTStmtReader;
3804 /// Build directive with the given start and end location.
3805 ///
3806 /// \param StartLoc Starting location of the directive kind.
3807 /// \param EndLoc Ending location of the directive.
3808 /// \param CollapsedNum Number of collapsed nested loops.
3809 ///
3811 unsigned CollapsedNum)
3812 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3813 llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc,
3814 CollapsedNum) {}
3815
3816 /// Build an empty directive.
3817 ///
3818 /// \param CollapsedNum Number of collapsed nested loops.
3819 ///
3820 explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum)
3821 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3822 llvm::omp::OMPD_taskloop_simd, SourceLocation(),
3823 SourceLocation(), CollapsedNum) {}
3824
3825public:
3826 /// Creates directive with a list of \a Clauses.
3827 ///
3828 /// \param C AST context.
3829 /// \param StartLoc Starting location of the directive kind.
3830 /// \param EndLoc Ending Location of the directive.
3831 /// \param CollapsedNum Number of collapsed loops.
3832 /// \param Clauses List of clauses.
3833 /// \param AssociatedStmt Statement, associated with the directive.
3834 /// \param Exprs Helper expressions for CodeGen.
3835 ///
3836 static OMPTaskLoopSimdDirective *
3837 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3838 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3839 Stmt *AssociatedStmt, const HelperExprs &Exprs);
3840
3841 /// Creates an empty directive with the place
3842 /// for \a NumClauses clauses.
3843 ///
3844 /// \param C AST context.
3845 /// \param CollapsedNum Number of collapsed nested loops.
3846 /// \param NumClauses Number of clauses.
3847 ///
3848 static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
3849 unsigned NumClauses,
3850 unsigned CollapsedNum,
3851 EmptyShell);
3852
3853 static bool classof(const Stmt *T) {
3854 return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
3855 }
3856};
3857
3858/// This represents '#pragma omp master taskloop' directive.
3859///
3860/// \code
3861/// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num)
3862/// \endcode
3863/// In this example directive '#pragma omp master taskloop' has clauses
3864/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3865/// and 'num_tasks' with expression 'num'.
3866///
3868 friend class ASTStmtReader;
3870 /// true if the construct has inner cancel directive.
3871 bool HasCancel = false;
3872
3873 /// Build directive with the given start and end location.
3874 ///
3875 /// \param StartLoc Starting location of the directive kind.
3876 /// \param EndLoc Ending location of the directive.
3877 /// \param CollapsedNum Number of collapsed nested loops.
3878 ///
3880 unsigned CollapsedNum)
3881 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3882 llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc,
3883 CollapsedNum) {}
3884
3885 /// Build an empty directive.
3886 ///
3887 /// \param CollapsedNum Number of collapsed nested loops.
3888 ///
3889 explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum)
3890 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3891 llvm::omp::OMPD_master_taskloop, SourceLocation(),
3892 SourceLocation(), CollapsedNum) {}
3893
3894 /// Set cancel state.
3895 void setHasCancel(bool Has) { HasCancel = Has; }
3896
3897public:
3898 /// Creates directive with a list of \a Clauses.
3899 ///
3900 /// \param C AST context.
3901 /// \param StartLoc Starting location of the directive kind.
3902 /// \param EndLoc Ending Location of the directive.
3903 /// \param CollapsedNum Number of collapsed loops.
3904 /// \param Clauses List of clauses.
3905 /// \param AssociatedStmt Statement, associated with the directive.
3906 /// \param Exprs Helper expressions for CodeGen.
3907 /// \param HasCancel true if this directive has inner cancel directive.
3908 ///
3909 static OMPMasterTaskLoopDirective *
3910 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3911 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3912 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3913
3914 /// Creates an empty directive with the place
3915 /// for \a NumClauses clauses.
3916 ///
3917 /// \param C AST context.
3918 /// \param CollapsedNum Number of collapsed nested loops.
3919 /// \param NumClauses Number of clauses.
3920 ///
3921 static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
3922 unsigned NumClauses,
3923 unsigned CollapsedNum,
3924 EmptyShell);
3925
3926 /// Return true if current directive has inner cancel directive.
3927 bool hasCancel() const { return HasCancel; }
3928
3929 static bool classof(const Stmt *T) {
3930 return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass;
3931 }
3932};
3933
3934/// This represents '#pragma omp masked taskloop' directive.
3935///
3936/// \code
3937/// #pragma omp masked taskloop private(a,b) grainsize(val) num_tasks(num)
3938/// \endcode
3939/// In this example directive '#pragma omp masked taskloop' has clauses
3940/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3941/// and 'num_tasks' with expression 'num'.
3942///
3944 friend class ASTStmtReader;
3946 /// true if the construct has inner cancel directive.
3947 bool HasCancel = false;
3948
3949 /// Build directive with the given start and end location.
3950 ///
3951 /// \param StartLoc Starting location of the directive kind.
3952 /// \param EndLoc Ending location of the directive.
3953 /// \param CollapsedNum Number of collapsed nested loops.
3954 ///
3956 unsigned CollapsedNum)
3957 : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
3958 llvm::omp::OMPD_masked_taskloop, StartLoc, EndLoc,
3959 CollapsedNum) {}
3960
3961 /// Build an empty directive.
3962 ///
3963 /// \param CollapsedNum Number of collapsed nested loops.
3964 ///
3965 explicit OMPMaskedTaskLoopDirective(unsigned CollapsedNum)
3966 : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
3967 llvm::omp::OMPD_masked_taskloop, SourceLocation(),
3968 SourceLocation(), CollapsedNum) {}
3969
3970 /// Set cancel state.
3971 void setHasCancel(bool Has) { HasCancel = Has; }
3972
3973public:
3974 /// Creates directive with a list of \a Clauses.
3975 ///
3976 /// \param C AST context.
3977 /// \param StartLoc Starting location of the directive kind.
3978 /// \param EndLoc Ending Location of the directive.
3979 /// \param CollapsedNum Number of collapsed loops.
3980 /// \param Clauses List of clauses.
3981 /// \param AssociatedStmt Statement, associated with the directive.
3982 /// \param Exprs Helper expressions for CodeGen.
3983 /// \param HasCancel true if this directive has inner cancel directive.
3984 ///
3985 static OMPMaskedTaskLoopDirective *
3986 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3987 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3988 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3989
3990 /// Creates an empty directive with the place
3991 /// for \a 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 OMPMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
3998 unsigned NumClauses,
3999 unsigned CollapsedNum,
4000 EmptyShell);
4001
4002 /// Return true if current directive has inner cancel directive.
4003 bool hasCancel() const { return HasCancel; }
4004
4005 static bool classof(const Stmt *T) {
4006 return T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass;
4007 }
4008};
4009
4010/// This represents '#pragma omp master taskloop simd' directive.
4011///
4012/// \code
4013/// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num)
4014/// \endcode
4015/// In this example directive '#pragma omp master taskloop simd' has clauses
4016/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4017/// and 'num_tasks' with expression 'num'.
4018///
4020 friend class ASTStmtReader;
4022 /// Build directive with the given start and end location.
4023 ///
4024 /// \param StartLoc Starting location of the directive kind.
4025 /// \param EndLoc Ending location of the directive.
4026 /// \param CollapsedNum Number of collapsed nested loops.
4027 ///
4029 unsigned CollapsedNum)
4030 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
4031 llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc,
4032 CollapsedNum) {}
4033
4034 /// Build an empty directive.
4035 ///
4036 /// \param CollapsedNum Number of collapsed nested loops.
4037 ///
4038 explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum)
4039 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
4040 llvm::omp::OMPD_master_taskloop_simd, SourceLocation(),
4041 SourceLocation(), CollapsedNum) {}
4042
4043public:
4044 /// Creates directive with a list of \p Clauses.
4045 ///
4046 /// \param C AST context.
4047 /// \param StartLoc Starting location of the directive kind.
4048 /// \param EndLoc Ending Location of the directive.
4049 /// \param CollapsedNum Number of collapsed loops.
4050 /// \param Clauses List of clauses.
4051 /// \param AssociatedStmt Statement, associated with the directive.
4052 /// \param Exprs Helper expressions for CodeGen.
4053 ///
4054 static OMPMasterTaskLoopSimdDirective *
4055 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4056 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4057 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4058
4059 /// Creates an empty directive with the place for \p NumClauses clauses.
4060 ///
4061 /// \param C AST context.
4062 /// \param CollapsedNum Number of collapsed nested loops.
4063 /// \param NumClauses Number of clauses.
4064 ///
4065 static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
4066 unsigned NumClauses,
4067 unsigned CollapsedNum,
4068 EmptyShell);
4069
4070 static bool classof(const Stmt *T) {
4071 return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass;
4072 }
4073};
4074
4075/// This represents '#pragma omp masked taskloop simd' directive.
4076///
4077/// \code
4078/// #pragma omp masked taskloop simd private(a,b) grainsize(val) num_tasks(num)
4079/// \endcode
4080/// In this example directive '#pragma omp masked taskloop simd' has clauses
4081/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4082/// and 'num_tasks' with expression 'num'.
4083///
4085 friend class ASTStmtReader;
4087 /// Build directive with the given start and end location.
4088 ///
4089 /// \param StartLoc Starting location of the directive kind.
4090 /// \param EndLoc Ending location of the directive.
4091 /// \param CollapsedNum Number of collapsed nested loops.
4092 ///
4094 unsigned CollapsedNum)
4095 : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
4096 llvm::omp::OMPD_masked_taskloop_simd, StartLoc, EndLoc,
4097 CollapsedNum) {}
4098
4099 /// Build an empty directive.
4100 ///
4101 /// \param CollapsedNum Number of collapsed nested loops.
4102 ///
4103 explicit OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
4104 : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
4105 llvm::omp::OMPD_masked_taskloop_simd, SourceLocation(),
4106 SourceLocation(), CollapsedNum) {}
4107
4108public:
4109 /// Creates directive with a list of \p Clauses.
4110 ///
4111 /// \param C AST context.
4112 /// \param StartLoc Starting location of the directive kind.
4113 /// \param EndLoc Ending Location of the directive.
4114 /// \param CollapsedNum Number of collapsed loops.
4115 /// \param Clauses List of clauses.
4116 /// \param AssociatedStmt Statement, associated with the directive.
4117 /// \param Exprs Helper expressions for CodeGen.
4118 ///
4119 static OMPMaskedTaskLoopSimdDirective *
4120 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4121 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4122 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4123
4124 /// Creates an empty directive with the place for \p NumClauses clauses.
4125 ///
4126 /// \param C AST context.
4127 /// \param CollapsedNum Number of collapsed nested loops.
4128 /// \param NumClauses Number of clauses.
4129 ///
4130 static OMPMaskedTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
4131 unsigned NumClauses,
4132 unsigned CollapsedNum,
4133 EmptyShell);
4134
4135 static bool classof(const Stmt *T) {
4136 return T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass;
4137 }
4138};
4139
4140/// This represents '#pragma omp parallel master taskloop' directive.
4141///
4142/// \code
4143/// #pragma omp parallel master taskloop private(a,b) grainsize(val)
4144/// num_tasks(num)
4145/// \endcode
4146/// In this example directive '#pragma omp parallel master taskloop' has clauses
4147/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4148/// and 'num_tasks' with expression 'num'.
4149///
4151 friend class ASTStmtReader;
4153 /// true if the construct has inner cancel directive.
4154 bool HasCancel = false;
4155
4156 /// Build directive with the given start and end location.
4157 ///
4158 /// \param StartLoc Starting location of the directive kind.
4159 /// \param EndLoc Ending location of the directive.
4160 /// \param CollapsedNum Number of collapsed nested loops.
4161 ///
4163 SourceLocation EndLoc,
4164 unsigned CollapsedNum)
4165 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
4166 llvm::omp::OMPD_parallel_master_taskloop, StartLoc,
4167 EndLoc, CollapsedNum) {}
4168
4169 /// Build an empty directive.
4170 ///
4171 /// \param CollapsedNum Number of collapsed nested loops.
4172 ///
4173 explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum)
4174 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
4175 llvm::omp::OMPD_parallel_master_taskloop,
4176 SourceLocation(), SourceLocation(), CollapsedNum) {}
4177
4178 /// Set cancel state.
4179 void setHasCancel(bool Has) { HasCancel = Has; }
4180
4181public:
4182 /// Creates directive with a list of \a Clauses.
4183 ///
4184 /// \param C AST context.
4185 /// \param StartLoc Starting location of the directive kind.
4186 /// \param EndLoc Ending Location of the directive.
4187 /// \param CollapsedNum Number of collapsed loops.
4188 /// \param Clauses List of clauses.
4189 /// \param AssociatedStmt Statement, associated with the directive.
4190 /// \param Exprs Helper expressions for CodeGen.
4191 /// \param HasCancel true if this directive has inner cancel directive.
4192 ///
4193 static OMPParallelMasterTaskLoopDirective *
4194 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4195 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4196 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
4197
4198 /// Creates an empty directive with the place
4199 /// for \a NumClauses clauses.
4200 ///
4201 /// \param C AST context.
4202 /// \param CollapsedNum Number of collapsed nested loops.
4203 /// \param NumClauses Number of clauses.
4204 ///
4205 static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
4206 unsigned NumClauses,
4207 unsigned CollapsedNum,
4208 EmptyShell);
4209
4210 /// Return true if current directive has inner cancel directive.
4211 bool hasCancel() const { return HasCancel; }
4212
4213 static bool classof(const Stmt *T) {
4214 return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass;
4215 }
4216};
4217
4218/// This represents '#pragma omp parallel masked taskloop' directive.
4219///
4220/// \code
4221/// #pragma omp parallel masked taskloop private(a,b) grainsize(val)
4222/// num_tasks(num)
4223/// \endcode
4224/// In this example directive '#pragma omp parallel masked taskloop' has clauses
4225/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4226/// and 'num_tasks' with expression 'num'.
4227///
4229 friend class ASTStmtReader;
4231 /// true if the construct has inner cancel directive.
4232 bool HasCancel = false;
4233
4234 /// Build directive with the given start and end location.
4235 ///
4236 /// \param StartLoc Starting location of the directive kind.
4237 /// \param EndLoc Ending location of the directive.
4238 /// \param CollapsedNum Number of collapsed nested loops.
4239 ///
4241 SourceLocation EndLoc,
4242 unsigned CollapsedNum)
4243 : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
4244 llvm::omp::OMPD_parallel_masked_taskloop, StartLoc,
4245 EndLoc, CollapsedNum) {}
4246
4247 /// Build an empty directive.
4248 ///
4249 /// \param CollapsedNum Number of collapsed nested loops.
4250 ///
4251 explicit OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum)
4252 : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
4253 llvm::omp::OMPD_parallel_masked_taskloop,
4254 SourceLocation(), SourceLocation(), CollapsedNum) {}
4255
4256 /// Set cancel state.
4257 void setHasCancel(bool Has) { HasCancel = Has; }
4258
4259public:
4260 /// Creates directive with a list of \a Clauses.
4261 ///
4262 /// \param C AST context.
4263 /// \param StartLoc Starting location of the directive kind.
4264 /// \param EndLoc Ending Location of the directive.
4265 /// \param CollapsedNum Number of collapsed loops.
4266 /// \param Clauses List of clauses.
4267 /// \param AssociatedStmt Statement, associated with the directive.
4268 /// \param Exprs Helper expressions for CodeGen.
4269 /// \param HasCancel true if this directive has inner cancel directive.
4270 ///
4271 static OMPParallelMaskedTaskLoopDirective *
4272 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4273 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4274 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
4275
4276 /// Creates an empty directive with the place
4277 /// for \a NumClauses clauses.
4278 ///
4279 /// \param C AST context.
4280 /// \param CollapsedNum Number of collapsed nested loops.
4281 /// \param NumClauses Number of clauses.
4282 ///
4283 static OMPParallelMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
4284 unsigned NumClauses,
4285 unsigned CollapsedNum,
4286 EmptyShell);
4287
4288 /// Return true if current directive has inner cancel directive.
4289 bool hasCancel() const { return HasCancel; }
4290
4291 static bool classof(const Stmt *T) {
4292 return T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass;
4293 }
4294};
4295
4296/// This represents '#pragma omp parallel master taskloop simd' directive.
4297///
4298/// \code
4299/// #pragma omp parallel master taskloop simd private(a,b) grainsize(val)
4300/// num_tasks(num)
4301/// \endcode
4302/// In this example directive '#pragma omp parallel master taskloop simd' has
4303/// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
4304/// expression 'val' and 'num_tasks' with expression 'num'.
4305///
4307 friend class ASTStmtReader;
4309 /// Build directive with the given start and end location.
4310 ///
4311 /// \param StartLoc Starting location of the directive kind.
4312 /// \param EndLoc Ending location of the directive.
4313 /// \param CollapsedNum Number of collapsed nested loops.
4314 ///
4316 SourceLocation EndLoc,
4317 unsigned CollapsedNum)
4318 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
4319 llvm::omp::OMPD_parallel_master_taskloop_simd,
4320 StartLoc, EndLoc, CollapsedNum) {}
4321
4322 /// Build an empty directive.
4323 ///
4324 /// \param CollapsedNum Number of collapsed nested loops.
4325 ///
4326 explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum)
4327 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
4328 llvm::omp::OMPD_parallel_master_taskloop_simd,
4329 SourceLocation(), SourceLocation(), CollapsedNum) {}
4330
4331public:
4332 /// Creates directive with a list of \p Clauses.
4333 ///
4334 /// \param C AST context.
4335 /// \param StartLoc Starting location of the directive kind.
4336 /// \param EndLoc Ending Location of the directive.
4337 /// \param CollapsedNum Number of collapsed loops.
4338 /// \param Clauses List of clauses.
4339 /// \param AssociatedStmt Statement, associated with the directive.
4340 /// \param Exprs Helper expressions for CodeGen.
4341 ///
4342 static OMPParallelMasterTaskLoopSimdDirective *
4343 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4344 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4345 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4346
4347 /// Creates an empty directive with the place
4348 /// for \a NumClauses clauses.
4349 ///
4350 /// \param C AST context.
4351 /// \param CollapsedNum Number of collapsed nested loops.
4352 /// \param NumClauses Number of clauses.
4353 ///
4354 static OMPParallelMasterTaskLoopSimdDirective *
4355 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4356 EmptyShell);
4357
4358 static bool classof(const Stmt *T) {
4359 return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass;
4360 }
4361};
4362
4363/// This represents '#pragma omp parallel masked taskloop simd' directive.
4364///
4365/// \code
4366/// #pragma omp parallel masked taskloop simd private(a,b) grainsize(val)
4367/// num_tasks(num)
4368/// \endcode
4369/// In this example directive '#pragma omp parallel masked taskloop simd' has
4370/// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
4371/// expression 'val' and 'num_tasks' with expression 'num'.
4372///
4374 friend class ASTStmtReader;
4376 /// Build directive with the given start and end location.
4377 ///
4378 /// \param StartLoc Starting location of the directive kind.
4379 /// \param EndLoc Ending location of the directive.
4380 /// \param CollapsedNum Number of collapsed nested loops.
4381 ///
4383 SourceLocation EndLoc,
4384 unsigned CollapsedNum)
4385 : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
4386 llvm::omp::OMPD_parallel_masked_taskloop_simd,
4387 StartLoc, EndLoc, CollapsedNum) {}
4388
4389 /// Build an empty directive.
4390 ///
4391 /// \param CollapsedNum Number of collapsed nested loops.
4392 ///
4393 explicit OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
4394 : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
4395 llvm::omp::OMPD_parallel_masked_taskloop_simd,
4396 SourceLocation(), SourceLocation(), CollapsedNum) {}
4397
4398public:
4399 /// Creates directive with a list of \p Clauses.
4400 ///
4401 /// \param C AST context.
4402 /// \param StartLoc Starting location of the directive kind.
4403 /// \param EndLoc Ending Location of the directive.
4404 /// \param CollapsedNum Number of collapsed loops.
4405 /// \param Clauses List of clauses.
4406 /// \param AssociatedStmt Statement, associated with the directive.
4407 /// \param Exprs Helper expressions for CodeGen.
4408 ///
4409 static OMPParallelMaskedTaskLoopSimdDirective *
4410 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4411 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4412 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4413
4414 /// Creates an empty directive with the place
4415 /// for \a NumClauses clauses.
4416 ///
4417 /// \param C AST context.
4418 /// \param CollapsedNum Number of collapsed nested loops.
4419 /// \param NumClauses Number of clauses.
4420 ///
4421 static OMPParallelMaskedTaskLoopSimdDirective *
4422 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4423 EmptyShell);
4424
4425 static bool classof(const Stmt *T) {
4426 return T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass;
4427 }
4428};
4429
4430/// This represents '#pragma omp distribute' directive.
4431///
4432/// \code
4433/// #pragma omp distribute private(a,b)
4434/// \endcode
4435/// In this example directive '#pragma omp distribute' has clauses 'private'
4436/// with the variables 'a' and 'b'
4437///
4439 friend class ASTStmtReader;
4441
4442 /// Build directive with the given start and end location.
4443 ///
4444 /// \param StartLoc Starting location of the directive kind.
4445 /// \param EndLoc Ending location of the directive.
4446 /// \param CollapsedNum Number of collapsed nested loops.
4447 ///
4449 unsigned CollapsedNum)
4450 : OMPLoopDirective(OMPDistributeDirectiveClass,
4451 llvm::omp::OMPD_distribute, StartLoc, EndLoc,
4452 CollapsedNum) {}
4453
4454 /// Build an empty directive.
4455 ///
4456 /// \param CollapsedNum Number of collapsed nested loops.
4457 ///
4458 explicit OMPDistributeDirective(unsigned CollapsedNum)
4459 : OMPLoopDirective(OMPDistributeDirectiveClass,
4460 llvm::omp::OMPD_distribute, SourceLocation(),
4461 SourceLocation(), CollapsedNum) {}
4462
4463public:
4464 /// Creates directive with a list of \a Clauses.
4465 ///
4466 /// \param C AST context.
4467 /// \param StartLoc Starting location of the directive kind.
4468 /// \param EndLoc Ending Location of the directive.
4469 /// \param CollapsedNum Number of collapsed loops.
4470 /// \param Clauses List of clauses.
4471 /// \param AssociatedStmt Statement, associated with the directive.
4472 /// \param Exprs Helper expressions for CodeGen.
4473 ///
4474 static OMPDistributeDirective *
4475 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4476 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4477 Stmt *AssociatedStmt, const HelperExprs &Exprs,
4478 OpenMPDirectiveKind ParamPrevMappedDirective);
4479
4480 /// Creates an empty directive with the place
4481 /// for \a NumClauses clauses.
4482 ///
4483 /// \param C AST context.
4484 /// \param CollapsedNum Number of collapsed nested loops.
4485 /// \param NumClauses Number of clauses.
4486 ///
4487 static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
4488 unsigned NumClauses,
4489 unsigned CollapsedNum, EmptyShell);
4490
4491 static bool classof(const Stmt *T) {
4492 return T->getStmtClass() == OMPDistributeDirectiveClass;
4493 }
4494};
4495
4496/// This represents '#pragma omp target update' directive.
4497///
4498/// \code
4499/// #pragma omp target update to(a) from(b) device(1)
4500/// \endcode
4501/// In this example directive '#pragma omp target update' has clause 'to' with
4502/// argument 'a', clause 'from' with argument 'b' and clause 'device' with
4503/// argument '1'.
4504///
4506 friend class ASTStmtReader;
4508 /// Build directive with the given start and end location.
4509 ///
4510 /// \param StartLoc Starting location of the directive kind.
4511 /// \param EndLoc Ending Location of the directive.
4512 ///
4514 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
4515 llvm::omp::OMPD_target_update, StartLoc,
4516 EndLoc) {}
4517
4518 /// Build an empty directive.
4519 ///
4520 explicit OMPTargetUpdateDirective()
4521 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
4522 llvm::omp::OMPD_target_update, SourceLocation(),
4523 SourceLocation()) {}
4524
4525public:
4526 /// Creates directive with a list of \a Clauses.
4527 ///
4528 /// \param C AST context.
4529 /// \param StartLoc Starting location of the directive kind.
4530 /// \param EndLoc Ending Location of the directive.
4531 /// \param Clauses List of clauses.
4532 /// \param AssociatedStmt Statement, associated with the directive.
4533 ///
4534 static OMPTargetUpdateDirective *
4535 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4536 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
4537
4538 /// Creates an empty directive with the place for \a NumClauses
4539 /// clauses.
4540 ///
4541 /// \param C AST context.
4542 /// \param NumClauses The number of clauses.
4543 ///
4544 static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C,
4545 unsigned NumClauses, EmptyShell);
4546
4547 static bool classof(const Stmt *T) {
4548 return T->getStmtClass() == OMPTargetUpdateDirectiveClass;
4549 }
4550};
4551
4552/// This represents '#pragma omp distribute parallel for' composite
4553/// directive.
4554///
4555/// \code
4556/// #pragma omp distribute parallel for private(a,b)
4557/// \endcode
4558/// In this example directive '#pragma omp distribute parallel for' has clause
4559/// 'private' with the variables 'a' and 'b'
4560///
4562 friend class ASTStmtReader;
4564 /// true if the construct has inner cancel directive.
4565 bool HasCancel = false;
4566
4567 /// Build directive with the given start and end location.
4568 ///
4569 /// \param StartLoc Starting location of the directive kind.
4570 /// \param EndLoc Ending location of the directive.
4571 /// \param CollapsedNum Number of collapsed nested loops.
4572 ///
4574 SourceLocation EndLoc,
4575 unsigned CollapsedNum)
4576 : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4577 llvm::omp::OMPD_distribute_parallel_for, StartLoc,
4578 EndLoc, CollapsedNum) {}
4579
4580 /// Build an empty directive.
4581 ///
4582 /// \param CollapsedNum Number of collapsed nested loops.
4583 ///
4584 explicit OMPDistributeParallelForDirective(unsigned CollapsedNum)
4585 : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4586 llvm::omp::OMPD_distribute_parallel_for,
4587 SourceLocation(), SourceLocation(), CollapsedNum) {}
4588
4589 /// Sets special task reduction descriptor.
4590 void setTaskReductionRefExpr(Expr *E) {
4591 Data->getChildren()[numLoopChildren(
4592 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E;
4593 }
4594
4595 /// Set cancel state.
4596 void setHasCancel(bool Has) { HasCancel = Has; }
4597
4598public:
4599 /// Creates directive with a list of \a Clauses.
4600 ///
4601 /// \param C AST context.
4602 /// \param StartLoc Starting location of the directive kind.
4603 /// \param EndLoc Ending Location of the directive.
4604 /// \param CollapsedNum Number of collapsed loops.
4605 /// \param Clauses List of clauses.
4606 /// \param AssociatedStmt Statement, associated with the directive.
4607 /// \param Exprs Helper expressions for CodeGen.
4608 /// \param TaskRedRef Task reduction special reference expression to handle
4609 /// taskgroup descriptor.
4610 /// \param HasCancel true if this directive has inner cancel directive.
4611 ///
4612 static OMPDistributeParallelForDirective *
4613 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4614 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4615 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
4616 bool HasCancel);
4617
4618 /// Creates an empty directive with the place
4619 /// for \a NumClauses clauses.
4620 ///
4621 /// \param C AST context.
4622 /// \param CollapsedNum Number of collapsed nested loops.
4623 /// \param NumClauses Number of clauses.
4624 ///
4625 static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C,
4626 unsigned NumClauses,
4627 unsigned CollapsedNum,
4628 EmptyShell);
4629
4630 /// Returns special task reduction reference expression.
4632 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
4633 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]);
4634 }
4636 return const_cast<OMPDistributeParallelForDirective *>(this)
4638 }
4639
4640 /// Return true if current directive has inner cancel directive.
4641 bool hasCancel() const { return HasCancel; }
4642
4643 static bool classof(const Stmt *T) {
4644 return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
4645 }
4646};
4647
4648/// This represents '#pragma omp distribute parallel for simd' composite
4649/// directive.
4650///
4651/// \code
4652/// #pragma omp distribute parallel for simd private(x)
4653/// \endcode
4654/// In this example directive '#pragma omp distribute parallel for simd' has
4655/// clause 'private' with the variables 'x'
4656///
4658 friend class ASTStmtReader;
4660
4661 /// Build directive with the given start and end location.
4662 ///
4663 /// \param StartLoc Starting location of the directive kind.
4664 /// \param EndLoc Ending location of the directive.
4665 /// \param CollapsedNum Number of collapsed nested loops.
4666 ///
4668 SourceLocation EndLoc,
4669 unsigned CollapsedNum)
4670 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4671 llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc,
4672 EndLoc, CollapsedNum) {}
4673
4674 /// Build an empty directive.
4675 ///
4676 /// \param CollapsedNum Number of collapsed nested loops.
4677 ///
4678 explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum)
4679 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4680 llvm::omp::OMPD_distribute_parallel_for_simd,
4681 SourceLocation(), SourceLocation(), CollapsedNum) {}
4682
4683public:
4684 /// Creates directive with a list of \a Clauses.
4685 ///
4686 /// \param C AST context.
4687 /// \param StartLoc Starting location of the directive kind.
4688 /// \param EndLoc Ending Location of the directive.
4689 /// \param CollapsedNum Number of collapsed loops.
4690 /// \param Clauses List of clauses.
4691 /// \param AssociatedStmt Statement, associated with the directive.
4692 /// \param Exprs Helper expressions for CodeGen.
4693 ///
4694 static OMPDistributeParallelForSimdDirective *Create(
4695 const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4696 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4697 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4698
4699 /// Creates an empty directive with the place for \a NumClauses clauses.
4700 ///
4701 /// \param C AST context.
4702 /// \param CollapsedNum Number of collapsed nested loops.
4703 /// \param NumClauses Number of clauses.
4704 ///
4705 static OMPDistributeParallelForSimdDirective *CreateEmpty(
4706 const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4707 EmptyShell);
4708
4709 static bool classof(const Stmt *T) {
4710 return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass;
4711 }
4712};
4713
4714/// This represents '#pragma omp distribute simd' composite directive.
4715///
4716/// \code
4717/// #pragma omp distribute simd private(x)
4718/// \endcode
4719/// In this example directive '#pragma omp distribute simd' has clause
4720/// 'private' with the variables 'x'
4721///
4723 friend class ASTStmtReader;
4725
4726 /// Build directive with the given start and end location.
4727 ///
4728 /// \param StartLoc Starting location of the directive kind.
4729 /// \param EndLoc Ending location of the directive.
4730 /// \param CollapsedNum Number of collapsed nested loops.
4731 ///
4733 unsigned CollapsedNum)
4734 : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4735 llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc,
4736 CollapsedNum) {}
4737
4738 /// Build an empty directive.
4739 ///
4740 /// \param CollapsedNum Number of collapsed nested loops.
4741 ///
4742 explicit OMPDistributeSimdDirective(unsigned CollapsedNum)
4743 : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4744 llvm::omp::OMPD_distribute_simd, SourceLocation(),
4745 SourceLocation(), CollapsedNum) {}
4746
4747public:
4748 /// Creates directive with a list of \a Clauses.
4749 ///
4750 /// \param C AST context.
4751 /// \param StartLoc Starting location of the directive kind.
4752 /// \param EndLoc Ending Location of the directive.
4753 /// \param CollapsedNum Number of collapsed loops.
4754 /// \param Clauses List of clauses.
4755 /// \param AssociatedStmt Statement, associated with the directive.
4756 /// \param Exprs Helper expressions for CodeGen.
4757 ///
4758 static OMPDistributeSimdDirective *
4759 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4760 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4761 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4762
4763 /// Creates an empty directive with the place for \a NumClauses clauses.
4764 ///
4765 /// \param C AST context.
4766 /// \param CollapsedNum Number of collapsed nested loops.
4767 /// \param NumClauses Number of clauses.
4768 ///
4769 static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C,
4770 unsigned NumClauses,
4771 unsigned CollapsedNum,
4772 EmptyShell);
4773
4774 static bool classof(const Stmt *T) {
4775 return T->getStmtClass() == OMPDistributeSimdDirectiveClass;
4776 }
4777};
4778
4779/// This represents '#pragma omp target parallel for simd' directive.
4780///
4781/// \code
4782/// #pragma omp target parallel for simd private(a) map(b) safelen(c)
4783/// \endcode
4784/// In this example directive '#pragma omp target parallel for simd' has clauses
4785/// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen'
4786/// with the variable 'c'.
4787///
4789 friend class ASTStmtReader;
4791
4792 /// Build directive with the given start and end location.
4793 ///
4794 /// \param StartLoc Starting location of the directive kind.
4795 /// \param EndLoc Ending location of the directive.
4796 /// \param CollapsedNum Number of collapsed nested loops.
4797 ///
4799 SourceLocation EndLoc,
4800 unsigned CollapsedNum)
4801 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4802 llvm::omp::OMPD_target_parallel_for_simd, StartLoc,
4803 EndLoc, CollapsedNum) {}
4804
4805 /// Build an empty directive.
4806 ///
4807 /// \param CollapsedNum Number of collapsed nested loops.
4808 ///
4809 explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum)
4810 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4811 llvm::omp::OMPD_target_parallel_for_simd,
4812 SourceLocation(), SourceLocation(), CollapsedNum) {}
4813
4814public:
4815 /// Creates directive with a list of \a Clauses.
4816 ///
4817 /// \param C AST context.
4818 /// \param StartLoc Starting location of the directive kind.
4819 /// \param EndLoc Ending Location of the directive.
4820 /// \param CollapsedNum Number of collapsed loops.
4821 /// \param Clauses List of clauses.
4822 /// \param AssociatedStmt Statement, associated with the directive.
4823 /// \param Exprs Helper expressions for CodeGen.
4824 ///
4825 static OMPTargetParallelForSimdDirective *
4826 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4827 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4828 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4829
4830 /// Creates an empty directive with the place for \a NumClauses clauses.
4831 ///
4832 /// \param C AST context.
4833 /// \param CollapsedNum Number of collapsed nested loops.
4834 /// \param NumClauses Number of clauses.
4835 ///
4836 static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C,
4837 unsigned NumClauses,
4838 unsigned CollapsedNum,
4839 EmptyShell);
4840
4841 static bool classof(const Stmt *T) {
4842 return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
4843 }
4844};
4845
4846/// This represents '#pragma omp target simd' directive.
4847///
4848/// \code
4849/// #pragma omp target simd private(a) map(b) safelen(c)
4850/// \endcode
4851/// In this example directive '#pragma omp target simd' has clauses 'private'
4852/// with the variable 'a', 'map' with the variable 'b' and 'safelen' with
4853/// the variable 'c'.
4854///
4856 friend class ASTStmtReader;
4858
4859 /// Build directive with the given start and end location.
4860 ///
4861 /// \param StartLoc Starting location of the directive kind.
4862 /// \param EndLoc Ending location of the directive.
4863 /// \param CollapsedNum Number of collapsed nested loops.
4864 ///
4866 unsigned CollapsedNum)
4867 : OMPLoopDirective(OMPTargetSimdDirectiveClass,
4868 llvm::omp::OMPD_target_simd, StartLoc, EndLoc,
4869 CollapsedNum) {}
4870
4871 /// Build an empty directive.
4872