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