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