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
17#include "clang/AST/ASTContext.h"
18#include "clang/AST/Expr.h"
19#include "clang/AST/OpenMPClause.h"
20#include "clang/AST/Stmt.h"
21#include "clang/AST/StmtCXX.h"
22#include "clang/Basic/OpenMPKinds.h"
23#include "clang/Basic/SourceLocation.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.
176 static OMPCanonicalLoop *createEmpty(const ASTContext &Ctx) {
177 return new (Ctx) OMPCanonicalLoop();
178 }
179
180 static bool classof(const Stmt *S) {
181 return S->getStmtClass() == StmtClass::OMPCanonicalLoopClass;
182 }
183
184 SourceLocation getBeginLoc() const { return getLoopStmt()->getBeginLoc(); }
185 SourceLocation getEndLoc() const { return getLoopStmt()->getEndLoc(); }
186
187 /// Return this AST node's children.
188 /// @{
189 child_range children() {
190 return child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1);
191 }
192 const_child_range children() const {
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 /// @{
215 CapturedStmt *getDistanceFunc() {
216 return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]);
217 }
218 const CapturedStmt *getDistanceFunc() const {
219 return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]);
220 }
221 void setDistanceFunc(CapturedStmt *S) {
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 /// @{
236 CapturedStmt *getLoopVarFunc() {
237 return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]);
238 }
239 const CapturedStmt *getLoopVarFunc() const {
240 return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]);
241 }
242 void setLoopVarFunc(CapturedStmt *S) {
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 /// @{
250 DeclRefExpr *getLoopVarRef() {
251 return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]);
252 }
253 const DeclRefExpr *getLoopVarRef() const {
254 return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]);
255 }
256 void setLoopVarRef(DeclRefExpr *E) {
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///
266class OMPExecutableDirective : public Stmt {
267 friend class ASTStmtReader;
268 friend class ASTStmtWriter;
269
270 /// Kind of the directive.
271 OpenMPDirectiveKind Kind = llvm::omp::OMPD_unknown;
272 /// Starting location of the directive (directive keyword).
273 SourceLocation StartLoc;
274 /// Ending location of the directive.
275 SourceLocation EndLoc;
276
277 /// Get the clauses storage.
278 MutableArrayRef<OMPClause *> getClauses() {
279 if (!Data)
280 return std::nullopt;
281 return Data->getClauses();
282 }
283
284protected:
285 /// Data, associated with the directive.
286 OMPChildren *Data = nullptr;
287
288 /// Build instance of directive of class \a K.
289 ///
290 /// \param SC Statement class.
291 /// \param K Kind of OpenMP directive.
292 /// \param StartLoc Starting location of the directive (directive keyword).
293 /// \param EndLoc Ending location of the directive.
294 ///
295 OMPExecutableDirective(StmtClass SC, OpenMPDirectiveKind K,
296 SourceLocation StartLoc, SourceLocation EndLoc)
297 : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
298 EndLoc(std::move(EndLoc)) {}
299
300 template <typename T, typename... Params>
301 static T *createDirective(const ASTContext &C, ArrayRef<OMPClause *> Clauses,
302 Stmt *AssociatedStmt, unsigned NumChildren,
303 Params &&... P) {
304 void *Mem =
305 C.Allocate(sizeof(T) + OMPChildren::size(Clauses.size(), AssociatedStmt,
306 NumChildren),
307 alignof(T));
308
309 auto *Data = OMPChildren::Create(reinterpret_cast<T *>(Mem) + 1, Clauses,
310 AssociatedStmt, NumChildren);
311 auto *Inst = new (Mem) T(std::forward<Params>(P)...);
312 Inst->Data = Data;
313 return Inst;
314 }
315
316 template <typename T, typename... Params>
317 static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses,
318 bool HasAssociatedStmt, unsigned NumChildren,
319 Params &&... P) {
320 void *Mem =
321 C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt,
322 NumChildren),
323 alignof(T));
324 auto *Data =
325 OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses,
326 HasAssociatedStmt, NumChildren);
327 auto *Inst = new (Mem) T(std::forward<Params>(P)...);
328 Inst->Data = Data;
329 return Inst;
330 }
331
332 template <typename T>
333 static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses,
334 bool HasAssociatedStmt = false,
335 unsigned NumChildren = 0) {
336 void *Mem =
337 C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt,
338 NumChildren),
339 alignof(T));
340 auto *Data =
341 OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses,
342 HasAssociatedStmt, NumChildren);
343 auto *Inst = new (Mem) T;
344 Inst->Data = Data;
345 return Inst;
346 }
347
348public:
349 /// Iterates over expressions/statements used in the construct.
350 class used_clauses_child_iterator
351 : public llvm::iterator_adaptor_base<
352 used_clauses_child_iterator, ArrayRef<OMPClause *>::iterator,
353 std::forward_iterator_tag, Stmt *, ptrdiff_t, Stmt *, Stmt *> {
354 ArrayRef<OMPClause *>::iterator End;
355 OMPClause::child_iterator ChildI, ChildEnd;
356
357 void MoveToNext() {
358 if (ChildI != ChildEnd)
359 return;
360 while (this->I != End) {
361 ++this->I;
362 if (this->I != End) {
363 ChildI = (*this->I)->used_children().begin();
364 ChildEnd = (*this->I)->used_children().end();
365 if (ChildI != ChildEnd)
366 return;
367 }
368 }
369 }
370
371 public:
372 explicit used_clauses_child_iterator(ArrayRef<OMPClause *> Clauses)
373 : used_clauses_child_iterator::iterator_adaptor_base(Clauses.begin()),
374 End(Clauses.end()) {
375 if (this->I != End) {
376 ChildI = (*this->I)->used_children().begin();
377 ChildEnd = (*this->I)->used_children().end();
378 MoveToNext();
379 }
380 }
381 Stmt *operator*() const { return *ChildI; }
382 Stmt *operator->() const { return **this; }
383
384 used_clauses_child_iterator &operator++() {
385 ++ChildI;
386 if (ChildI != ChildEnd)
387 return *this;
388 if (this->I != End) {
389 ++this->I;
390 if (this->I != End) {
391 ChildI = (*this->I)->used_children().begin();
392 ChildEnd = (*this->I)->used_children().end();
393 }
394 }
395 MoveToNext();
396 return *this;
397 }
398 };
399
400 static llvm::iterator_range<used_clauses_child_iterator>
401 used_clauses_children(ArrayRef<OMPClause *> Clauses) {
402 return {
403 used_clauses_child_iterator(Clauses),
404 used_clauses_child_iterator(llvm::ArrayRef(Clauses.end(), (size_t)0))};
405 }
406
407 /// Iterates over a filtered subrange of clauses applied to a
408 /// directive.
409 ///
410 /// This iterator visits only clauses of type SpecificClause.
411 template <typename SpecificClause>
412 class specific_clause_iterator
413 : public llvm::iterator_adaptor_base<
414 specific_clause_iterator<SpecificClause>,
415 ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag,
416 const SpecificClause *, ptrdiff_t, const SpecificClause *,
417 const SpecificClause *> {
418 ArrayRef<OMPClause *>::const_iterator End;
419
420 void SkipToNextClause() {
421 while (this->I != End && !isa<SpecificClause>(*this->I))
422 ++this->I;
423 }
424
425 public:
426 explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses)
427 : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()),
428 End(Clauses.end()) {
429 SkipToNextClause();
430 }
431
432 const SpecificClause *operator*() const {
433 return cast<SpecificClause>(*this->I);
434 }
435 const SpecificClause *operator->() const { return **this; }
436
437 specific_clause_iterator &operator++() {
438 ++this->I;
439 SkipToNextClause();
440 return *this;
441 }
442 };
443
444 template <typename SpecificClause>
445 static llvm::iterator_range<specific_clause_iterator<SpecificClause>>
446 getClausesOfKind(ArrayRef<OMPClause *> Clauses) {
447 return {specific_clause_iterator<SpecificClause>(Clauses),
448 specific_clause_iterator<SpecificClause>(
449 llvm::ArrayRef(Clauses.end(), (size_t)0))};
450 }
451
452 template <typename SpecificClause>
453 llvm::iterator_range<specific_clause_iterator<SpecificClause>>
454 getClausesOfKind() const {
455 return getClausesOfKind<SpecificClause>(clauses());
456 }
457
458 /// Gets a single clause of the specified kind associated with the
459 /// current directive iff there is only one clause of this kind (and assertion
460 /// is fired if there is more than one clause is associated with the
461 /// directive). Returns nullptr if no clause of this kind is associated with
462 /// the directive.
463 template <typename SpecificClause>
464 static const SpecificClause *getSingleClause(ArrayRef<OMPClause *> Clauses) {
465 auto ClausesOfKind = getClausesOfKind<SpecificClause>(Clauses);
466
467 if (ClausesOfKind.begin() != ClausesOfKind.end()) {
468 assert(std::next(ClausesOfKind.begin()) == ClausesOfKind.end() &&
469 "There are at least 2 clauses of the specified kind");
470 return *ClausesOfKind.begin();
471 }
472 return nullptr;
473 }
474
475 template <typename SpecificClause>
476 const SpecificClause *getSingleClause() const {
477 return getSingleClause<SpecificClause>(clauses());
478 }
479
480 /// Returns true if the current directive has one or more clauses of a
481 /// specific kind.
482 template <typename SpecificClause>
483 bool hasClausesOfKind() const {
484 auto Clauses = getClausesOfKind<SpecificClause>();
485 return Clauses.begin() != Clauses.end();
486 }
487
488 /// Returns starting location of directive kind.
489 SourceLocation getBeginLoc() const { return StartLoc; }
490 /// Returns ending location of directive.
491 SourceLocation getEndLoc() const { return EndLoc; }
492
493 /// Set starting location of directive kind.
494 ///
495 /// \param Loc New starting location of directive.
496 ///
497 void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
498 /// Set ending location of directive.
499 ///
500 /// \param Loc New ending location of directive.
501 ///
502 void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
503
504 /// Get number of clauses.
505 unsigned getNumClauses() const {
506 if (!Data)
507 return 0;
508 return Data->getNumClauses();
509 }
510
511 /// Returns specified clause.
512 ///
513 /// \param I Number of clause.
514 ///
515 OMPClause *getClause(unsigned I) const { return clauses()[I]; }
516
517 /// Returns true if directive has associated statement.
518 bool hasAssociatedStmt() const { return Data && Data->hasAssociatedStmt(); }
519
520 /// Returns statement associated with the directive.
521 const Stmt *getAssociatedStmt() const {
522 return const_cast<OMPExecutableDirective *>(this)->getAssociatedStmt();
523 }
524 Stmt *getAssociatedStmt() {
525 assert(hasAssociatedStmt() &&
526 "Expected directive with the associated statement.");
527 return Data->getAssociatedStmt();
528 }
529
530 /// Returns the captured statement associated with the
531 /// component region within the (combined) directive.
532 ///
533 /// \param RegionKind Component region kind.
534 const CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const {
535 assert(hasAssociatedStmt() &&
536 "Expected directive with the associated statement.");
537 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
538 getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
539 return Data->getCapturedStmt(RegionKind, CaptureRegions);
540 }
541
542 /// Get innermost captured statement for the construct.
543 CapturedStmt *getInnermostCapturedStmt() {
544 assert(hasAssociatedStmt() &&
545 "Expected directive with the associated statement.");
546 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
547 getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
548 return Data->getInnermostCapturedStmt(CaptureRegions);
549 }
550
551 const CapturedStmt *getInnermostCapturedStmt() const {
552 return const_cast<OMPExecutableDirective *>(this)
553 ->getInnermostCapturedStmt();
554 }
555
556 OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
557
558 static bool classof(const Stmt *S) {
559 return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
560 S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
561 }
562
563 child_range children() {
564 if (!Data)
565 return child_range(child_iterator(), child_iterator());
566 return Data->getAssociatedStmtAsRange();
567 }
568
569 const_child_range children() const {
570 return const_cast<OMPExecutableDirective *>(this)->children();
571 }
572
573 ArrayRef<OMPClause *> clauses() const {
574 if (!Data)
575 return std::nullopt;
576 return Data->getClauses();
577 }
578
579 /// Returns whether or not this is a Standalone directive.
580 ///
581 /// Stand-alone directives are executable directives
582 /// that have no associated user code.
583 bool isStandaloneDirective() const;
584
585 /// Returns the AST node representing OpenMP structured-block of this
586 /// OpenMP executable directive,
587 /// Prerequisite: Executable Directive must not be Standalone directive.
588 const Stmt *getStructuredBlock() const {
589 return const_cast<OMPExecutableDirective *>(this)->getStructuredBlock();
590 }
591 Stmt *getStructuredBlock();
592
593 const Stmt *getRawStmt() const {
594 return const_cast<OMPExecutableDirective *>(this)->getRawStmt();
595 }
596 Stmt *getRawStmt() {
597 assert(hasAssociatedStmt() &&
598 "Expected directive with the associated statement.");
599 return Data->getRawStmt();
600 }
601};
602
603/// This represents '#pragma omp parallel' directive.
604///
605/// \code
606/// #pragma omp parallel private(a,b) reduction(+: c,d)
607/// \endcode
608/// In this example directive '#pragma omp parallel' has clauses 'private'
609/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
610/// variables 'c' and 'd'.
611///
612class OMPParallelDirective : public OMPExecutableDirective {
613 friend class ASTStmtReader;
614 friend class OMPExecutableDirective;
615 /// true if the construct has inner cancel directive.
616 bool HasCancel = false;
617
618 /// Build directive with the given start and end location.
619 ///
620 /// \param StartLoc Starting location of the directive (directive keyword).
621 /// \param EndLoc Ending Location of the directive.
622 ///
623 OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc)
624 : OMPExecutableDirective(OMPParallelDirectiveClass,
625 llvm::omp::OMPD_parallel, StartLoc, EndLoc) {}
626
627 /// Build an empty directive.
628 ///
629 explicit OMPParallelDirective()
630 : OMPExecutableDirective(OMPParallelDirectiveClass,
631 llvm::omp::OMPD_parallel, SourceLocation(),
632 SourceLocation()) {}
633
634 /// Sets special task reduction descriptor.
635 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
636
637 /// Set cancel state.
638 void setHasCancel(bool Has) { HasCancel = Has; }
639
640public:
641 /// Creates directive with a list of \a Clauses.
642 ///
643 /// \param C AST context.
644 /// \param StartLoc Starting location of the directive kind.
645 /// \param EndLoc Ending Location of the directive.
646 /// \param Clauses List of clauses.
647 /// \param AssociatedStmt Statement associated with the directive.
648 /// \param TaskRedRef Task reduction special reference expression to handle
649 /// taskgroup descriptor.
650 /// \param HasCancel true if this directive has inner cancel directive.
651 ///
652 static OMPParallelDirective *
653 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
654 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
655 bool HasCancel);
656
657 /// Creates an empty directive with the place for \a N clauses.
658 ///
659 /// \param C AST context.
660 /// \param NumClauses Number of clauses.
661 ///
662 static OMPParallelDirective *CreateEmpty(const ASTContext &C,
663 unsigned NumClauses, EmptyShell);
664
665 /// Returns special task reduction reference expression.
666 Expr *getTaskReductionRefExpr() {
667 return cast_or_null<Expr>(Data->getChildren()[0]);
668 }
669 const Expr *getTaskReductionRefExpr() const {
670 return const_cast<OMPParallelDirective *>(this)->getTaskReductionRefExpr();
671 }
672
673 /// Return true if current directive has inner cancel directive.
674 bool hasCancel() const { return HasCancel; }
675
676 static bool classof(const Stmt *T) {
677 return T->getStmtClass() == OMPParallelDirectiveClass;
678 }
679};
680
681/// The base class for all loop-based directives, including loop transformation
682/// directives.
683class OMPLoopBasedDirective : public OMPExecutableDirective {
684 friend class ASTStmtReader;
685
686protected:
687 /// Number of collapsed loops as specified by 'collapse' clause.
688 unsigned NumAssociatedLoops = 0;
689
690 /// Build instance of loop directive of class \a Kind.
691 ///
692 /// \param SC Statement class.
693 /// \param Kind Kind of OpenMP directive.
694 /// \param StartLoc Starting location of the directive (directive keyword).
695 /// \param EndLoc Ending location of the directive.
696 /// \param NumAssociatedLoops Number of loops associated with the construct.
697 ///
698 OMPLoopBasedDirective(StmtClass SC, OpenMPDirectiveKind Kind,
699 SourceLocation StartLoc, SourceLocation EndLoc,
700 unsigned NumAssociatedLoops)
701 : OMPExecutableDirective(SC, Kind, StartLoc, EndLoc),
702 NumAssociatedLoops(NumAssociatedLoops) {}
703
704public:
705 /// The expressions built to support OpenMP loops in combined/composite
706 /// pragmas (e.g. pragma omp distribute parallel for)
707 struct DistCombinedHelperExprs {
708 /// DistributeLowerBound - used when composing 'omp distribute' with
709 /// 'omp for' in a same construct.
710 Expr *LB;
711 /// DistributeUpperBound - used when composing 'omp distribute' with
712 /// 'omp for' in a same construct.
713 Expr *UB;
714 /// DistributeEnsureUpperBound - used when composing 'omp distribute'
715 /// with 'omp for' in a same construct, EUB depends on DistUB
716 Expr *EUB;
717 /// Distribute loop iteration variable init used when composing 'omp
718 /// distribute'
719 /// with 'omp for' in a same construct
720 Expr *Init;
721 /// Distribute Loop condition used when composing 'omp distribute'
722 /// with 'omp for' in a same construct
723 Expr *Cond;
724 /// Update of LowerBound for statically scheduled omp loops for
725 /// outer loop in combined constructs (e.g. 'distribute parallel for')
726 Expr *NLB;
727 /// Update of UpperBound for statically scheduled omp loops for
728 /// outer loop in combined constructs (e.g. 'distribute parallel for')
729 Expr *NUB;
730 /// Distribute Loop condition used when composing 'omp distribute'
731 /// with 'omp for' in a same construct when schedule is chunked.
732 Expr *DistCond;
733 /// 'omp parallel for' loop condition used when composed with
734 /// 'omp distribute' in the same construct and when schedule is
735 /// chunked and the chunk size is 1.
736 Expr *ParForInDistCond;
737 };
738
739 /// The expressions built for the OpenMP loop CodeGen for the
740 /// whole collapsed loop nest.
741 struct HelperExprs {
742 /// Loop iteration variable.
743 Expr *IterationVarRef;
744 /// Loop last iteration number.
745 Expr *LastIteration;
746 /// Loop number of iterations.
747 Expr *NumIterations;
748 /// Calculation of last iteration.
749 Expr *CalcLastIteration;
750 /// Loop pre-condition.
751 Expr *PreCond;
752 /// Loop condition.
753 Expr *Cond;
754 /// Loop iteration variable init.
755 Expr *Init;
756 /// Loop increment.
757 Expr *Inc;
758 /// IsLastIteration - local flag variable passed to runtime.
759 Expr *IL;
760 /// LowerBound - local variable passed to runtime.
761 Expr *LB;
762 /// UpperBound - local variable passed to runtime.
763 Expr *UB;
764 /// Stride - local variable passed to runtime.
765 Expr *ST;
766 /// EnsureUpperBound -- expression UB = min(UB, NumIterations).
767 Expr *EUB;
768 /// Update of LowerBound for statically scheduled 'omp for' loops.
769 Expr *NLB;
770 /// Update of UpperBound for statically scheduled 'omp for' loops.
771 Expr *NUB;
772 /// PreviousLowerBound - local variable passed to runtime in the
773 /// enclosing schedule or null if that does not apply.
774 Expr *PrevLB;
775 /// PreviousUpperBound - local variable passed to runtime in the
776 /// enclosing schedule or null if that does not apply.
777 Expr *PrevUB;
778 /// DistInc - increment expression for distribute loop when found
779 /// combined with a further loop level (e.g. in 'distribute parallel for')
780 /// expression IV = IV + ST
781 Expr *DistInc;
782 /// PrevEUB - expression similar to EUB but to be used when loop
783 /// scheduling uses PrevLB and PrevUB (e.g. in 'distribute parallel for'
784 /// when ensuring that the UB is either the calculated UB by the runtime or
785 /// the end of the assigned distribute chunk)
786 /// expression UB = min (UB, PrevUB)
787 Expr *PrevEUB;
788 /// Counters Loop counters.
789 SmallVector<Expr *, 4> Counters;
790 /// PrivateCounters Loop counters.
791 SmallVector<Expr *, 4> PrivateCounters;
792 /// Expressions for loop counters inits for CodeGen.
793 SmallVector<Expr *, 4> Inits;
794 /// Expressions for loop counters update for CodeGen.
795 SmallVector<Expr *, 4> Updates;
796 /// Final loop counter values for GodeGen.
797 SmallVector<Expr *, 4> Finals;
798 /// List of counters required for the generation of the non-rectangular
799 /// loops.
800 SmallVector<Expr *, 4> DependentCounters;
801 /// List of initializers required for the generation of the non-rectangular
802 /// loops.
803 SmallVector<Expr *, 4> DependentInits;
804 /// List of final conditions required for the generation of the
805 /// non-rectangular loops.
806 SmallVector<Expr *, 4> FinalsConditions;
807 /// Init statement for all captured expressions.
808 Stmt *PreInits;
809
810 /// Expressions used when combining OpenMP loop pragmas
811 DistCombinedHelperExprs DistCombinedFields;
812
813 /// Check if all the expressions are built (does not check the
814 /// worksharing ones).
815 bool builtAll() {
816 return IterationVarRef != nullptr && LastIteration != nullptr &&
817 NumIterations != nullptr && PreCond != nullptr &&
818 Cond != nullptr && Init != nullptr && Inc != nullptr;
819 }
820
821 /// Initialize all the fields to null.
822 /// \param Size Number of elements in the
823 /// counters/finals/updates/dependent_counters/dependent_inits/finals_conditions
824 /// arrays.
825 void clear(unsigned Size) {
826 IterationVarRef = nullptr;
827 LastIteration = nullptr;
828 CalcLastIteration = nullptr;
829 PreCond = nullptr;
830 Cond = nullptr;
831 Init = nullptr;
832 Inc = nullptr;
833 IL = nullptr;
834 LB = nullptr;
835 UB = nullptr;
836 ST = nullptr;
837 EUB = nullptr;
838 NLB = nullptr;
839 NUB = nullptr;
840 NumIterations = nullptr;
841 PrevLB = nullptr;
842 PrevUB = nullptr;
843 DistInc = nullptr;
844 PrevEUB = nullptr;
845 Counters.resize(Size);
846 PrivateCounters.resize(Size);
847 Inits.resize(Size);
848 Updates.resize(Size);
849 Finals.resize(Size);
850 DependentCounters.resize(Size);
851 DependentInits.resize(Size);
852 FinalsConditions.resize(Size);
853 for (unsigned I = 0; I < Size; ++I) {
854 Counters[I] = nullptr;
855 PrivateCounters[I] = nullptr;
856 Inits[I] = nullptr;
857 Updates[I] = nullptr;
858 Finals[I] = nullptr;
859 DependentCounters[I] = nullptr;
860 DependentInits[I] = nullptr;
861 FinalsConditions[I] = nullptr;
862 }
863 PreInits = nullptr;
864 DistCombinedFields.LB = nullptr;
865 DistCombinedFields.UB = nullptr;
866 DistCombinedFields.EUB = nullptr;
867 DistCombinedFields.Init = nullptr;
868 DistCombinedFields.Cond = nullptr;
869 DistCombinedFields.NLB = nullptr;
870 DistCombinedFields.NUB = nullptr;
871 DistCombinedFields.DistCond = nullptr;
872 DistCombinedFields.ParForInDistCond = nullptr;
873 }
874 };
875
876 /// Get number of collapsed loops.
877 unsigned getLoopsNumber() const { return NumAssociatedLoops; }
878
879 /// Try to find the next loop sub-statement in the specified statement \p
880 /// CurStmt.
881 /// \param TryImperfectlyNestedLoops true, if we need to try to look for the
882 /// imperfectly nested loop.
883 static Stmt *tryToFindNextInnerLoop(Stmt *CurStmt,
884 bool TryImperfectlyNestedLoops);
885 static const Stmt *tryToFindNextInnerLoop(const Stmt *CurStmt,
886 bool TryImperfectlyNestedLoops) {
887 return tryToFindNextInnerLoop(const_cast<Stmt *>(CurStmt),
888 TryImperfectlyNestedLoops);
889 }
890
891 /// Calls the specified callback function for all the loops in \p CurStmt,
892 /// from the outermost to the innermost.
893 static bool
894 doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
895 unsigned NumLoops,
896 llvm::function_ref<bool(unsigned, Stmt *)> Callback,
897 llvm::function_ref<void(OMPLoopTransformationDirective *)>
898 OnTransformationCallback);
899 static bool
900 doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
901 unsigned NumLoops,
902 llvm::function_ref<bool(unsigned, const Stmt *)> Callback,
903 llvm::function_ref<void(const OMPLoopTransformationDirective *)>
904 OnTransformationCallback) {
905 auto &&NewCallback = [Callback](unsigned Cnt, Stmt *CurStmt) {
906 return Callback(Cnt, CurStmt);
907 };
908 auto &&NewTransformCb =
909 [OnTransformationCallback](OMPLoopTransformationDirective *A) {
910 OnTransformationCallback(A);
911 };
912 return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
913 NumLoops, NewCallback, NewTransformCb);
914 }
915
916 /// Calls the specified callback function for all the loops in \p CurStmt,
917 /// from the outermost to the innermost.
918 static bool
919 doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
920 unsigned NumLoops,
921 llvm::function_ref<bool(unsigned, Stmt *)> Callback) {
922 auto &&TransformCb = [](OMPLoopTransformationDirective *) {};
923 return doForAllLoops(CurStmt, TryImperfectlyNestedLoops, NumLoops, Callback,
924 TransformCb);
925 }
926 static bool
927 doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
928 unsigned NumLoops,
929 llvm::function_ref<bool(unsigned, const Stmt *)> Callback) {
930 auto &&NewCallback = [Callback](unsigned Cnt, const Stmt *CurStmt) {
931 return Callback(Cnt, CurStmt);
932 };
933 return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
934 NumLoops, NewCallback);
935 }
936
937 /// Calls the specified callback function for all the loop bodies in \p
938 /// CurStmt, from the outermost loop to the innermost.
939 static void doForAllLoopsBodies(
940 Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops,
941 llvm::function_ref<void(unsigned, Stmt *, Stmt *)> Callback);
942 static void doForAllLoopsBodies(
943 const Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops,
944 llvm::function_ref<void(unsigned, const Stmt *, const Stmt *)> Callback) {
945 auto &&NewCallback = [Callback](unsigned Cnt, Stmt *Loop, Stmt *Body) {
946 Callback(Cnt, Loop, Body);
947 };
948 doForAllLoopsBodies(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
949 NumLoops, NewCallback);
950 }
951
952 static bool classof(const Stmt *T) {
953 if (auto *D = dyn_cast<OMPExecutableDirective>(T))
954 return isOpenMPLoopDirective(D->getDirectiveKind());
955 return false;
956 }
957};
958
959/// The base class for all loop transformation directives.
960class OMPLoopTransformationDirective : public OMPLoopBasedDirective {
961 friend class ASTStmtReader;
962
963 /// Number of loops generated by this loop transformation.
964 unsigned NumGeneratedLoops = 0;
965
966protected:
967 explicit OMPLoopTransformationDirective(StmtClass SC,
968 OpenMPDirectiveKind Kind,
969 SourceLocation StartLoc,
970 SourceLocation EndLoc,
971 unsigned NumAssociatedLoops)
972 : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, NumAssociatedLoops) {}
973
974 /// Set the number of loops generated by this loop transformation.
975 void setNumGeneratedLoops(unsigned Num) { NumGeneratedLoops = Num; }
976
977public:
978 /// Return the number of associated (consumed) loops.
979 unsigned getNumAssociatedLoops() const { return getLoopsNumber(); }
980
981 /// Return the number of loops generated by this loop transformation.
982 unsigned getNumGeneratedLoops() { return NumGeneratedLoops; }
983
984 /// Get the de-sugared statements after the loop transformation.
985 ///
986 /// Might be nullptr if either the directive generates no loops and is handled
987 /// directly in CodeGen, or resolving a template-dependence context is
988 /// required.
989 Stmt *getTransformedStmt() const;
990
991 /// Return preinits statement.
992 Stmt *getPreInits() const;
993
994 static bool classof(const Stmt *T) {
995 return T->getStmtClass() == OMPTileDirectiveClass ||
996 T->getStmtClass() == OMPUnrollDirectiveClass;
997 }
998};
999
1000/// This is a common base class for loop directives ('omp simd', 'omp
1001/// for', 'omp for simd' etc.). It is responsible for the loop code generation.
1002///
1003class OMPLoopDirective : public OMPLoopBasedDirective {
1004 friend class ASTStmtReader;
1005
1006 /// Offsets to the stored exprs.
1007 /// This enumeration contains offsets to all the pointers to children
1008 /// expressions stored in OMPLoopDirective.
1009 /// The first 9 children are necessary for all the loop directives,
1010 /// the next 8 are specific to the worksharing ones, and the next 11 are
1011 /// used for combined constructs containing two pragmas associated to loops.
1012 /// After the fixed children, three arrays of length NumAssociatedLoops are
1013 /// allocated: loop counters, their updates and final values.
1014 /// PrevLowerBound and PrevUpperBound are used to communicate blocking
1015 /// information in composite constructs which require loop blocking
1016 /// DistInc is used to generate the increment expression for the distribute
1017 /// loop when combined with a further nested loop
1018 /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the
1019 /// for loop when combined with a previous distribute loop in the same pragma
1020 /// (e.g. 'distribute parallel for')
1021 ///
1022 enum {
1023 IterationVariableOffset = 0,
1024 LastIterationOffset = 1,
1025 CalcLastIterationOffset = 2,
1026 PreConditionOffset = 3,
1027 CondOffset = 4,
1028 InitOffset = 5,
1029 IncOffset = 6,
1030 PreInitsOffset = 7,
1031 // The '...End' enumerators do not correspond to child expressions - they
1032 // specify the offset to the end (and start of the following counters/
1033 // updates/finals/dependent_counters/dependent_inits/finals_conditions
1034 // arrays).
1035 DefaultEnd = 8,
1036 // The following 8 exprs are used by worksharing and distribute loops only.
1037 IsLastIterVariableOffset = 8,
1038 LowerBoundVariableOffset = 9,
1039 UpperBoundVariableOffset = 10,
1040 StrideVariableOffset = 11,
1041 EnsureUpperBoundOffset = 12,
1042 NextLowerBoundOffset = 13,
1043 NextUpperBoundOffset = 14,
1044 NumIterationsOffset = 15,
1045 // Offset to the end for worksharing loop directives.
1046 WorksharingEnd = 16,
1047 PrevLowerBoundVariableOffset = 16,
1048 PrevUpperBoundVariableOffset = 17,
1049 DistIncOffset = 18,
1050 PrevEnsureUpperBoundOffset = 19,
1051 CombinedLowerBoundVariableOffset = 20,
1052 CombinedUpperBoundVariableOffset = 21,
1053 CombinedEnsureUpperBoundOffset = 22,
1054 CombinedInitOffset = 23,
1055 CombinedConditionOffset = 24,
1056 CombinedNextLowerBoundOffset = 25,
1057 CombinedNextUpperBoundOffset = 26,
1058 CombinedDistConditionOffset = 27,
1059 CombinedParForInDistConditionOffset = 28,
1060 // Offset to the end (and start of the following
1061 // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions
1062 // arrays) for combined distribute loop directives.
1063 CombinedDistributeEnd = 29,
1064 };
1065
1066 /// Get the counters storage.
1067 MutableArrayRef<Expr *> getCounters() {
1068 auto **Storage = reinterpret_cast<Expr **>(
1069 &Data->getChildren()[getArraysOffset(getDirectiveKind())]);
1070 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1071 }
1072
1073 /// Get the private counters storage.
1074 MutableArrayRef<Expr *> getPrivateCounters() {
1075 auto **Storage = reinterpret_cast<Expr **>(
1076 &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1077 getLoopsNumber()]);
1078 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1079 }
1080
1081 /// Get the updates storage.
1082 MutableArrayRef<Expr *> getInits() {
1083 auto **Storage = reinterpret_cast<Expr **>(
1084 &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1085 2 * getLoopsNumber()]);
1086 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1087 }
1088
1089 /// Get the updates storage.
1090 MutableArrayRef<Expr *> getUpdates() {
1091 auto **Storage = reinterpret_cast<Expr **>(
1092 &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1093 3 * getLoopsNumber()]);
1094 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1095 }
1096
1097 /// Get the final counter updates storage.
1098 MutableArrayRef<Expr *> getFinals() {
1099 auto **Storage = reinterpret_cast<Expr **>(
1100 &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1101 4 * getLoopsNumber()]);
1102 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1103 }
1104
1105 /// Get the dependent counters storage.
1106 MutableArrayRef<Expr *> getDependentCounters() {
1107 auto **Storage = reinterpret_cast<Expr **>(
1108 &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1109 5 * getLoopsNumber()]);
1110 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1111 }
1112
1113 /// Get the dependent inits storage.
1114 MutableArrayRef<Expr *> getDependentInits() {
1115 auto **Storage = reinterpret_cast<Expr **>(
1116 &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1117 6 * getLoopsNumber()]);
1118 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1119 }
1120
1121 /// Get the finals conditions storage.
1122 MutableArrayRef<Expr *> getFinalsConditions() {
1123 auto **Storage = reinterpret_cast<Expr **>(
1124 &Data->getChildren()[getArraysOffset(getDirectiveKind()) +
1125 7 * getLoopsNumber()]);
1126 return llvm::MutableArrayRef(Storage, getLoopsNumber());
1127 }
1128
1129protected:
1130 /// Build instance of loop directive of class \a Kind.
1131 ///
1132 /// \param SC Statement class.
1133 /// \param Kind Kind of OpenMP directive.
1134 /// \param StartLoc Starting location of the directive (directive keyword).
1135 /// \param EndLoc Ending location of the directive.
1136 /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
1137 ///
1138 OMPLoopDirective(StmtClass SC, OpenMPDirectiveKind Kind,
1139 SourceLocation StartLoc, SourceLocation EndLoc,
1140 unsigned CollapsedNum)
1141 : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, CollapsedNum) {}
1142
1143 /// Offset to the start of children expression arrays.
1144 static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
1145 if (isOpenMPLoopBoundSharingDirective(Kind))
1146 return CombinedDistributeEnd;
1147 if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) ||
1148 isOpenMPGenericLoopDirective(Kind) || isOpenMPDistributeDirective(Kind))
1149 return WorksharingEnd;
1150 return DefaultEnd;
1151 }
1152
1153 /// Children number.
1154 static unsigned numLoopChildren(unsigned CollapsedNum,
1155 OpenMPDirectiveKind Kind) {
1156 return getArraysOffset(Kind) +
1157 8 * CollapsedNum; // Counters, PrivateCounters, Inits,
1158 // Updates, Finals, DependentCounters,
1159 // DependentInits, FinalsConditions.
1160 }
1161
1162 void setIterationVariable(Expr *IV) {
1163 Data->getChildren()[IterationVariableOffset] = IV;
1164 }
1165 void setLastIteration(Expr *LI) {
1166 Data->getChildren()[LastIterationOffset] = LI;
1167 }
1168 void setCalcLastIteration(Expr *CLI) {
1169 Data->getChildren()[CalcLastIterationOffset] = CLI;
1170 }
1171 void setPreCond(Expr *PC) { Data->getChildren()[PreConditionOffset] = PC; }
1172 void setCond(Expr *Cond) { Data->getChildren()[CondOffset] = Cond; }
1173 void setInit(Expr *Init) { Data->getChildren()[InitOffset] = Init; }
1174 void setInc(Expr *Inc) { Data->getChildren()[IncOffset] = Inc; }
1175 void setPreInits(Stmt *PreInits) {
1176 Data->getChildren()[PreInitsOffset] = PreInits;
1177 }
1178 void setIsLastIterVariable(Expr *IL) {
1179 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1180 isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1181 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1182 isOpenMPDistributeDirective(getDirectiveKind())) &&
1183 "expected worksharing loop directive");
1184 Data->getChildren()[IsLastIterVariableOffset] = IL;
1185 }
1186 void setLowerBoundVariable(Expr *LB) {
1187 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1188 isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1189 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1190 isOpenMPDistributeDirective(getDirectiveKind())) &&
1191 "expected worksharing loop directive");
1192 Data->getChildren()[LowerBoundVariableOffset] = LB;
1193 }
1194 void setUpperBoundVariable(Expr *UB) {
1195 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1196 isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1197 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1198 isOpenMPDistributeDirective(getDirectiveKind())) &&
1199 "expected worksharing loop directive");
1200 Data->getChildren()[UpperBoundVariableOffset] = UB;
1201 }
1202 void setStrideVariable(Expr *ST) {
1203 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1204 isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1205 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1206 isOpenMPDistributeDirective(getDirectiveKind())) &&
1207 "expected worksharing loop directive");
1208 Data->getChildren()[StrideVariableOffset] = ST;
1209 }
1210 void setEnsureUpperBound(Expr *EUB) {
1211 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1212 isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1213 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1214 isOpenMPDistributeDirective(getDirectiveKind())) &&
1215 "expected worksharing loop directive");
1216 Data->getChildren()[EnsureUpperBoundOffset] = EUB;
1217 }
1218 void setNextLowerBound(Expr *NLB) {
1219 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1220 isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1221 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1222 isOpenMPDistributeDirective(getDirectiveKind())) &&
1223 "expected worksharing loop directive");
1224 Data->getChildren()[NextLowerBoundOffset] = NLB;
1225 }
1226 void setNextUpperBound(Expr *NUB) {
1227 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1228 isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1229 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1230 isOpenMPDistributeDirective(getDirectiveKind())) &&
1231 "expected worksharing loop directive");
1232 Data->getChildren()[NextUpperBoundOffset] = NUB;
1233 }
1234 void setNumIterations(Expr *NI) {
1235 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1236 isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1237 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1238 isOpenMPDistributeDirective(getDirectiveKind())) &&
1239 "expected worksharing loop directive");
1240 Data->getChildren()[NumIterationsOffset] = NI;
1241 }
1242 void setPrevLowerBoundVariable(Expr *PrevLB) {
1243 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1244 "expected loop bound sharing directive");
1245 Data->getChildren()[PrevLowerBoundVariableOffset] = PrevLB;
1246 }
1247 void setPrevUpperBoundVariable(Expr *PrevUB) {
1248 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1249 "expected loop bound sharing directive");
1250 Data->getChildren()[PrevUpperBoundVariableOffset] = PrevUB;
1251 }
1252 void setDistInc(Expr *DistInc) {
1253 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1254 "expected loop bound sharing directive");
1255 Data->getChildren()[DistIncOffset] = DistInc;
1256 }
1257 void setPrevEnsureUpperBound(Expr *PrevEUB) {
1258 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1259 "expected loop bound sharing directive");
1260 Data->getChildren()[PrevEnsureUpperBoundOffset] = PrevEUB;
1261 }
1262 void setCombinedLowerBoundVariable(Expr *CombLB) {
1263 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1264 "expected loop bound sharing directive");
1265 Data->getChildren()[CombinedLowerBoundVariableOffset] = CombLB;
1266 }
1267 void setCombinedUpperBoundVariable(Expr *CombUB) {
1268 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1269 "expected loop bound sharing directive");
1270 Data->getChildren()[CombinedUpperBoundVariableOffset] = CombUB;
1271 }
1272 void setCombinedEnsureUpperBound(Expr *CombEUB) {
1273 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1274 "expected loop bound sharing directive");
1275 Data->getChildren()[CombinedEnsureUpperBoundOffset] = CombEUB;
1276 }
1277 void setCombinedInit(Expr *CombInit) {
1278 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1279 "expected loop bound sharing directive");
1280 Data->getChildren()[CombinedInitOffset] = CombInit;
1281 }
1282 void setCombinedCond(Expr *CombCond) {
1283 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1284 "expected loop bound sharing directive");
1285 Data->getChildren()[CombinedConditionOffset] = CombCond;
1286 }
1287 void setCombinedNextLowerBound(Expr *CombNLB) {
1288 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1289 "expected loop bound sharing directive");
1290 Data->getChildren()[CombinedNextLowerBoundOffset] = CombNLB;
1291 }
1292 void setCombinedNextUpperBound(Expr *CombNUB) {
1293 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1294 "expected loop bound sharing directive");
1295 Data->getChildren()[CombinedNextUpperBoundOffset] = CombNUB;
1296 }
1297 void setCombinedDistCond(Expr *CombDistCond) {
1298 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1299 "expected loop bound distribute sharing directive");
1300 Data->getChildren()[CombinedDistConditionOffset] = CombDistCond;
1301 }
1302 void setCombinedParForInDistCond(Expr *CombParForInDistCond) {
1303 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1304 "expected loop bound distribute sharing directive");
1305 Data->getChildren()[CombinedParForInDistConditionOffset] =
1306 CombParForInDistCond;
1307 }
1308 void setCounters(ArrayRef<Expr *> A);
1309 void setPrivateCounters(ArrayRef<Expr *> A);
1310 void setInits(ArrayRef<Expr *> A);
1311 void setUpdates(ArrayRef<Expr *> A);
1312 void setFinals(ArrayRef<Expr *> A);
1313 void setDependentCounters(ArrayRef<Expr *> A);
1314 void setDependentInits(ArrayRef<Expr *> A);
1315 void setFinalsConditions(ArrayRef<Expr *> A);
1316
1317public:
1318 Expr *getIterationVariable() const {
1319 return cast<Expr>(Data->getChildren()[IterationVariableOffset]);
1320 }
1321 Expr *getLastIteration() const {
1322 return cast<Expr>(Data->getChildren()[LastIterationOffset]);
1323 }
1324 Expr *getCalcLastIteration() const {
1325 return cast<Expr>(Data->getChildren()[CalcLastIterationOffset]);
1326 }
1327 Expr *getPreCond() const {
1328 return cast<Expr>(Data->getChildren()[PreConditionOffset]);
1329 }
1330 Expr *getCond() const { return cast<Expr>(Data->getChildren()[CondOffset]); }
1331 Expr *getInit() const { return cast<Expr>(Data->getChildren()[InitOffset]); }
1332 Expr *getInc() const { return cast<Expr>(Data->getChildren()[IncOffset]); }
1333 const Stmt *getPreInits() const {
1334 return Data->getChildren()[PreInitsOffset];
1335 }
1336 Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; }
1337 Expr *getIsLastIterVariable() const {
1338 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1339 isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1340 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1341 isOpenMPDistributeDirective(getDirectiveKind())) &&
1342 "expected worksharing loop directive");
1343 return cast<Expr>(Data->getChildren()[IsLastIterVariableOffset]);
1344 }
1345 Expr *getLowerBoundVariable() const {
1346 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1347 isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1348 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1349 isOpenMPDistributeDirective(getDirectiveKind())) &&
1350 "expected worksharing loop directive");
1351 return cast<Expr>(Data->getChildren()[LowerBoundVariableOffset]);
1352 }
1353 Expr *getUpperBoundVariable() const {
1354 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1355 isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1356 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1357 isOpenMPDistributeDirective(getDirectiveKind())) &&
1358 "expected worksharing loop directive");
1359 return cast<Expr>(Data->getChildren()[UpperBoundVariableOffset]);
1360 }
1361 Expr *getStrideVariable() const {
1362 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1363 isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1364 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1365 isOpenMPDistributeDirective(getDirectiveKind())) &&
1366 "expected worksharing loop directive");
1367 return cast<Expr>(Data->getChildren()[StrideVariableOffset]);
1368 }
1369 Expr *getEnsureUpperBound() const {
1370 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1371 isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1372 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1373 isOpenMPDistributeDirective(getDirectiveKind())) &&
1374 "expected worksharing loop directive");
1375 return cast<Expr>(Data->getChildren()[EnsureUpperBoundOffset]);
1376 }
1377 Expr *getNextLowerBound() const {
1378 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1379 isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1380 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1381 isOpenMPDistributeDirective(getDirectiveKind())) &&
1382 "expected worksharing loop directive");
1383 return cast<Expr>(Data->getChildren()[NextLowerBoundOffset]);
1384 }
1385 Expr *getNextUpperBound() const {
1386 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1387 isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1388 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1389 isOpenMPDistributeDirective(getDirectiveKind())) &&
1390 "expected worksharing loop directive");
1391 return cast<Expr>(Data->getChildren()[NextUpperBoundOffset]);
1392 }
1393 Expr *getNumIterations() const {
1394 assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
1395 isOpenMPGenericLoopDirective(getDirectiveKind()) ||
1396 isOpenMPTaskLoopDirective(getDirectiveKind()) ||
1397 isOpenMPDistributeDirective(getDirectiveKind())) &&
1398 "expected worksharing loop directive");
1399 return cast<Expr>(Data->getChildren()[NumIterationsOffset]);
1400 }
1401 Expr *getPrevLowerBoundVariable() const {
1402 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1403 "expected loop bound sharing directive");
1404 return cast<Expr>(Data->getChildren()[PrevLowerBoundVariableOffset]);
1405 }
1406 Expr *getPrevUpperBoundVariable() const {
1407 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1408 "expected loop bound sharing directive");
1409 return cast<Expr>(Data->getChildren()[PrevUpperBoundVariableOffset]);
1410 }
1411 Expr *getDistInc() const {
1412 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1413 "expected loop bound sharing directive");
1414 return cast<Expr>(Data->getChildren()[DistIncOffset]);
1415 }
1416 Expr *getPrevEnsureUpperBound() const {
1417 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1418 "expected loop bound sharing directive");
1419 return cast<Expr>(Data->getChildren()[PrevEnsureUpperBoundOffset]);
1420 }
1421 Expr *getCombinedLowerBoundVariable() const {
1422 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1423 "expected loop bound sharing directive");
1424 return cast<Expr>(Data->getChildren()[CombinedLowerBoundVariableOffset]);
1425 }
1426 Expr *getCombinedUpperBoundVariable() const {
1427 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1428 "expected loop bound sharing directive");
1429 return cast<Expr>(Data->getChildren()[CombinedUpperBoundVariableOffset]);
1430 }
1431 Expr *getCombinedEnsureUpperBound() const {
1432 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1433 "expected loop bound sharing directive");
1434 return cast<Expr>(Data->getChildren()[CombinedEnsureUpperBoundOffset]);
1435 }
1436 Expr *getCombinedInit() const {
1437 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1438 "expected loop bound sharing directive");
1439 return cast<Expr>(Data->getChildren()[CombinedInitOffset]);
1440 }
1441 Expr *getCombinedCond() const {
1442 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1443 "expected loop bound sharing directive");
1444 return cast<Expr>(Data->getChildren()[CombinedConditionOffset]);
1445 }
1446 Expr *getCombinedNextLowerBound() const {
1447 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1448 "expected loop bound sharing directive");
1449 return cast<Expr>(Data->getChildren()[CombinedNextLowerBoundOffset]);
1450 }
1451 Expr *getCombinedNextUpperBound() const {
1452 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1453 "expected loop bound sharing directive");
1454 return cast<Expr>(Data->getChildren()[CombinedNextUpperBoundOffset]);
1455 }
1456 Expr *getCombinedDistCond() const {
1457 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1458 "expected loop bound distribute sharing directive");
1459 return cast<Expr>(Data->getChildren()[CombinedDistConditionOffset]);
1460 }
1461 Expr *getCombinedParForInDistCond() const {
1462 assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
1463 "expected loop bound distribute sharing directive");
1464 return cast<Expr>(Data->getChildren()[CombinedParForInDistConditionOffset]);
1465 }
1466 Stmt *getBody();
1467 const Stmt *getBody() const {
1468 return const_cast<OMPLoopDirective *>(this)->getBody();
1469 }
1470
1471 ArrayRef<Expr *> counters() { return getCounters(); }
1472
1473 ArrayRef<Expr *> counters() const {
1474 return const_cast<OMPLoopDirective *>(this)->getCounters();
1475 }
1476
1477 ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
1478
1479 ArrayRef<Expr *> private_counters() const {
1480 return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
1481 }
1482
1483 ArrayRef<Expr *> inits() { return getInits(); }
1484
1485 ArrayRef<Expr *> inits() const {
1486 return const_cast<OMPLoopDirective *>(this)->getInits();
1487 }
1488
1489 ArrayRef<Expr *> updates() { return getUpdates(); }
1490
1491 ArrayRef<Expr *> updates() const {
1492 return const_cast<OMPLoopDirective *>(this)->getUpdates();
1493 }
1494
1495 ArrayRef<Expr *> finals() { return getFinals(); }
1496
1497 ArrayRef<Expr *> finals() const {
1498 return const_cast<OMPLoopDirective *>(this)->getFinals();
1499 }
1500
1501 ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); }
1502
1503 ArrayRef<Expr *> dependent_counters() const {
1504 return const_cast<OMPLoopDirective *>(this)->getDependentCounters();
1505 }
1506
1507 ArrayRef<Expr *> dependent_inits() { return getDependentInits(); }
1508
1509 ArrayRef<Expr *> dependent_inits() const {
1510 return const_cast<OMPLoopDirective *>(this)->getDependentInits();
1511 }
1512
1513 ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); }
1514
1515 ArrayRef<Expr *> finals_conditions() const {
1516 return const_cast<OMPLoopDirective *>(this)->getFinalsConditions();
1517 }
1518
1519 static bool classof(const Stmt *T) {
1520 return T->getStmtClass() == OMPSimdDirectiveClass ||
1521 T->getStmtClass() == OMPForDirectiveClass ||
1522 T->getStmtClass() == OMPForSimdDirectiveClass ||
1523 T->getStmtClass() == OMPParallelForDirectiveClass ||
1524 T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
1525 T->getStmtClass() == OMPTaskLoopDirectiveClass ||
1526 T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
1527 T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass ||
1528 T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass ||
1529 T->getStmtClass() == OMPMasterTaskLoopDirectiveClass ||
1530 T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass ||
1531 T->getStmtClass() == OMPGenericLoopDirectiveClass ||
1532 T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass ||
1533 T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass ||
1534 T->getStmtClass() == OMPParallelGenericLoopDirectiveClass ||
1535 T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass ||
1536 T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass ||
1537 T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass ||
1538 T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass ||
1539 T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass ||
1540 T->getStmtClass() == OMPDistributeDirectiveClass ||
1541 T->getStmtClass() == OMPTargetParallelForDirectiveClass ||
1542 T->getStmtClass() == OMPDistributeParallelForDirectiveClass ||
1543 T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass ||
1544 T->getStmtClass() == OMPDistributeSimdDirectiveClass ||
1545 T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass ||
1546 T->getStmtClass() == OMPTargetSimdDirectiveClass ||
1547 T->getStmtClass() == OMPTeamsDistributeDirectiveClass ||
1548 T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass ||
1549 T->getStmtClass() ==
1550 OMPTeamsDistributeParallelForSimdDirectiveClass ||
1551 T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass ||
1552 T->getStmtClass() ==
1553 OMPTargetTeamsDistributeParallelForDirectiveClass ||
1554 T->getStmtClass() ==
1555 OMPTargetTeamsDistributeParallelForSimdDirectiveClass ||
1556 T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass ||
1557 T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
1558 }
1559};
1560
1561/// This represents '#pragma omp simd' directive.
1562///
1563/// \code
1564/// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
1565/// \endcode
1566/// In this example directive '#pragma omp simd' has clauses 'private'
1567/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
1568/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
1569///
1570class OMPSimdDirective : public OMPLoopDirective {
1571 friend class ASTStmtReader;
1572 friend class OMPExecutableDirective;
1573 /// Build directive with the given start and end location.
1574 ///
1575 /// \param StartLoc Starting location of the directive kind.
1576 /// \param EndLoc Ending location of the directive.
1577 /// \param CollapsedNum Number of collapsed nested loops.
1578 ///
1579 OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1580 unsigned CollapsedNum)
1581 : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, StartLoc,
1582 EndLoc, CollapsedNum) {}
1583
1584 /// Build an empty directive.
1585 ///
1586 /// \param CollapsedNum Number of collapsed nested loops.
1587 ///
1588 explicit OMPSimdDirective(unsigned CollapsedNum)
1589 : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd,
1590 SourceLocation(), SourceLocation(), CollapsedNum) {}
1591
1592public:
1593 /// Creates directive with a list of \a Clauses.
1594 ///
1595 /// \param C AST context.
1596 /// \param StartLoc Starting location of the directive kind.
1597 /// \param EndLoc Ending Location of the directive.
1598 /// \param CollapsedNum Number of collapsed loops.
1599 /// \param Clauses List of clauses.
1600 /// \param AssociatedStmt Statement, associated with the directive.
1601 /// \param Exprs Helper expressions for CodeGen.
1602 ///
1603 static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1604 SourceLocation EndLoc, unsigned CollapsedNum,
1605 ArrayRef<OMPClause *> Clauses,
1606 Stmt *AssociatedStmt,
1607 const HelperExprs &Exprs);
1608
1609 /// Creates an empty directive with the place
1610 /// for \a NumClauses clauses.
1611 ///
1612 /// \param C AST context.
1613 /// \param CollapsedNum Number of collapsed nested loops.
1614 /// \param NumClauses Number of clauses.
1615 ///
1616 static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1617 unsigned CollapsedNum, EmptyShell);
1618
1619 static bool classof(const Stmt *T) {
1620 return T->getStmtClass() == OMPSimdDirectiveClass;
1621 }
1622};
1623
1624/// This represents '#pragma omp for' directive.
1625///
1626/// \code
1627/// #pragma omp for private(a,b) reduction(+:c,d)
1628/// \endcode
1629/// In this example directive '#pragma omp for' has clauses 'private' with the
1630/// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
1631/// and 'd'.
1632///
1633class OMPForDirective : public OMPLoopDirective {
1634 friend class ASTStmtReader;
1635 friend class OMPExecutableDirective;
1636 /// true if current directive has inner cancel directive.
1637 bool HasCancel = false;
1638
1639 /// Build directive with the given start and end location.
1640 ///
1641 /// \param StartLoc Starting location of the directive kind.
1642 /// \param EndLoc Ending location of the directive.
1643 /// \param CollapsedNum Number of collapsed nested loops.
1644 ///
1645 OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1646 unsigned CollapsedNum)
1647 : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, StartLoc,
1648 EndLoc, CollapsedNum) {}
1649
1650 /// Build an empty directive.
1651 ///
1652 /// \param CollapsedNum Number of collapsed nested loops.
1653 ///
1654 explicit OMPForDirective(unsigned CollapsedNum)
1655 : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for,
1656 SourceLocation(), SourceLocation(), CollapsedNum) {}
1657
1658 /// Sets special task reduction descriptor.
1659 void setTaskReductionRefExpr(Expr *E) {
1660 Data->getChildren()[numLoopChildren(getLoopsNumber(),
1661 llvm::omp::OMPD_for)] = E;
1662 }
1663
1664 /// Set cancel state.
1665 void setHasCancel(bool Has) { HasCancel = Has; }
1666
1667public:
1668 /// Creates directive with a list of \a Clauses.
1669 ///
1670 /// \param C AST context.
1671 /// \param StartLoc Starting location of the directive kind.
1672 /// \param EndLoc Ending Location of the directive.
1673 /// \param CollapsedNum Number of collapsed loops.
1674 /// \param Clauses List of clauses.
1675 /// \param AssociatedStmt Statement, associated with the directive.
1676 /// \param Exprs Helper expressions for CodeGen.
1677 /// \param TaskRedRef Task reduction special reference expression to handle
1678 /// taskgroup descriptor.
1679 /// \param HasCancel true if current directive has inner cancel directive.
1680 ///
1681 static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1682 SourceLocation EndLoc, unsigned CollapsedNum,
1683 ArrayRef<OMPClause *> Clauses,
1684 Stmt *AssociatedStmt, const HelperExprs &Exprs,
1685 Expr *TaskRedRef, bool HasCancel);
1686
1687 /// Creates an empty directive with the place
1688 /// for \a NumClauses clauses.
1689 ///
1690 /// \param C AST context.
1691 /// \param CollapsedNum Number of collapsed nested loops.
1692 /// \param NumClauses Number of clauses.
1693 ///
1694 static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1695 unsigned CollapsedNum, EmptyShell);
1696
1697 /// Returns special task reduction reference expression.
1698 Expr *getTaskReductionRefExpr() {
1699 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
1700 getLoopsNumber(), llvm::omp::OMPD_for)]);
1701 }
1702 const Expr *getTaskReductionRefExpr() const {
1703 return const_cast<OMPForDirective *>(this)->getTaskReductionRefExpr();
1704 }
1705
1706 /// Return true if current directive has inner cancel directive.
1707 bool hasCancel() const { return HasCancel; }
1708
1709 static bool classof(const Stmt *T) {
1710 return T->getStmtClass() == OMPForDirectiveClass;
1711 }
1712};
1713
1714/// This represents '#pragma omp for simd' directive.
1715///
1716/// \code
1717/// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
1718/// \endcode
1719/// In this example directive '#pragma omp for simd' has clauses 'private'
1720/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
1721/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
1722///
1723class OMPForSimdDirective : public OMPLoopDirective {
1724 friend class ASTStmtReader;
1725 friend class OMPExecutableDirective;
1726 /// Build directive with the given start and end location.
1727 ///
1728 /// \param StartLoc Starting location of the directive kind.
1729 /// \param EndLoc Ending location of the directive.
1730 /// \param CollapsedNum Number of collapsed nested loops.
1731 ///
1732 OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1733 unsigned CollapsedNum)
1734 : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
1735 StartLoc, EndLoc, CollapsedNum) {}
1736
1737 /// Build an empty directive.
1738 ///
1739 /// \param CollapsedNum Number of collapsed nested loops.
1740 ///
1741 explicit OMPForSimdDirective(unsigned CollapsedNum)
1742 : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
1743 SourceLocation(), SourceLocation(), CollapsedNum) {}
1744
1745public:
1746 /// Creates directive with a list of \a Clauses.
1747 ///
1748 /// \param C AST context.
1749 /// \param StartLoc Starting location of the directive kind.
1750 /// \param EndLoc Ending Location of the directive.
1751 /// \param CollapsedNum Number of collapsed loops.
1752 /// \param Clauses List of clauses.
1753 /// \param AssociatedStmt Statement, associated with the directive.
1754 /// \param Exprs Helper expressions for CodeGen.
1755 ///
1756 static OMPForSimdDirective *
1757 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1758 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1759 Stmt *AssociatedStmt, const HelperExprs &Exprs);
1760
1761 /// Creates an empty directive with the place
1762 /// for \a NumClauses clauses.
1763 ///
1764 /// \param C AST context.
1765 /// \param CollapsedNum Number of collapsed nested loops.
1766 /// \param NumClauses Number of clauses.
1767 ///
1768 static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
1769 unsigned NumClauses,
1770 unsigned CollapsedNum, EmptyShell);
1771
1772 static bool classof(const Stmt *T) {
1773 return T->getStmtClass() == OMPForSimdDirectiveClass;
1774 }
1775};
1776
1777/// This represents '#pragma omp sections' directive.
1778///
1779/// \code
1780/// #pragma omp sections private(a,b) reduction(+:c,d)
1781/// \endcode
1782/// In this example directive '#pragma omp sections' has clauses 'private' with
1783/// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
1784/// 'c' and 'd'.
1785///
1786class OMPSectionsDirective : public OMPExecutableDirective {
1787 friend class ASTStmtReader;
1788 friend class OMPExecutableDirective;
1789
1790 /// true if current directive has inner cancel directive.
1791 bool HasCancel = false;
1792
1793 /// Build directive with the given start and end location.
1794 ///
1795 /// \param StartLoc Starting location of the directive kind.
1796 /// \param EndLoc Ending location of the directive.
1797 ///
1798 OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1799 : OMPExecutableDirective(OMPSectionsDirectiveClass,
1800 llvm::omp::OMPD_sections, StartLoc, EndLoc) {}
1801
1802 /// Build an empty directive.
1803 ///
1804 explicit OMPSectionsDirective()
1805 : OMPExecutableDirective(OMPSectionsDirectiveClass,
1806 llvm::omp::OMPD_sections, SourceLocation(),
1807 SourceLocation()) {}
1808
1809 /// Sets special task reduction descriptor.
1810 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
1811
1812 /// Set cancel state.
1813 void setHasCancel(bool Has) { HasCancel = Has; }
1814
1815public:
1816 /// Creates directive with a list of \a Clauses.
1817 ///
1818 /// \param C AST context.
1819 /// \param StartLoc Starting location of the directive kind.
1820 /// \param EndLoc Ending Location of the directive.
1821 /// \param Clauses List of clauses.
1822 /// \param AssociatedStmt Statement, associated with the directive.
1823 /// \param TaskRedRef Task reduction special reference expression to handle
1824 /// taskgroup descriptor.
1825 /// \param HasCancel true if current directive has inner directive.
1826 ///
1827 static OMPSectionsDirective *
1828 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1829 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
1830 bool HasCancel);
1831
1832 /// Creates an empty directive with the place for \a NumClauses
1833 /// clauses.
1834 ///
1835 /// \param C AST context.
1836 /// \param NumClauses Number of clauses.
1837 ///
1838 static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
1839 unsigned NumClauses, EmptyShell);
1840
1841 /// Returns special task reduction reference expression.
1842 Expr *getTaskReductionRefExpr() {
1843 return cast_or_null<Expr>(Data->getChildren()[0]);
1844 }
1845 const Expr *getTaskReductionRefExpr() const {
1846 return const_cast<OMPSectionsDirective *>(this)->getTaskReductionRefExpr();
1847 }
1848
1849 /// Return true if current directive has inner cancel directive.
1850 bool hasCancel() const { return HasCancel; }
1851
1852 static bool classof(const Stmt *T) {
1853 return T->getStmtClass() == OMPSectionsDirectiveClass;
1854 }
1855};
1856
1857/// This represents '#pragma omp section' directive.
1858///
1859/// \code
1860/// #pragma omp section
1861/// \endcode
1862///
1863class OMPSectionDirective : public OMPExecutableDirective {
1864 friend class ASTStmtReader;
1865 friend class OMPExecutableDirective;
1866
1867 /// true if current directive has inner cancel directive.
1868 bool HasCancel = false;
1869
1870 /// Build directive with the given start and end location.
1871 ///
1872 /// \param StartLoc Starting location of the directive kind.
1873 /// \param EndLoc Ending location of the directive.
1874 ///
1875 OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1876 : OMPExecutableDirective(OMPSectionDirectiveClass,
1877 llvm::omp::OMPD_section, StartLoc, EndLoc) {}
1878
1879 /// Build an empty directive.
1880 ///
1881 explicit OMPSectionDirective()
1882 : OMPExecutableDirective(OMPSectionDirectiveClass,
1883 llvm::omp::OMPD_section, SourceLocation(),
1884 SourceLocation()) {}
1885
1886public:
1887 /// Creates directive.
1888 ///
1889 /// \param C AST context.
1890 /// \param StartLoc Starting location of the directive kind.
1891 /// \param EndLoc Ending Location of the directive.
1892 /// \param AssociatedStmt Statement, associated with the directive.
1893 /// \param HasCancel true if current directive has inner directive.
1894 ///
1895 static OMPSectionDirective *Create(const ASTContext &C,
1896 SourceLocation StartLoc,
1897 SourceLocation EndLoc,
1898 Stmt *AssociatedStmt, bool HasCancel);
1899
1900 /// Creates an empty directive.
1901 ///
1902 /// \param C AST context.
1903 ///
1904 static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1905
1906 /// Set cancel state.
1907 void setHasCancel(bool Has) { HasCancel = Has; }
1908
1909 /// Return true if current directive has inner cancel directive.
1910 bool hasCancel() const { return HasCancel; }
1911
1912 static bool classof(const Stmt *T) {
1913 return T->getStmtClass() == OMPSectionDirectiveClass;
1914 }
1915};
1916
1917/// This represents '#pragma omp single' directive.
1918///
1919/// \code
1920/// #pragma omp single private(a,b) copyprivate(c,d)
1921/// \endcode
1922/// In this example directive '#pragma omp single' has clauses 'private' with
1923/// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
1924///
1925class OMPSingleDirective : public OMPExecutableDirective {
1926 friend class ASTStmtReader;
1927 friend class OMPExecutableDirective;
1928 /// Build directive with the given start and end location.
1929 ///
1930 /// \param StartLoc Starting location of the directive kind.
1931 /// \param EndLoc Ending location of the directive.
1932 ///
1933 OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1934 : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
1935 StartLoc, EndLoc) {}
1936
1937 /// Build an empty directive.
1938 ///
1939 explicit OMPSingleDirective()
1940 : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
1941 SourceLocation(), SourceLocation()) {}
1942
1943public:
1944 /// Creates directive with a list of \a Clauses.
1945 ///
1946 /// \param C AST context.
1947 /// \param StartLoc Starting location of the directive kind.
1948 /// \param EndLoc Ending Location of the directive.
1949 /// \param Clauses List of clauses.
1950 /// \param AssociatedStmt Statement, associated with the directive.
1951 ///
1952 static OMPSingleDirective *
1953 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1954 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1955
1956 /// Creates an empty directive with the place for \a NumClauses
1957 /// clauses.
1958 ///
1959 /// \param C AST context.
1960 /// \param NumClauses Number of clauses.
1961 ///
1962 static OMPSingleDirective *CreateEmpty(const ASTContext &C,
1963 unsigned NumClauses, EmptyShell);
1964
1965 static bool classof(const Stmt *T) {
1966 return T->getStmtClass() == OMPSingleDirectiveClass;
1967 }
1968};
1969
1970/// This represents '#pragma omp master' directive.
1971///
1972/// \code
1973/// #pragma omp master
1974/// \endcode
1975///
1976class OMPMasterDirective : public OMPExecutableDirective {
1977 friend class ASTStmtReader;
1978 friend class OMPExecutableDirective;
1979 /// Build directive with the given start and end location.
1980 ///
1981 /// \param StartLoc Starting location of the directive kind.
1982 /// \param EndLoc Ending location of the directive.
1983 ///
1984 OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1985 : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
1986 StartLoc, EndLoc) {}
1987
1988 /// Build an empty directive.
1989 ///
1990 explicit OMPMasterDirective()
1991 : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
1992 SourceLocation(), SourceLocation()) {}
1993
1994public:
1995 /// Creates directive.
1996 ///
1997 /// \param C AST context.
1998 /// \param StartLoc Starting location of the directive kind.
1999 /// \param EndLoc Ending Location of the directive.
2000 /// \param AssociatedStmt Statement, associated with the directive.
2001 ///
2002 static OMPMasterDirective *Create(const ASTContext &C,
2003 SourceLocation StartLoc,
2004 SourceLocation EndLoc,
2005 Stmt *AssociatedStmt);
2006
2007 /// Creates an empty directive.
2008 ///
2009 /// \param C AST context.
2010 ///
2011 static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2012
2013 static bool classof(const Stmt *T) {
2014 return T->getStmtClass() == OMPMasterDirectiveClass;
2015 }
2016};
2017
2018/// This represents '#pragma omp critical' directive.
2019///
2020/// \code
2021/// #pragma omp critical
2022/// \endcode
2023///
2024class OMPCriticalDirective : public OMPExecutableDirective {
2025 friend class ASTStmtReader;
2026 friend class OMPExecutableDirective;
2027 /// Name of the directive.
2028 DeclarationNameInfo DirName;
2029 /// Build directive with the given start and end location.
2030 ///
2031 /// \param Name Name of the directive.
2032 /// \param StartLoc Starting location of the directive kind.
2033 /// \param EndLoc Ending location of the directive.
2034 ///
2035 OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
2036 SourceLocation EndLoc)
2037 : OMPExecutableDirective(OMPCriticalDirectiveClass,
2038 llvm::omp::OMPD_critical, StartLoc, EndLoc),
2039 DirName(Name) {}
2040
2041 /// Build an empty directive.
2042 ///
2043 explicit OMPCriticalDirective()
2044 : OMPExecutableDirective(OMPCriticalDirectiveClass,
2045 llvm::omp::OMPD_critical, SourceLocation(),
2046 SourceLocation()) {}
2047
2048 /// Set name of the directive.
2049 ///
2050 /// \param Name Name of the directive.
2051 ///
2052 void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
2053
2054public:
2055 /// Creates directive.
2056 ///
2057 /// \param C AST context.
2058 /// \param Name Name of the directive.
2059 /// \param StartLoc Starting location of the directive kind.
2060 /// \param EndLoc Ending Location of the directive.
2061 /// \param Clauses List of clauses.
2062 /// \param AssociatedStmt Statement, associated with the directive.
2063 ///
2064 static OMPCriticalDirective *
2065 Create(const ASTContext &C, const DeclarationNameInfo &Name,
2066 SourceLocation StartLoc, SourceLocation EndLoc,
2067 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2068
2069 /// Creates an empty directive.
2070 ///
2071 /// \param C AST context.
2072 /// \param NumClauses Number of clauses.
2073 ///
2074 static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
2075 unsigned NumClauses, EmptyShell);
2076
2077 /// Return name of the directive.
2078 ///
2079 DeclarationNameInfo getDirectiveName() const { return DirName; }
2080
2081 static bool classof(const Stmt *T) {
2082 return T->getStmtClass() == OMPCriticalDirectiveClass;
2083 }
2084};
2085
2086/// This represents '#pragma omp parallel for' directive.
2087///
2088/// \code
2089/// #pragma omp parallel for private(a,b) reduction(+:c,d)
2090/// \endcode
2091/// In this example directive '#pragma omp parallel for' has clauses 'private'
2092/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
2093/// variables 'c' and 'd'.
2094///
2095class OMPParallelForDirective : public OMPLoopDirective {
2096 friend class ASTStmtReader;
2097 friend class OMPExecutableDirective;
2098
2099 /// true if current region has inner cancel directive.
2100 bool HasCancel = false;
2101
2102 /// Build directive with the given start and end location.
2103 ///
2104 /// \param StartLoc Starting location of the directive kind.
2105 /// \param EndLoc Ending location of the directive.
2106 /// \param CollapsedNum Number of collapsed nested loops.
2107 ///
2108 OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2109 unsigned CollapsedNum)
2110 : OMPLoopDirective(OMPParallelForDirectiveClass,
2111 llvm::omp::OMPD_parallel_for, StartLoc, EndLoc,
2112 CollapsedNum) {}
2113
2114 /// Build an empty directive.
2115 ///
2116 /// \param CollapsedNum Number of collapsed nested loops.
2117 ///
2118 explicit OMPParallelForDirective(unsigned CollapsedNum)
2119 : OMPLoopDirective(OMPParallelForDirectiveClass,
2120 llvm::omp::OMPD_parallel_for, SourceLocation(),
2121 SourceLocation(), CollapsedNum) {}
2122
2123 /// Sets special task reduction descriptor.
2124 void setTaskReductionRefExpr(Expr *E) {
2125 Data->getChildren()[numLoopChildren(getLoopsNumber(),
2126 llvm::omp::OMPD_parallel_for)] = E;
2127 }
2128
2129 /// Set cancel state.
2130 void setHasCancel(bool Has) { HasCancel = Has; }
2131
2132public:
2133 /// Creates directive with a list of \a Clauses.
2134 ///
2135 /// \param C AST context.
2136 /// \param StartLoc Starting location of the directive kind.
2137 /// \param EndLoc Ending Location of the directive.
2138 /// \param CollapsedNum Number of collapsed loops.
2139 /// \param Clauses List of clauses.
2140 /// \param AssociatedStmt Statement, associated with the directive.
2141 /// \param Exprs Helper expressions for CodeGen.
2142 /// \param TaskRedRef Task reduction special reference expression to handle
2143 /// taskgroup descriptor.
2144 /// \param HasCancel true if current directive has inner cancel directive.
2145 ///
2146 static OMPParallelForDirective *
2147 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2148 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2149 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
2150 bool HasCancel);
2151
2152 /// Creates an empty directive with the place
2153 /// for \a NumClauses clauses.
2154 ///
2155 /// \param C AST context.
2156 /// \param CollapsedNum Number of collapsed nested loops.
2157 /// \param NumClauses Number of clauses.
2158 ///
2159 static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
2160 unsigned NumClauses,
2161 unsigned CollapsedNum,
2162 EmptyShell);
2163
2164 /// Returns special task reduction reference expression.
2165 Expr *getTaskReductionRefExpr() {
2166 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
2167 getLoopsNumber(), llvm::omp::OMPD_parallel_for)]);
2168 }
2169 const Expr *getTaskReductionRefExpr() const {
2170 return const_cast<OMPParallelForDirective *>(this)
2171 ->getTaskReductionRefExpr();
2172 }
2173
2174 /// Return true if current directive has inner cancel directive.
2175 bool hasCancel() const { return HasCancel; }
2176
2177 static bool classof(const Stmt *T) {
2178 return T->getStmtClass() == OMPParallelForDirectiveClass;
2179 }
2180};
2181
2182/// This represents '#pragma omp parallel for simd' directive.
2183///
2184/// \code
2185/// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
2186/// \endcode
2187/// In this example directive '#pragma omp parallel for simd' has clauses
2188/// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
2189/// and linear step 's', 'reduction' with operator '+' and variables 'c' and
2190/// 'd'.
2191///
2192class OMPParallelForSimdDirective : public OMPLoopDirective {
2193 friend class ASTStmtReader;
2194 friend class OMPExecutableDirective;
2195 /// Build directive with the given start and end location.
2196 ///
2197 /// \param StartLoc Starting location of the directive kind.
2198 /// \param EndLoc Ending location of the directive.
2199 /// \param CollapsedNum Number of collapsed nested loops.
2200 ///
2201 OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2202 unsigned CollapsedNum)
2203 : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
2204 llvm::omp::OMPD_parallel_for_simd, StartLoc, EndLoc,
2205 CollapsedNum) {}
2206
2207 /// Build an empty directive.
2208 ///
2209 /// \param CollapsedNum Number of collapsed nested loops.
2210 ///
2211 explicit OMPParallelForSimdDirective(unsigned CollapsedNum)
2212 : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
2213 llvm::omp::OMPD_parallel_for_simd, SourceLocation(),
2214 SourceLocation(), CollapsedNum) {}
2215
2216public:
2217 /// Creates directive with a list of \a Clauses.
2218 ///
2219 /// \param C AST context.
2220 /// \param StartLoc Starting location of the directive kind.
2221 /// \param EndLoc Ending Location of the directive.
2222 /// \param CollapsedNum Number of collapsed loops.
2223 /// \param Clauses List of clauses.
2224 /// \param AssociatedStmt Statement, associated with the directive.
2225 /// \param Exprs Helper expressions for CodeGen.
2226 ///
2227 static OMPParallelForSimdDirective *
2228 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2229 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2230 Stmt *AssociatedStmt, const HelperExprs &Exprs);
2231
2232 /// Creates an empty directive with the place
2233 /// for \a NumClauses clauses.
2234 ///
2235 /// \param C AST context.
2236 /// \param CollapsedNum Number of collapsed nested loops.
2237 /// \param NumClauses Number of clauses.
2238 ///
2239 static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
2240 unsigned NumClauses,
2241 unsigned CollapsedNum,
2242 EmptyShell);
2243
2244 static bool classof(const Stmt *T) {
2245 return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
2246 }
2247};
2248
2249/// This represents '#pragma omp parallel master' directive.
2250///
2251/// \code
2252/// #pragma omp parallel master private(a,b)
2253/// \endcode
2254/// In this example directive '#pragma omp parallel master' has clauses
2255/// 'private' with the variables 'a' and 'b'
2256///
2257class OMPParallelMasterDirective : public OMPExecutableDirective {
2258 friend class ASTStmtReader;
2259 friend class OMPExecutableDirective;
2260
2261 OMPParallelMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2262 : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
2263 llvm::omp::OMPD_parallel_master, StartLoc,
2264 EndLoc) {}
2265
2266 explicit OMPParallelMasterDirective()
2267 : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
2268 llvm::omp::OMPD_parallel_master,
2269 SourceLocation(), SourceLocation()) {}
2270
2271 /// Sets special task reduction descriptor.
2272 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2273
2274public:
2275 /// Creates directive with a list of \a Clauses.
2276 ///
2277 /// \param C AST context.
2278 /// \param StartLoc Starting location of the directive kind.
2279 /// \param EndLoc Ending Location of the directive.
2280 /// \param Clauses List of clauses.
2281 /// \param AssociatedStmt Statement, associated with the directive.
2282 /// \param TaskRedRef Task reduction special reference expression to handle
2283 /// taskgroup descriptor.
2284 ///
2285 static OMPParallelMasterDirective *
2286 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2287 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
2288
2289 /// Creates an empty directive with the place for \a NumClauses
2290 /// clauses.
2291 ///
2292 /// \param C AST context.
2293 /// \param NumClauses Number of clauses.
2294 ///
2295 static OMPParallelMasterDirective *
2296 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2297
2298 /// Returns special task reduction reference expression.
2299 Expr *getTaskReductionRefExpr() {
2300 return cast_or_null<Expr>(Data->getChildren()[0]);
2301 }
2302 const Expr *getTaskReductionRefExpr() const {
2303 return const_cast<OMPParallelMasterDirective *>(this)
2304 ->getTaskReductionRefExpr();
2305 }
2306
2307 static bool classof(const Stmt *T) {
2308 return T->getStmtClass() == OMPParallelMasterDirectiveClass;
2309 }
2310};
2311
2312/// This represents '#pragma omp parallel masked' directive.
2313///
2314/// \code
2315/// #pragma omp parallel masked filter(tid)
2316/// \endcode
2317/// In this example directive '#pragma omp parallel masked' has a clause
2318/// 'filter' with the variable tid
2319///
2320class OMPParallelMaskedDirective final : public OMPExecutableDirective {
2321 friend class ASTStmtReader;
2322 friend class OMPExecutableDirective;
2323
2324 OMPParallelMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2325 : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
2326 llvm::omp::OMPD_parallel_masked, StartLoc,
2327 EndLoc) {}
2328
2329 explicit OMPParallelMaskedDirective()
2330 : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
2331 llvm::omp::OMPD_parallel_masked,
2332 SourceLocation(), SourceLocation()) {}
2333
2334 /// Sets special task reduction descriptor.
2335 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2336
2337public:
2338 /// Creates directive with a list of \a Clauses.
2339 ///
2340 /// \param C AST context.
2341 /// \param StartLoc Starting location of the directive kind.
2342 /// \param EndLoc Ending Location of the directive.
2343 /// \param Clauses List of clauses.
2344 /// \param AssociatedStmt Statement, associated with the directive.
2345 /// \param TaskRedRef Task reduction special reference expression to handle
2346 /// taskgroup descriptor.
2347 ///
2348 static OMPParallelMaskedDirective *
2349 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2350 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
2351
2352 /// Creates an empty directive with the place for \a NumClauses
2353 /// clauses.
2354 ///
2355 /// \param C AST context.
2356 /// \param NumClauses Number of clauses.
2357 ///
2358 static OMPParallelMaskedDirective *
2359 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2360
2361 /// Returns special task reduction reference expression.
2362 Expr *getTaskReductionRefExpr() {
2363 return cast_or_null<Expr>(Data->getChildren()[0]);
2364 }
2365 const Expr *getTaskReductionRefExpr() const {
2366 return const_cast<OMPParallelMaskedDirective *>(this)
2367 ->getTaskReductionRefExpr();
2368 }
2369
2370 static bool classof(const Stmt *T) {
2371 return T->getStmtClass() == OMPParallelMaskedDirectiveClass;
2372 }
2373};
2374
2375/// This represents '#pragma omp parallel sections' directive.
2376///
2377/// \code
2378/// #pragma omp parallel sections private(a,b) reduction(+:c,d)
2379/// \endcode
2380/// In this example directive '#pragma omp parallel sections' has clauses
2381/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
2382/// and variables 'c' and 'd'.
2383///
2384class OMPParallelSectionsDirective : public OMPExecutableDirective {
2385 friend class ASTStmtReader;
2386 friend class OMPExecutableDirective;
2387
2388 /// true if current directive has inner cancel directive.
2389 bool HasCancel = false;
2390
2391 /// Build directive with the given start and end location.
2392 ///
2393 /// \param StartLoc Starting location of the directive kind.
2394 /// \param EndLoc Ending location of the directive.
2395 ///
2396 OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2397 : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
2398 llvm::omp::OMPD_parallel_sections, StartLoc,
2399 EndLoc) {}
2400
2401 /// Build an empty directive.
2402 ///
2403 explicit OMPParallelSectionsDirective()
2404 : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
2405 llvm::omp::OMPD_parallel_sections,
2406 SourceLocation(), SourceLocation()) {}
2407
2408 /// Sets special task reduction descriptor.
2409 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2410
2411 /// Set cancel state.
2412 void setHasCancel(bool Has) { HasCancel = Has; }
2413
2414public:
2415 /// Creates directive with a list of \a Clauses.
2416 ///
2417 /// \param C AST context.
2418 /// \param StartLoc Starting location of the directive kind.
2419 /// \param EndLoc Ending Location of the directive.
2420 /// \param Clauses List of clauses.
2421 /// \param AssociatedStmt Statement, associated with the directive.
2422 /// \param TaskRedRef Task reduction special reference expression to handle
2423 /// taskgroup descriptor.
2424 /// \param HasCancel true if current directive has inner cancel directive.
2425 ///
2426 static OMPParallelSectionsDirective *
2427 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2428 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
2429 bool HasCancel);
2430
2431 /// Creates an empty directive with the place for \a NumClauses
2432 /// clauses.
2433 ///
2434 /// \param C AST context.
2435 /// \param NumClauses Number of clauses.
2436 ///
2437 static OMPParallelSectionsDirective *
2438 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2439
2440 /// Returns special task reduction reference expression.
2441 Expr *getTaskReductionRefExpr() {
2442 return cast_or_null<Expr>(Data->getChildren()[0]);
2443 }
2444 const Expr *getTaskReductionRefExpr() const {
2445 return const_cast<OMPParallelSectionsDirective *>(this)
2446 ->getTaskReductionRefExpr();
2447 }
2448
2449 /// Return true if current directive has inner cancel directive.
2450 bool hasCancel() const { return HasCancel; }
2451
2452 static bool classof(const Stmt *T) {
2453 return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
2454 }
2455};
2456
2457/// This represents '#pragma omp task' directive.
2458///
2459/// \code
2460/// #pragma omp task private(a,b) final(d)
2461/// \endcode
2462/// In this example directive '#pragma omp task' has clauses 'private' with the
2463/// variables 'a' and 'b' and 'final' with condition 'd'.
2464///
2465class OMPTaskDirective : public OMPExecutableDirective {
2466 friend class ASTStmtReader;
2467 friend class OMPExecutableDirective;
2468 /// true if this directive has inner cancel directive.
2469 bool HasCancel = false;
2470
2471 /// Build directive with the given start and end location.
2472 ///
2473 /// \param StartLoc Starting location of the directive kind.
2474 /// \param EndLoc Ending location of the directive.
2475 ///
2476 OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2477 : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
2478 StartLoc, EndLoc) {}
2479
2480 /// Build an empty directive.
2481 ///
2482 explicit OMPTaskDirective()
2483 : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
2484 SourceLocation(), SourceLocation()) {}
2485
2486 /// Set cancel state.
2487 void setHasCancel(bool Has) { HasCancel = Has; }
2488
2489public:
2490 /// Creates directive with a list of \a Clauses.
2491 ///
2492 /// \param C AST context.
2493 /// \param StartLoc Starting location of the directive kind.
2494 /// \param EndLoc Ending Location of the directive.
2495 /// \param Clauses List of clauses.
2496 /// \param AssociatedStmt Statement, associated with the directive.
2497 /// \param HasCancel true, if current directive has inner cancel directive.
2498 ///
2499 static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2500 SourceLocation EndLoc,
2501 ArrayRef<OMPClause *> Clauses,
2502 Stmt *AssociatedStmt, bool HasCancel);
2503
2504 /// Creates an empty directive with the place for \a NumClauses
2505 /// clauses.
2506 ///
2507 /// \param C AST context.
2508 /// \param NumClauses Number of clauses.
2509 ///
2510 static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
2511 EmptyShell);
2512
2513 /// Return true if current directive has inner cancel directive.
2514 bool hasCancel() const { return HasCancel; }
2515
2516 static bool classof(const Stmt *T) {
2517 return T->getStmtClass() == OMPTaskDirectiveClass;
2518 }
2519};
2520
2521/// This represents '#pragma omp taskyield' directive.
2522///
2523/// \code
2524/// #pragma omp taskyield
2525/// \endcode
2526///
2527class OMPTaskyieldDirective : public OMPExecutableDirective {
2528 friend class ASTStmtReader;
2529 friend class OMPExecutableDirective;
2530 /// Build directive with the given start and end location.
2531 ///
2532 /// \param StartLoc Starting location of the directive kind.
2533 /// \param EndLoc Ending location of the directive.
2534 ///
2535 OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2536 : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
2537 llvm::omp::OMPD_taskyield, StartLoc, EndLoc) {}
2538
2539 /// Build an empty directive.
2540 ///
2541 explicit OMPTaskyieldDirective()
2542 : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
2543 llvm::omp::OMPD_taskyield, SourceLocation(),
2544 SourceLocation()) {}
2545
2546public:
2547 /// Creates directive.
2548 ///
2549 /// \param C AST context.
2550 /// \param StartLoc Starting location of the directive kind.
2551 /// \param EndLoc Ending Location of the directive.
2552 ///
2553 static OMPTaskyieldDirective *
2554 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
2555
2556 /// Creates an empty directive.
2557 ///
2558 /// \param C AST context.
2559 ///
2560 static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2561
2562 static bool classof(const Stmt *T) {
2563 return T->getStmtClass() == OMPTaskyieldDirectiveClass;
2564 }
2565};
2566
2567/// This represents '#pragma omp barrier' directive.
2568///
2569/// \code
2570/// #pragma omp barrier
2571/// \endcode
2572///
2573class OMPBarrierDirective : public OMPExecutableDirective {
2574 friend class ASTStmtReader;
2575 friend class OMPExecutableDirective;
2576 /// Build directive with the given start and end location.
2577 ///
2578 /// \param StartLoc Starting location of the directive kind.
2579 /// \param EndLoc Ending location of the directive.
2580 ///
2581 OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2582 : OMPExecutableDirective(OMPBarrierDirectiveClass,
2583 llvm::omp::OMPD_barrier, StartLoc, EndLoc) {}
2584
2585 /// Build an empty directive.
2586 ///
2587 explicit OMPBarrierDirective()
2588 : OMPExecutableDirective(OMPBarrierDirectiveClass,
2589 llvm::omp::OMPD_barrier, SourceLocation(),
2590 SourceLocation()) {}
2591
2592public:
2593 /// Creates directive.
2594 ///
2595 /// \param C AST context.
2596 /// \param StartLoc Starting location of the directive kind.
2597 /// \param EndLoc Ending Location of the directive.
2598 ///
2599 static OMPBarrierDirective *
2600 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
2601
2602 /// Creates an empty directive.
2603 ///
2604 /// \param C AST context.
2605 ///
2606 static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2607
2608 static bool classof(const Stmt *T) {
2609 return T->getStmtClass() == OMPBarrierDirectiveClass;
2610 }
2611};
2612
2613/// This represents '#pragma omp taskwait' directive.
2614///
2615/// \code
2616/// #pragma omp taskwait
2617/// \endcode
2618///
2619class OMPTaskwaitDirective : public OMPExecutableDirective {
2620 friend class ASTStmtReader;
2621 friend class OMPExecutableDirective;
2622 /// Build directive with the given start and end location.
2623 ///
2624 /// \param StartLoc Starting location of the directive kind.
2625 /// \param EndLoc Ending location of the directive.
2626 ///
2627 OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2628 : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
2629 llvm::omp::OMPD_taskwait, StartLoc, EndLoc) {}
2630
2631 /// Build an empty directive.
2632 ///
2633 explicit OMPTaskwaitDirective()
2634 : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
2635 llvm::omp::OMPD_taskwait, SourceLocation(),
2636 SourceLocation()) {}
2637
2638public:
2639 /// Creates directive.
2640 ///
2641 /// \param C AST context.
2642 /// \param StartLoc Starting location of the directive kind.
2643 /// \param EndLoc Ending Location of the directive.
2644 /// \param Clauses List of clauses.
2645 ///
2646 static OMPTaskwaitDirective *Create(const ASTContext &C,
2647 SourceLocation StartLoc,
2648 SourceLocation EndLoc,
2649 ArrayRef<OMPClause *> Clauses);
2650
2651 /// Creates an empty directive.
2652 ///
2653 /// \param C AST context.
2654 /// \param NumClauses Number of clauses.
2655 ///
2656 static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C,
2657 unsigned NumClauses, EmptyShell);
2658
2659 static bool classof(const Stmt *T) {
2660 return T->getStmtClass() == OMPTaskwaitDirectiveClass;
2661 }
2662};
2663
2664/// This represents '#pragma omp taskgroup' directive.
2665///
2666/// \code
2667/// #pragma omp taskgroup
2668/// \endcode
2669///
2670class OMPTaskgroupDirective : public OMPExecutableDirective {
2671 friend class ASTStmtReader;
2672 friend class OMPExecutableDirective;
2673 /// Build directive with the given start and end location.
2674 ///
2675 /// \param StartLoc Starting location of the directive kind.
2676 /// \param EndLoc Ending location of the directive.
2677 ///
2678 OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2679 : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
2680 llvm::omp::OMPD_taskgroup, StartLoc, EndLoc) {}
2681
2682 /// Build an empty directive.
2683 ///
2684 explicit OMPTaskgroupDirective()
2685 : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
2686 llvm::omp::OMPD_taskgroup, SourceLocation(),
2687 SourceLocation()) {}
2688
2689 /// Sets the task_reduction return variable.
2690 void setReductionRef(Expr *RR) { Data->getChildren()[0] = RR; }
2691
2692public:
2693 /// Creates directive.
2694 ///
2695 /// \param C AST context.
2696 /// \param StartLoc Starting location of the directive kind.
2697 /// \param EndLoc Ending Location of the directive.
2698 /// \param Clauses List of clauses.
2699 /// \param AssociatedStmt Statement, associated with the directive.
2700 /// \param ReductionRef Reference to the task_reduction return variable.
2701 ///
2702 static OMPTaskgroupDirective *
2703 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2704 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
2705 Expr *ReductionRef);
2706
2707 /// Creates an empty directive.
2708 ///
2709 /// \param C AST context.
2710 /// \param NumClauses Number of clauses.
2711 ///
2712 static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C,
2713 unsigned NumClauses, EmptyShell);
2714
2715
2716 /// Returns reference to the task_reduction return variable.
2717 const Expr *getReductionRef() const {
2718 return const_cast<OMPTaskgroupDirective *>(this)->getReductionRef();
2719 }
2720 Expr *getReductionRef() { return cast_or_null<Expr>(Data->getChildren()[0]); }
2721
2722 static bool classof(const Stmt *T) {
2723 return T->getStmtClass() == OMPTaskgroupDirectiveClass;
2724 }
2725};
2726
2727/// This represents '#pragma omp flush' directive.
2728///
2729/// \code
2730/// #pragma omp flush(a,b)
2731/// \endcode
2732/// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
2733/// and 'b'.
2734/// 'omp flush' directive does not have clauses but have an optional list of
2735/// variables to flush. This list of variables is stored within some fake clause
2736/// FlushClause.
2737class OMPFlushDirective : public OMPExecutableDirective {
2738 friend class ASTStmtReader;
2739 friend class OMPExecutableDirective;
2740 /// Build directive with the given start and end location.
2741 ///
2742 /// \param StartLoc Starting location of the directive kind.
2743 /// \param EndLoc Ending location of the directive.
2744 ///
2745 OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2746 : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
2747 StartLoc, EndLoc) {}
2748
2749 /// Build an empty directive.
2750 ///
2751 explicit OMPFlushDirective()
2752 : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
2753 SourceLocation(), SourceLocation()) {}
2754
2755public:
2756 /// Creates directive with a list of \a Clauses.
2757 ///
2758 /// \param C AST context.
2759 /// \param StartLoc Starting location of the directive kind.
2760 /// \param EndLoc Ending Location of the directive.
2761 /// \param Clauses List of clauses (only single OMPFlushClause clause is
2762 /// allowed).
2763 ///
2764 static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2765 SourceLocation EndLoc,
2766 ArrayRef<OMPClause *> Clauses);
2767
2768 /// Creates an empty directive with the place for \a NumClauses
2769 /// clauses.
2770 ///
2771 /// \param C AST context.
2772 /// \param NumClauses Number of clauses.
2773 ///
2774 static OMPFlushDirective *CreateEmpty(const ASTContext &C,
2775 unsigned NumClauses, EmptyShell);
2776
2777 static bool classof(const Stmt *T) {
2778 return T->getStmtClass() == OMPFlushDirectiveClass;
2779 }
2780};
2781
2782/// This represents '#pragma omp depobj' directive.
2783///
2784/// \code
2785/// #pragma omp depobj(a) depend(in:x,y)
2786/// \endcode
2787/// In this example directive '#pragma omp depobj' initializes a depobj object
2788/// 'a' with dependence type 'in' and a list with 'x' and 'y' locators.
2789class OMPDepobjDirective final : public OMPExecutableDirective {
2790 friend class ASTStmtReader;
2791 friend class OMPExecutableDirective;
2792
2793 /// Build directive with the given start and end location.
2794 ///
2795 /// \param StartLoc Starting location of the directive kind.
2796 /// \param EndLoc Ending location of the directive.
2797 ///
2798 OMPDepobjDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2799 : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
2800 StartLoc, EndLoc) {}
2801
2802 /// Build an empty directive.
2803 ///
2804 explicit OMPDepobjDirective()
2805 : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
2806 SourceLocation(), SourceLocation()) {}
2807
2808public:
2809 /// Creates directive with a list of \a Clauses.
2810 ///
2811 /// \param C AST context.
2812 /// \param StartLoc Starting location of the directive kind.
2813 /// \param EndLoc Ending Location of the directive.
2814 /// \param Clauses List of clauses.
2815 ///
2816 static OMPDepobjDirective *Create(const ASTContext &C,
2817 SourceLocation StartLoc,
2818 SourceLocation EndLoc,
2819 ArrayRef<OMPClause *> Clauses);
2820
2821 /// Creates an empty directive with the place for \a NumClauses
2822 /// clauses.
2823 ///
2824 /// \param C AST context.
2825 /// \param NumClauses Number of clauses.
2826 ///
2827 static OMPDepobjDirective *CreateEmpty(const ASTContext &C,
2828 unsigned NumClauses, EmptyShell);
2829
2830 static bool classof(const Stmt *T) {
2831 return T->getStmtClass() == OMPDepobjDirectiveClass;
2832 }
2833};
2834
2835/// This represents '#pragma omp ordered' directive.
2836///
2837/// \code
2838/// #pragma omp ordered
2839/// \endcode
2840///
2841class OMPOrderedDirective : public OMPExecutableDirective {
2842 friend class ASTStmtReader;
2843 friend class OMPExecutableDirective;
2844 /// Build directive with the given start and end location.
2845 ///
2846 /// \param StartLoc Starting location of the directive kind.
2847 /// \param EndLoc Ending location of the directive.
2848 ///
2849 OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2850 : OMPExecutableDirective(OMPOrderedDirectiveClass,
2851 llvm::omp::OMPD_ordered, StartLoc, EndLoc) {}
2852
2853 /// Build an empty directive.
2854 ///
2855 explicit OMPOrderedDirective()
2856 : OMPExecutableDirective(OMPOrderedDirectiveClass,
2857 llvm::omp::OMPD_ordered, SourceLocation(),
2858 SourceLocation()) {}
2859
2860public:
2861 /// Creates directive.
2862 ///
2863 /// \param C AST context.
2864 /// \param StartLoc Starting location of the directive kind.
2865 /// \param EndLoc Ending Location of the directive.
2866 /// \param Clauses List of clauses.
2867 /// \param AssociatedStmt Statement, associated with the directive.
2868 ///
2869 static OMPOrderedDirective *
2870 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2871 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2872
2873 /// Creates an empty directive.
2874 ///
2875 /// \param C AST context.
2876 /// \param NumClauses Number of clauses.
2877 /// \param IsStandalone true, if the standalone directive is created.
2878 ///
2879 static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
2880 unsigned NumClauses,
2881 bool IsStandalone, EmptyShell);
2882
2883 static bool classof(const Stmt *T) {
2884 return T->getStmtClass() == OMPOrderedDirectiveClass;
2885 }
2886};
2887
2888/// This represents '#pragma omp atomic' directive.
2889///
2890/// \code
2891/// #pragma omp atomic capture
2892/// \endcode
2893/// In this example directive '#pragma omp atomic' has clause 'capture'.
2894///
2895class OMPAtomicDirective : public OMPExecutableDirective {
2896 friend class ASTStmtReader;
2897 friend class OMPExecutableDirective;
2898
2899 struct FlagTy {
2900 /// Used for 'atomic update' or 'atomic capture' constructs. They may
2901 /// have atomic expressions of forms:
2902 /// \code
2903 /// x = x binop expr;
2904 /// x = expr binop x;
2905 /// \endcode
2906 /// This field is 1 for the first form of the expression and 0 for the
2907 /// second. Required for correct codegen of non-associative operations (like
2908 /// << or >>).
2909 uint8_t IsXLHSInRHSPart : 1;
2910 /// Used for 'atomic update' or 'atomic capture' constructs. They may
2911 /// have atomic expressions of forms:
2912 /// \code
2913 /// v = x; <update x>;
2914 /// <update x>; v = x;
2915 /// \endcode
2916 /// This field is 1 for the first(postfix) form of the expression and 0
2917 /// otherwise.
2918 uint8_t IsPostfixUpdate : 1;
2919 /// 1 if 'v' is updated only when the condition is false (compare capture
2920 /// only).
2921 uint8_t IsFailOnly : 1;
2922 } Flags;
2923
2924 /// Build directive with the given start and end location.
2925 ///
2926 /// \param StartLoc Starting location of the directive kind.
2927 /// \param EndLoc Ending location of the directive.
2928 ///
2929 OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2930 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
2931 StartLoc, EndLoc) {}
2932
2933 /// Build an empty directive.
2934 ///
2935 explicit OMPAtomicDirective()
2936 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
2937 SourceLocation(), SourceLocation()) {}
2938
2939 enum DataPositionTy : size_t {
2940 POS_X = 0,
2941 POS_V,
2942 POS_E,
2943 POS_UpdateExpr,
2944 POS_D,
2945 POS_Cond,
2946 POS_R,
2947 };
2948
2949 /// Set 'x' part of the associated expression/statement.
2950 void setX(Expr *X) { Data->getChildren()[DataPositionTy::POS_X] = X; }
2951 /// Set helper expression of the form
2952 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
2953 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2954 void setUpdateExpr(Expr *UE) {
2955 Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE;
2956 }
2957 /// Set 'v' part of the associated expression/statement.
2958 void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; }
2959 /// Set 'r' part of the associated expression/statement.
2960 void setR(Expr *R) { Data->getChildren()[DataPositionTy::POS_R] = R; }
2961 /// Set 'expr' part of the associated expression/statement.
2962 void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; }
2963 /// Set 'd' part of the associated expression/statement.
2964 void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; }
2965 /// Set conditional expression in `atomic compare`.
2966 void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; }
2967
2968public:
2969 struct Expressions {
2970 /// 'x' part of the associated expression/statement.
2971 Expr *X = nullptr;
2972 /// 'v' part of the associated expression/statement.
2973 Expr *V = nullptr;
2974 // 'r' part of the associated expression/statement.
2975 Expr *R = nullptr;
2976 /// 'expr' part of the associated expression/statement.
2977 Expr *E = nullptr;
2978 /// UE Helper expression of the form:
2979 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
2980 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2981 Expr *UE = nullptr;
2982 /// 'd' part of the associated expression/statement.
2983 Expr *D = nullptr;
2984 /// Conditional expression in `atomic compare` construct.
2985 Expr *Cond = nullptr;
2986 /// True if UE has the first form and false if the second.
2987 bool IsXLHSInRHSPart;
2988 /// True if original value of 'x' must be stored in 'v', not an updated one.
2989 bool IsPostfixUpdate;
2990 /// True if 'v' is updated only when the condition is false (compare capture
2991 /// only).
2992 bool IsFailOnly;
2993 };
2994
2995 /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
2996 /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
2997 /// detailed description of 'x', 'v' and 'expr').
2998 ///
2999 /// \param C AST context.
3000 /// \param StartLoc Starting location of the directive kind.
3001 /// \param EndLoc Ending Location of the directive.
3002 /// \param Clauses List of clauses.
3003 /// \param AssociatedStmt Statement, associated with the directive.
3004 /// \param Exprs Associated expressions or statements.
3005 static OMPAtomicDirective *Create(const ASTContext &C,
3006 SourceLocation StartLoc,
3007 SourceLocation EndLoc,
3008 ArrayRef<OMPClause *> Clauses,
3009 Stmt *AssociatedStmt, Expressions Exprs);
3010
3011 /// Creates an empty directive with the place for \a NumClauses
3012 /// clauses.
3013 ///
3014 /// \param C AST context.
3015 /// \param NumClauses Number of clauses.
3016 ///
3017 static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
3018 unsigned NumClauses, EmptyShell);
3019
3020 /// Get 'x' part of the associated expression/statement.
3021 Expr *getX() {
3022 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
3023 }
3024 const Expr *getX() const {
3025 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
3026 }
3027 /// Get helper expression of the form
3028 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
3029 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3030 Expr *getUpdateExpr() {
3031 return cast_or_null<Expr>(
3032 Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
3033 }
3034 const Expr *getUpdateExpr() const {
3035 return cast_or_null<Expr>(
3036 Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
3037 }
3038 /// Return true if helper update expression has form
3039 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
3040 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3041 bool isXLHSInRHSPart() const { return Flags.IsXLHSInRHSPart; }
3042 /// Return true if 'v' expression must be updated to original value of
3043 /// 'x', false if 'v' must be updated to the new value of 'x'.
3044 bool isPostfixUpdate() const { return Flags.IsPostfixUpdate; }
3045 /// Return true if 'v' is updated only when the condition is evaluated false
3046 /// (compare capture only).
3047 bool isFailOnly() const { return Flags.IsFailOnly; }
3048 /// Get 'v' part of the associated expression/statement.
3049 Expr *getV() {
3050 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
3051 }
3052 const Expr *getV() const {
3053 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
3054 }
3055 /// Get 'r' part of the associated expression/statement.
3056 Expr *getR() {
3057 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
3058 }
3059 const Expr *getR() const {
3060 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
3061 }
3062 /// Get 'expr' part of the associated expression/statement.
3063 Expr *getExpr() {
3064 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
3065 }
3066 const Expr *getExpr() const {
3067 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
3068 }
3069 /// Get 'd' part of the associated expression/statement.
3070 Expr *getD() {
3071 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
3072 }
3073 Expr *getD() const {
3074 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
3075 }
3076 /// Get the 'cond' part of the source atomic expression.
3077 Expr *getCondExpr() {
3078 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
3079 }
3080 Expr *getCondExpr() const {
3081 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
3082 }
3083
3084 static bool classof(const Stmt *T) {
3085 return T->getStmtClass() == OMPAtomicDirectiveClass;
3086 }
3087};
3088
3089/// This represents '#pragma omp target' directive.
3090///
3091/// \code
3092/// #pragma omp target if(a)
3093/// \endcode
3094/// In this example directive '#pragma omp target' has clause 'if' with
3095/// condition 'a'.
3096///
3097class OMPTargetDirective : public OMPExecutableDirective {
3098 friend class ASTStmtReader;
3099 friend class OMPExecutableDirective;
3100 /// Build directive with the given start and end location.
3101 ///
3102 /// \param StartLoc Starting location of the directive kind.
3103 /// \param EndLoc Ending location of the directive.
3104 ///
3105 OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3106 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
3107 StartLoc, EndLoc) {}
3108
3109 /// Build an empty directive.
3110 ///
3111 explicit OMPTargetDirective()
3112 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
3113 SourceLocation(), SourceLocation()) {}
3114
3115public:
3116 /// Creates directive with a list of \a Clauses.
3117 ///
3118 /// \param C AST context.
3119 /// \param StartLoc Starting location of the directive kind.
3120 /// \param EndLoc Ending Location of the directive.
3121 /// \param Clauses List of clauses.
3122 /// \param AssociatedStmt Statement, associated with the directive.
3123 ///
3124 static OMPTargetDirective *
3125 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3126 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3127
3128 /// Creates an empty directive with the place for \a NumClauses
3129 /// clauses.
3130 ///
3131 /// \param C AST context.
3132 /// \param NumClauses Number of clauses.
3133 ///
3134 static OMPTargetDirective *CreateEmpty(const ASTContext &C,
3135 unsigned NumClauses, EmptyShell);
3136
3137 static bool classof(const Stmt *T) {
3138 return T->getStmtClass() == OMPTargetDirectiveClass;
3139 }
3140};
3141
3142/// This represents '#pragma omp target data' directive.
3143///
3144/// \code
3145/// #pragma omp target data device(0) if(a) map(b[:])
3146/// \endcode
3147/// In this example directive '#pragma omp target data' has clauses 'device'
3148/// with the value '0', 'if' with condition 'a' and 'map' with array
3149/// section 'b[:]'.
3150///
3151class OMPTargetDataDirective : public OMPExecutableDirective {
3152 friend class ASTStmtReader;
3153 friend class OMPExecutableDirective;
3154 /// Build directive with the given start and end location.
3155 ///
3156 /// \param StartLoc Starting location of the directive kind.
3157 /// \param EndLoc Ending Location of the directive.
3158 ///
3159 OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3160 : OMPExecutableDirective(OMPTargetDataDirectiveClass,
3161 llvm::omp::OMPD_target_data, StartLoc, EndLoc) {}
3162
3163 /// Build an empty directive.
3164 ///
3165 explicit OMPTargetDataDirective()
3166 : OMPExecutableDirective(OMPTargetDataDirectiveClass,
3167 llvm::omp::OMPD_target_data, SourceLocation(),
3168 SourceLocation()) {}
3169
3170public:
3171 /// Creates directive with a list of \a Clauses.
3172 ///
3173 /// \param C AST context.
3174 /// \param StartLoc Starting location of the directive kind.
3175 /// \param EndLoc Ending Location of the directive.
3176 /// \param Clauses List of clauses.
3177 /// \param AssociatedStmt Statement, associated with the directive.
3178 ///
3179 static OMPTargetDataDirective *
3180 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3181 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3182
3183 /// Creates an empty directive with the place for \a N clauses.
3184 ///
3185 /// \param C AST context.
3186 /// \param N The number of clauses.
3187 ///
3188 static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
3189 EmptyShell);
3190
3191 static bool classof(const Stmt *T) {
3192 return T->getStmtClass() == OMPTargetDataDirectiveClass;
3193 }
3194};
3195
3196/// This represents '#pragma omp target enter data' directive.
3197///
3198/// \code
3199/// #pragma omp target enter data device(0) if(a) map(b[:])
3200/// \endcode
3201/// In this example directive '#pragma omp target enter data' has clauses
3202/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
3203/// section 'b[:]'.
3204///
3205class OMPTargetEnterDataDirective : public OMPExecutableDirective {
3206 friend class ASTStmtReader;
3207 friend class OMPExecutableDirective;
3208 /// Build directive with the given start and end location.
3209 ///
3210 /// \param StartLoc Starting location of the directive kind.
3211 /// \param EndLoc Ending Location of the directive.
3212 ///
3213 OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3214 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3215 llvm::omp::OMPD_target_enter_data, StartLoc,
3216 EndLoc) {}
3217
3218 /// Build an empty directive.
3219 ///
3220 explicit OMPTargetEnterDataDirective()
3221 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3222 llvm::omp::OMPD_target_enter_data,
3223 SourceLocation(), SourceLocation()) {}
3224
3225public:
3226 /// Creates directive with a list of \a Clauses.
3227 ///
3228 /// \param C AST context.
3229 /// \param StartLoc Starting location of the directive kind.
3230 /// \param EndLoc Ending Location of the directive.
3231 /// \param Clauses List of clauses.
3232 /// \param AssociatedStmt Statement, associated with the directive.
3233 ///
3234 static OMPTargetEnterDataDirective *
3235 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3236 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3237
3238 /// Creates an empty directive with the place for \a N clauses.
3239 ///
3240 /// \param C AST context.
3241 /// \param N The number of clauses.
3242 ///
3243 static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C,
3244 unsigned N, EmptyShell);
3245
3246 static bool classof(const Stmt *T) {
3247 return T->getStmtClass() == OMPTargetEnterDataDirectiveClass;
3248 }
3249};
3250
3251/// This represents '#pragma omp target exit data' directive.
3252///
3253/// \code
3254/// #pragma omp target exit data device(0) if(a) map(b[:])
3255/// \endcode
3256/// In this example directive '#pragma omp target exit data' has clauses
3257/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
3258/// section 'b[:]'.
3259///
3260class OMPTargetExitDataDirective : public OMPExecutableDirective {
3261 friend class ASTStmtReader;
3262 friend class OMPExecutableDirective;
3263 /// Build directive with the given start and end location.
3264 ///
3265 /// \param StartLoc Starting location of the directive kind.
3266 /// \param EndLoc Ending Location of the directive.
3267 ///
3268 OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3269 : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3270 llvm::omp::OMPD_target_exit_data, StartLoc,
3271 EndLoc) {}
3272
3273 /// Build an empty directive.
3274 ///
3275 explicit OMPTargetExitDataDirective()
3276 : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3277 llvm::omp::OMPD_target_exit_data,
3278 SourceLocation(), SourceLocation()) {}
3279
3280public:
3281 /// Creates directive with a list of \a Clauses.
3282 ///
3283 /// \param C AST context.
3284 /// \param StartLoc Starting location of the directive kind.
3285 /// \param EndLoc Ending Location of the directive.
3286 /// \param Clauses List of clauses.
3287 /// \param AssociatedStmt Statement, associated with the directive.
3288 ///
3289 static OMPTargetExitDataDirective *
3290 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3291 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3292
3293 /// Creates an empty directive with the place for \a N clauses.
3294 ///
3295 /// \param C AST context.
3296 /// \param N The number of clauses.
3297 ///
3298 static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
3299 unsigned N, EmptyShell);
3300
3301 static bool classof(const Stmt *T) {
3302 return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
3303 }
3304};
3305
3306/// This represents '#pragma omp target parallel' directive.
3307///
3308/// \code
3309/// #pragma omp target parallel if(a)
3310/// \endcode
3311/// In this example directive '#pragma omp target parallel' has clause 'if' with
3312/// condition 'a'.
3313///
3314class OMPTargetParallelDirective : public OMPExecutableDirective {
3315 friend class ASTStmtReader;
3316 friend class OMPExecutableDirective;
3317 /// true if the construct has inner cancel directive.
3318 bool HasCancel = false;
3319
3320 /// Build directive with the given start and end location.
3321 ///
3322 /// \param StartLoc Starting location of the directive kind.
3323 /// \param EndLoc Ending location of the directive.
3324 ///
3325 OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3326 : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3327 llvm::omp::OMPD_target_parallel, StartLoc,
3328 EndLoc) {}
3329
3330 /// Build an empty directive.
3331 ///
3332 explicit OMPTargetParallelDirective()
3333 : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3334 llvm::omp::OMPD_target_parallel,
3335 SourceLocation(), SourceLocation()) {}
3336
3337 /// Sets special task reduction descriptor.
3338 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
3339 /// Set cancel state.
3340 void setHasCancel(bool Has) { HasCancel = Has; }
3341
3342public:
3343 /// Creates directive with a list of \a Clauses.
3344 ///
3345 /// \param C AST context.
3346 /// \param StartLoc Starting location of the directive kind.
3347 /// \param EndLoc Ending Location of the directive.
3348 /// \param Clauses List of clauses.
3349 /// \param AssociatedStmt Statement, associated with the directive.
3350 /// \param TaskRedRef Task reduction special reference expression to handle
3351 /// taskgroup descriptor.
3352 /// \param HasCancel true if this directive has inner cancel directive.
3353 ///
3354 static OMPTargetParallelDirective *
3355 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3356 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
3357 bool HasCancel);
3358
3359 /// Creates an empty directive with the place for \a NumClauses
3360 /// clauses.
3361 ///
3362 /// \param C AST context.
3363 /// \param NumClauses Number of clauses.
3364 ///
3365 static OMPTargetParallelDirective *
3366 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
3367
3368 /// Returns special task reduction reference expression.
3369 Expr *getTaskReductionRefExpr() {
3370 return cast_or_null<Expr>(Data->getChildren()[0]);
3371 }
3372 const Expr *getTaskReductionRefExpr() const {
3373 return const_cast<OMPTargetParallelDirective *>(this)
3374 ->getTaskReductionRefExpr();
3375 }
3376
3377 /// Return true if current directive has inner cancel directive.
3378 bool hasCancel() const { return HasCancel; }
3379
3380 static bool classof(const Stmt *T) {
3381 return T->getStmtClass() == OMPTargetParallelDirectiveClass;
3382 }
3383};
3384
3385/// This represents '#pragma omp target parallel for' directive.
3386///
3387/// \code
3388/// #pragma omp target parallel for private(a,b) reduction(+:c,d)
3389/// \endcode
3390/// In this example directive '#pragma omp target parallel for' has clauses
3391/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
3392/// and variables 'c' and 'd'.
3393///
3394class OMPTargetParallelForDirective : public OMPLoopDirective {
3395 friend class ASTStmtReader;
3396 friend class OMPExecutableDirective;
3397
3398 /// true if current region has inner cancel directive.
3399 bool HasCancel = false;
3400
3401 /// Build directive with the given start and end location.
3402 ///
3403 /// \param StartLoc Starting location of the directive kind.
3404 /// \param EndLoc Ending location of the directive.
3405 /// \param CollapsedNum Number of collapsed nested loops.
3406 ///
3407 OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3408 unsigned CollapsedNum)
3409 : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3410 llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc,
3411 CollapsedNum) {}
3412
3413 /// Build an empty directive.
3414 ///
3415 /// \param CollapsedNum Number of collapsed nested loops.
3416 ///
3417 explicit OMPTargetParallelForDirective(unsigned CollapsedNum)
3418 : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3419 llvm::omp::OMPD_target_parallel_for, SourceLocation(),
3420 SourceLocation(), CollapsedNum) {}
3421
3422 /// Sets special task reduction descriptor.
3423 void setTaskReductionRefExpr(Expr *E) {
3424 Data->getChildren()[numLoopChildren(
3425 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E;
3426 }
3427
3428 /// Set cancel state.
3429 void setHasCancel(bool Has) { HasCancel = Has; }
3430
3431public:
3432 /// Creates directive with a list of \a Clauses.
3433 ///
3434 /// \param C AST context.
3435 /// \param StartLoc Starting location of the directive kind.
3436 /// \param EndLoc Ending Location of the directive.
3437 /// \param CollapsedNum Number of collapsed loops.
3438 /// \param Clauses List of clauses.
3439 /// \param AssociatedStmt Statement, associated with the directive.
3440 /// \param Exprs Helper expressions for CodeGen.
3441 /// \param TaskRedRef Task reduction special reference expression to handle
3442 /// taskgroup descriptor.
3443 /// \param HasCancel true if current directive has inner cancel directive.
3444 ///
3445 static OMPTargetParallelForDirective *
3446 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3447 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3448 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
3449 bool HasCancel);
3450
3451 /// Creates an empty directive with the place
3452 /// for \a NumClauses clauses.
3453 ///
3454 /// \param C AST context.
3455 /// \param CollapsedNum Number of collapsed nested loops.
3456 /// \param NumClauses Number of clauses.
3457 ///
3458 static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C,
3459 unsigned NumClauses,
3460 unsigned CollapsedNum,
3461 EmptyShell);
3462
3463 /// Returns special task reduction reference expression.
3464 Expr *getTaskReductionRefExpr() {
3465 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
3466 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]);
3467 }
3468 const Expr *getTaskReductionRefExpr() const {
3469 return const_cast<OMPTargetParallelForDirective *>(this)
3470 ->getTaskReductionRefExpr();
3471 }
3472
3473 /// Return true if current directive has inner cancel directive.
3474 bool hasCancel() const { return HasCancel; }
3475
3476 static bool classof(const Stmt *T) {
3477 return T->getStmtClass() == OMPTargetParallelForDirectiveClass;
3478 }
3479};
3480
3481/// This represents '#pragma omp teams' directive.
3482///
3483/// \code
3484/// #pragma omp teams if(a)
3485/// \endcode
3486/// In this example directive '#pragma omp teams' has clause 'if' with
3487/// condition 'a'.
3488///
3489class OMPTeamsDirective : public OMPExecutableDirective {
3490 friend class ASTStmtReader;
3491 friend class OMPExecutableDirective;
3492 /// Build directive with the given start and end location.
3493 ///
3494 /// \param StartLoc Starting location of the directive kind.
3495 /// \param EndLoc Ending location of the directive.
3496 ///
3497 OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3498 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3499 StartLoc, EndLoc) {}
3500
3501 /// Build an empty directive.
3502 ///
3503 explicit OMPTeamsDirective()
3504 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3505 SourceLocation(), SourceLocation()) {}
3506
3507public:
3508 /// Creates directive with a list of \a Clauses.
3509 ///
3510 /// \param C AST context.
3511 /// \param StartLoc Starting location of the directive kind.
3512 /// \param EndLoc Ending Location of the directive.
3513 /// \param Clauses List of clauses.
3514 /// \param AssociatedStmt Statement, associated with the directive.
3515 ///
3516 static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
3517 SourceLocation EndLoc,
3518 ArrayRef<OMPClause *> Clauses,
3519 Stmt *AssociatedStmt);
3520
3521 /// Creates an empty directive with the place for \a NumClauses
3522 /// clauses.
3523 ///
3524 /// \param C AST context.
3525 /// \param NumClauses Number of clauses.
3526 ///
3527 static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
3528 unsigned NumClauses, EmptyShell);
3529
3530 static bool classof(const Stmt *T) {
3531 return T->getStmtClass() == OMPTeamsDirectiveClass;
3532 }
3533};
3534
3535/// This represents '#pragma omp cancellation point' directive.
3536///
3537/// \code
3538/// #pragma omp cancellation point for
3539/// \endcode
3540///
3541/// In this example a cancellation point is created for innermost 'for' region.
3542class OMPCancellationPointDirective : public OMPExecutableDirective {
3543 friend class ASTStmtReader;
3544 friend class OMPExecutableDirective;
3545 OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
3546 /// Build directive with the given start and end location.
3547 ///
3548 /// \param StartLoc Starting location of the directive kind.
3549 /// \param EndLoc Ending location of the directive.
3550 /// statements and child expressions.
3551 ///
3552 OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3553 : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3554 llvm::omp::OMPD_cancellation_point, StartLoc,
3555 EndLoc) {}
3556
3557 /// Build an empty directive.
3558 explicit OMPCancellationPointDirective()
3559 : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3560 llvm::omp::OMPD_cancellation_point,
3561 SourceLocation(), SourceLocation()) {}
3562
3563 /// Set cancel region for current cancellation point.
3564 /// \param CR Cancellation region.
3565 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
3566
3567public:
3568 /// Creates directive.
3569 ///
3570 /// \param C AST context.
3571 /// \param StartLoc Starting location of the directive kind.
3572 /// \param EndLoc Ending Location of the directive.
3573 ///
3574 static OMPCancellationPointDirective *
3575 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3576 OpenMPDirectiveKind CancelRegion);
3577
3578 /// Creates an empty directive.
3579 ///
3580 /// \param C AST context.
3581 ///
3582 static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
3583 EmptyShell);
3584
3585 /// Get cancellation region for the current cancellation point.
3586 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
3587
3588 static bool classof(const Stmt *T) {
3589 return T->getStmtClass() == OMPCancellationPointDirectiveClass;
3590 }
3591};
3592
3593/// This represents '#pragma omp cancel' directive.
3594///
3595/// \code
3596/// #pragma omp cancel for
3597/// \endcode
3598///
3599/// In this example a cancel is created for innermost 'for' region.
3600class OMPCancelDirective : public OMPExecutableDirective {
3601 friend class ASTStmtReader;
3602 friend class OMPExecutableDirective;
3603 OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
3604 /// Build directive with the given start and end location.
3605 ///
3606 /// \param StartLoc Starting location of the directive kind.
3607 /// \param EndLoc Ending location of the directive.
3608 ///
3609 OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3610 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3611 StartLoc, EndLoc) {}
3612
3613 /// Build an empty directive.
3614 ///
3615 explicit OMPCancelDirective()
3616 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3617 SourceLocation(), SourceLocation()) {}
3618
3619 /// Set cancel region for current cancellation point.
3620 /// \param CR Cancellation region.
3621 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
3622
3623public:
3624 /// Creates directive.
3625 ///
3626 /// \param C AST context.
3627 /// \param StartLoc Starting location of the directive kind.
3628 /// \param EndLoc Ending Location of the directive.
3629 /// \param Clauses List of clauses.
3630 ///
3631 static OMPCancelDirective *
3632 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3633 ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
3634
3635 /// Creates an empty directive.
3636 ///
3637 /// \param C AST context.
3638 /// \param NumClauses Number of clauses.
3639 ///
3640 static OMPCancelDirective *CreateEmpty(const ASTContext &C,
3641 unsigned NumClauses, EmptyShell);
3642
3643 /// Get cancellation region for the current cancellation point.
3644 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
3645
3646 static bool classof(const Stmt *T) {
3647 return T->getStmtClass() == OMPCancelDirectiveClass;
3648 }
3649};
3650
3651/// This represents '#pragma omp taskloop' directive.
3652///
3653/// \code
3654/// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
3655/// \endcode
3656/// In this example directive '#pragma omp taskloop' has clauses 'private'
3657/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
3658/// 'num_tasks' with expression 'num'.
3659///
3660class OMPTaskLoopDirective : public OMPLoopDirective {
3661 friend class ASTStmtReader;
3662 friend class OMPExecutableDirective;
3663 /// true if the construct has inner cancel directive.
3664 bool HasCancel = false;
3665
3666 /// Build directive with the given start and end location.
3667 ///
3668 /// \param StartLoc Starting location of the directive kind.
3669 /// \param EndLoc Ending location of the directive.
3670 /// \param CollapsedNum Number of collapsed nested loops.
3671 ///
3672 OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3673 unsigned CollapsedNum)
3674 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3675 StartLoc, EndLoc, CollapsedNum) {}
3676
3677 /// Build an empty directive.
3678 ///
3679 /// \param CollapsedNum Number of collapsed nested loops.
3680 ///
3681 explicit OMPTaskLoopDirective(unsigned CollapsedNum)
3682 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3683 SourceLocation(), SourceLocation(), CollapsedNum) {}
3684
3685 /// Set cancel state.
3686 void setHasCancel(bool Has) { HasCancel = Has; }
3687
3688public:
3689 /// Creates directive with a list of \a Clauses.
3690 ///
3691 /// \param C AST context.
3692 /// \param StartLoc Starting location of the directive kind.
3693 /// \param EndLoc Ending Location of the directive.
3694 /// \param CollapsedNum Number of collapsed loops.
3695 /// \param Clauses List of clauses.
3696 /// \param AssociatedStmt Statement, associated with the directive.
3697 /// \param Exprs Helper expressions for CodeGen.
3698 /// \param HasCancel true if this directive has inner cancel directive.
3699 ///
3700 static OMPTaskLoopDirective *
3701 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3702 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3703 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3704
3705 /// Creates an empty directive with the place
3706 /// for \a NumClauses clauses.
3707 ///
3708 /// \param C AST context.
3709 /// \param CollapsedNum Number of collapsed nested loops.
3710 /// \param NumClauses Number of clauses.
3711 ///
3712 static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
3713 unsigned NumClauses,
3714 unsigned CollapsedNum, EmptyShell);
3715
3716 /// Return true if current directive has inner cancel directive.
3717 bool hasCancel() const { return HasCancel; }
3718
3719 static bool classof(const Stmt *T) {
3720 return T->getStmtClass() == OMPTaskLoopDirectiveClass;
3721 }
3722};
3723
3724/// This represents '#pragma omp taskloop simd' directive.
3725///
3726/// \code
3727/// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
3728/// \endcode
3729/// In this example directive '#pragma omp taskloop simd' has clauses 'private'
3730/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
3731/// 'num_tasks' with expression 'num'.
3732///
3733class OMPTaskLoopSimdDirective : public OMPLoopDirective {
3734 friend class ASTStmtReader;
3735 friend class OMPExecutableDirective;
3736 /// Build directive with the given start and end location.
3737 ///
3738 /// \param StartLoc Starting location of the directive kind.
3739 /// \param EndLoc Ending location of the directive.
3740 /// \param CollapsedNum Number of collapsed nested loops.
3741 ///
3742 OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3743 unsigned CollapsedNum)
3744 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3745 llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc,
3746 CollapsedNum) {}
3747
3748 /// Build an empty directive.
3749 ///
3750 /// \param CollapsedNum Number of collapsed nested loops.
3751 ///
3752 explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum)
3753 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3754 llvm::omp::OMPD_taskloop_simd, SourceLocation(),
3755 SourceLocation(), CollapsedNum) {}
3756
3757public:
3758 /// Creates directive with a list of \a Clauses.
3759 ///
3760 /// \param C AST context.
3761 /// \param StartLoc Starting location of the directive kind.
3762 /// \param EndLoc Ending Location of the directive.
3763 /// \param CollapsedNum Number of collapsed loops.
3764 /// \param Clauses List of clauses.
3765 /// \param AssociatedStmt Statement, associated with the directive.
3766 /// \param Exprs Helper expressions for CodeGen.
3767 ///
3768 static OMPTaskLoopSimdDirective *
3769 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3770 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3771 Stmt *AssociatedStmt, const HelperExprs &Exprs);
3772
3773 /// Creates an empty directive with the place
3774 /// for \a NumClauses clauses.
3775 ///
3776 /// \param C AST context.
3777 /// \param CollapsedNum Number of collapsed nested loops.
3778 /// \param NumClauses Number of clauses.
3779 ///
3780 static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
3781 unsigned NumClauses,
3782 unsigned CollapsedNum,
3783 EmptyShell);
3784
3785 static bool classof(const Stmt *T) {
3786 return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
3787 }
3788};
3789
3790/// This represents '#pragma omp master taskloop' directive.
3791///
3792/// \code
3793/// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num)
3794/// \endcode
3795/// In this example directive '#pragma omp master taskloop' has clauses
3796/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3797/// and 'num_tasks' with expression 'num'.
3798///
3799class OMPMasterTaskLoopDirective : public OMPLoopDirective {
3800 friend class ASTStmtReader;
3801 friend class OMPExecutableDirective;
3802 /// true if the construct has inner cancel directive.
3803 bool HasCancel = false;
3804
3805 /// Build directive with the given start and end location.
3806 ///
3807 /// \param StartLoc Starting location of the directive kind.
3808 /// \param EndLoc Ending location of the directive.
3809 /// \param CollapsedNum Number of collapsed nested loops.
3810 ///
3811 OMPMasterTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3812 unsigned CollapsedNum)
3813 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3814 llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc,
3815 CollapsedNum) {}
3816
3817 /// Build an empty directive.
3818 ///
3819 /// \param CollapsedNum Number of collapsed nested loops.
3820 ///
3821 explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum)
3822 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3823 llvm::omp::OMPD_master_taskloop, SourceLocation(),
3824 SourceLocation(), CollapsedNum) {}
3825
3826 /// Set cancel state.
3827 void setHasCancel(bool Has) { HasCancel = Has; }
3828
3829public:
3830 /// Creates directive with a list of \a Clauses.
3831 ///
3832 /// \param C AST context.
3833 /// \param StartLoc Starting location of the directive kind.
3834 /// \param EndLoc Ending Location of the directive.
3835 /// \param CollapsedNum Number of collapsed loops.
3836 /// \param Clauses List of clauses.
3837 /// \param AssociatedStmt Statement, associated with the directive.
3838 /// \param Exprs Helper expressions for CodeGen.
3839 /// \param HasCancel true if this directive has inner cancel directive.
3840 ///
3841 static OMPMasterTaskLoopDirective *
3842 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3843 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3844 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3845
3846 /// Creates an empty directive with the place
3847 /// for \a NumClauses clauses.
3848 ///
3849 /// \param C AST context.
3850 /// \param CollapsedNum Number of collapsed nested loops.
3851 /// \param NumClauses Number of clauses.
3852 ///
3853 static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
3854 unsigned NumClauses,
3855 unsigned CollapsedNum,
3856 EmptyShell);
3857
3858 /// Return true if current directive has inner cancel directive.
3859 bool hasCancel() const { return HasCancel; }
3860
3861 static bool classof(const Stmt *T) {
3862 return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass;
3863 }
3864};
3865
3866/// This represents '#pragma omp masked taskloop' directive.
3867///
3868/// \code
3869/// #pragma omp masked taskloop private(a,b) grainsize(val) num_tasks(num)
3870/// \endcode
3871/// In this example directive '#pragma omp masked taskloop' has clauses
3872/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3873/// and 'num_tasks' with expression 'num'.
3874///
3875class OMPMaskedTaskLoopDirective final : public OMPLoopDirective {
3876 friend class ASTStmtReader;
3877 friend class OMPExecutableDirective;
3878 /// true if the construct has inner cancel directive.
3879 bool HasCancel = false;
3880
3881 /// Build directive with the given start and end location.
3882 ///
3883 /// \param StartLoc Starting location of the directive kind.
3884 /// \param EndLoc Ending location of the directive.
3885 /// \param CollapsedNum Number of collapsed nested loops.
3886 ///
3887 OMPMaskedTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3888 unsigned CollapsedNum)
3889 : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
3890 llvm::omp::OMPD_masked_taskloop, StartLoc, EndLoc,
3891 CollapsedNum) {}
3892
3893 /// Build an empty directive.
3894 ///
3895 /// \param CollapsedNum Number of collapsed nested loops.
3896 ///
3897 explicit OMPMaskedTaskLoopDirective(unsigned CollapsedNum)
3898 : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
3899 llvm::omp::OMPD_masked_taskloop, SourceLocation(),
3900 SourceLocation(), CollapsedNum) {}
3901
3902 /// Set cancel state.
3903 void setHasCancel(bool Has) { HasCancel = Has; }
3904
3905public:
3906 /// Creates directive with a list of \a Clauses.
3907 ///
3908 /// \param C AST context.
3909 /// \param StartLoc Starting location of the directive kind.
3910 /// \param EndLoc Ending Location of the directive.
3911 /// \param CollapsedNum Number of collapsed loops.
3912 /// \param Clauses List of clauses.
3913 /// \param AssociatedStmt Statement, associated with the directive.
3914 /// \param Exprs Helper expressions for CodeGen.
3915 /// \param HasCancel true if this directive has inner cancel directive.
3916 ///
3917 static OMPMaskedTaskLoopDirective *
3918 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3919 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3920 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3921
3922 /// Creates an empty directive with the place
3923 /// for \a NumClauses clauses.
3924 ///
3925 /// \param C AST context.
3926 /// \param CollapsedNum Number of collapsed nested loops.
3927 /// \param NumClauses Number of clauses.
3928 ///
3929 static OMPMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
3930 unsigned NumClauses,
3931 unsigned CollapsedNum,
3932 EmptyShell);
3933
3934 /// Return true if current directive has inner cancel directive.
3935 bool hasCancel() const { return HasCancel; }
3936
3937 static bool classof(const Stmt *T) {
3938 return T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass;
3939 }
3940};
3941
3942/// This represents '#pragma omp master taskloop simd' directive.
3943///
3944/// \code
3945/// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num)
3946/// \endcode
3947/// In this example directive '#pragma omp master taskloop simd' has clauses
3948/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3949/// and 'num_tasks' with expression 'num'.
3950///
3951class OMPMasterTaskLoopSimdDirective : public OMPLoopDirective {
3952 friend class ASTStmtReader;
3953 friend class OMPExecutableDirective;
3954 /// Build directive with the given start and end location.
3955 ///
3956 /// \param StartLoc Starting location of the directive kind.
3957 /// \param EndLoc Ending location of the directive.
3958 /// \param CollapsedNum Number of collapsed nested loops.
3959 ///
3960 OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3961 unsigned CollapsedNum)
3962 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
3963 llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc,
3964 CollapsedNum) {}
3965
3966 /// Build an empty directive.
3967 ///
3968 /// \param CollapsedNum Number of collapsed nested loops.
3969 ///
3970 explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum)
3971 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
3972 llvm::omp::OMPD_master_taskloop_simd, SourceLocation(),
3973 SourceLocation(), CollapsedNum) {}
3974
3975public:
3976 /// Creates directive with a list of \p Clauses.
3977 ///
3978 /// \param C AST context.
3979 /// \param StartLoc Starting location of the directive kind.
3980 /// \param EndLoc Ending Location of the directive.
3981 /// \param CollapsedNum Number of collapsed loops.
3982 /// \param Clauses List of clauses.
3983 /// \param AssociatedStmt Statement, associated with the directive.
3984 /// \param Exprs Helper expressions for CodeGen.
3985 ///
3986 static OMPMasterTaskLoopSimdDirective *
3987 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3988 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3989 Stmt *AssociatedStmt, const HelperExprs &Exprs);
3990
3991 /// Creates an empty directive with the place for \p NumClauses clauses.
3992 ///
3993 /// \param C AST context.
3994 /// \param CollapsedNum Number of collapsed nested loops.
3995 /// \param NumClauses Number of clauses.
3996 ///
3997 static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
3998 unsigned NumClauses,
3999 unsigned CollapsedNum,
4000 EmptyShell);
4001
4002 static bool classof(const Stmt *T) {
4003 return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass;
4004 }
4005};
4006
4007/// This represents '#pragma omp masked taskloop simd' directive.
4008///
4009/// \code
4010/// #pragma omp masked taskloop simd private(a,b) grainsize(val) num_tasks(num)
4011/// \endcode
4012/// In this example directive '#pragma omp masked taskloop simd' has clauses
4013/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4014/// and 'num_tasks' with expression 'num'.
4015///
4016class OMPMaskedTaskLoopSimdDirective final : public OMPLoopDirective {
4017 friend class ASTStmtReader;
4018 friend class OMPExecutableDirective;
4019 /// Build directive with the given start and end location.
4020 ///
4021 /// \param StartLoc Starting location of the directive kind.
4022 /// \param EndLoc Ending location of the directive.
4023 /// \param CollapsedNum Number of collapsed nested loops.
4024 ///
4025 OMPMaskedTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4026 unsigned CollapsedNum)
4027 : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
4028 llvm::omp::OMPD_masked_taskloop_simd, StartLoc, EndLoc,
4029 CollapsedNum) {}
4030
4031 /// Build an empty directive.
4032 ///
4033 /// \param CollapsedNum Number of collapsed nested loops.
4034 ///
4035 explicit OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
4036 : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
4037 llvm::omp::OMPD_masked_taskloop_simd, SourceLocation(),
4038 SourceLocation(), CollapsedNum) {}
4039
4040public:
4041 /// Creates directive with a list of \p Clauses.
4042 ///
4043 /// \param C AST context.
4044 /// \param StartLoc Starting location of the directive kind.
4045 /// \param EndLoc Ending Location of the directive.
4046 /// \param CollapsedNum Number of collapsed loops.
4047 /// \param Clauses List of clauses.
4048 /// \param AssociatedStmt Statement, associated with the directive.
4049 /// \param Exprs Helper expressions for CodeGen.
4050 ///
4051 static OMPMaskedTaskLoopSimdDirective *
4052 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4053 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4054 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4055
4056 /// Creates an empty directive with the place for \p NumClauses clauses.
4057 ///
4058 /// \param C AST context.
4059 /// \param CollapsedNum Number of collapsed nested loops.
4060 /// \param NumClauses Number of clauses.
4061 ///
4062 static OMPMaskedTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
4063 unsigned NumClauses,
4064 unsigned CollapsedNum,
4065 EmptyShell);
4066
4067 static bool classof(const Stmt *T) {
4068 return T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass;
4069 }
4070};
4071
4072/// This represents '#pragma omp parallel master taskloop' directive.
4073///
4074/// \code
4075/// #pragma omp parallel master taskloop private(a,b) grainsize(val)
4076/// num_tasks(num)
4077/// \endcode
4078/// In this example directive '#pragma omp parallel master taskloop' has clauses
4079/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4080/// and 'num_tasks' with expression 'num'.
4081///
4082class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective {
4083 friend class ASTStmtReader;
4084 friend class OMPExecutableDirective;
4085 /// true if the construct has inner cancel directive.
4086 bool HasCancel = false;
4087
4088 /// Build directive with the given start and end location.
4089 ///
4090 /// \param StartLoc Starting location of the directive kind.
4091 /// \param EndLoc Ending location of the directive.
4092 /// \param CollapsedNum Number of collapsed nested loops.
4093 ///
4094 OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc,
4095 SourceLocation EndLoc,
4096 unsigned CollapsedNum)
4097 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
4098 llvm::omp::OMPD_parallel_master_taskloop, StartLoc,
4099 EndLoc, CollapsedNum) {}
4100
4101 /// Build an empty directive.
4102 ///
4103 /// \param CollapsedNum Number of collapsed nested loops.
4104 ///
4105 explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum)
4106 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
4107 llvm::omp::OMPD_parallel_master_taskloop,
4108 SourceLocation(), SourceLocation(), CollapsedNum) {}
4109
4110 /// Set cancel state.
4111 void setHasCancel(bool Has) { HasCancel = Has; }
4112
4113public:
4114 /// Creates directive with a list of \a Clauses.
4115 ///
4116 /// \param C AST context.
4117 /// \param StartLoc Starting location of the directive kind.
4118 /// \param EndLoc Ending Location of the directive.
4119 /// \param CollapsedNum Number of collapsed loops.
4120 /// \param Clauses List of clauses.
4121 /// \param AssociatedStmt Statement, associated with the directive.
4122 /// \param Exprs Helper expressions for CodeGen.
4123 /// \param HasCancel true if this directive has inner cancel directive.
4124 ///
4125 static OMPParallelMasterTaskLoopDirective *
4126 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4127 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4128 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
4129
4130 /// Creates an empty directive with the place
4131 /// for \a NumClauses clauses.
4132 ///
4133 /// \param C AST context.
4134 /// \param CollapsedNum Number of collapsed nested loops.
4135 /// \param NumClauses Number of clauses.
4136 ///
4137 static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
4138 unsigned NumClauses,
4139 unsigned CollapsedNum,
4140 EmptyShell);
4141
4142 /// Return true if current directive has inner cancel directive.
4143 bool hasCancel() const { return HasCancel; }
4144
4145 static bool classof(const Stmt *T) {
4146 return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass;
4147 }
4148};
4149
4150/// This represents '#pragma omp parallel masked taskloop' directive.
4151///
4152/// \code
4153/// #pragma omp parallel masked taskloop private(a,b) grainsize(val)
4154/// num_tasks(num)
4155/// \endcode
4156/// In this example directive '#pragma omp parallel masked taskloop' has clauses
4157/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4158/// and 'num_tasks' with expression 'num'.
4159///
4160class OMPParallelMaskedTaskLoopDirective final : public OMPLoopDirective {
4161 friend class ASTStmtReader;
4162 friend class OMPExecutableDirective;
4163 /// true if the construct has inner cancel directive.
4164 bool HasCancel = false;
4165
4166 /// Build directive with the given start and end location.
4167 ///
4168 /// \param StartLoc Starting location of the directive kind.
4169 /// \param EndLoc Ending location of the directive.
4170 /// \param CollapsedNum Number of collapsed nested loops.
4171 ///
4172 OMPParallelMaskedTaskLoopDirective(SourceLocation StartLoc,
4173 SourceLocation EndLoc,
4174 unsigned CollapsedNum)
4175 : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
4176 llvm::omp::OMPD_parallel_masked_taskloop, StartLoc,
4177 EndLoc, CollapsedNum) {}
4178
4179 /// Build an empty directive.
4180 ///
4181 /// \param CollapsedNum Number of collapsed nested loops.
4182 ///
4183 explicit OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum)
4184 : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
4185 llvm::omp::OMPD_parallel_masked_taskloop,
4186 SourceLocation(), SourceLocation(), CollapsedNum) {}
4187
4188 /// Set cancel state.
4189 void setHasCancel(bool Has) { HasCancel = Has; }
4190
4191public:
4192 /// Creates directive with a list of \a Clauses.
4193 ///
4194 /// \param C AST context.
4195 /// \param StartLoc Starting location of the directive kind.
4196 /// \param EndLoc Ending Location of the directive.
4197 /// \param CollapsedNum Number of collapsed loops.
4198 /// \param Clauses List of clauses.
4199 /// \param AssociatedStmt Statement, associated with the directive.
4200 /// \param Exprs Helper expressions for CodeGen.
4201 /// \param HasCancel true if this directive has inner cancel directive.
4202 ///
4203 static OMPParallelMaskedTaskLoopDirective *
4204 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4205 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4206 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
4207
4208 /// Creates an empty directive with the place
4209 /// for \a NumClauses clauses.
4210 ///
4211 /// \param C AST context.
4212 /// \param CollapsedNum Number of collapsed nested loops.
4213 /// \param NumClauses Number of clauses.
4214 ///
4215 static OMPParallelMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
4216 unsigned NumClauses,
4217 unsigned CollapsedNum,
4218 EmptyShell);
4219
4220 /// Return true if current directive has inner cancel directive.
4221 bool hasCancel() const { return HasCancel; }
4222
4223 static bool classof(const Stmt *T) {
4224 return T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass;
4225 }
4226};
4227
4228/// This represents '#pragma omp parallel master taskloop simd' directive.
4229///
4230/// \code
4231/// #pragma omp parallel master taskloop simd private(a,b) grainsize(val)
4232/// num_tasks(num)
4233/// \endcode
4234/// In this example directive '#pragma omp parallel master taskloop simd' has
4235/// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
4236/// expression 'val' and 'num_tasks' with expression 'num'.
4237///
4238class OMPParallelMasterTaskLoopSimdDirective : public OMPLoopDirective {
4239 friend class ASTStmtReader;
4240 friend class OMPExecutableDirective;
4241 /// Build directive with the given start and end location.
4242 ///
4243 /// \param StartLoc Starting location of the directive kind.
4244 /// \param EndLoc Ending location of the directive.
4245 /// \param CollapsedNum Number of collapsed nested loops.
4246 ///
4247 OMPParallelMasterTaskLoopSimdDirective(SourceLocation StartLoc,
4248 SourceLocation EndLoc,
4249 unsigned CollapsedNum)
4250 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
4251 llvm::omp::OMPD_parallel_master_taskloop_simd,
4252 StartLoc, EndLoc, CollapsedNum) {}
4253
4254 /// Build an empty directive.
4255 ///
4256 /// \param CollapsedNum Number of collapsed nested loops.
4257 ///
4258 explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum)
4259 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
4260 llvm::omp::OMPD_parallel_master_taskloop_simd,
4261 SourceLocation(), SourceLocation(), CollapsedNum) {}
4262
4263public:
4264 /// Creates directive with a list of \p Clauses.
4265 ///
4266 /// \param C AST context.
4267 /// \param StartLoc Starting location of the directive kind.
4268 /// \param EndLoc Ending Location of the directive.
4269 /// \param CollapsedNum Number of collapsed loops.
4270 /// \param Clauses List of clauses.
4271 /// \param AssociatedStmt Statement, associated with the directive.
4272 /// \param Exprs Helper expressions for CodeGen.
4273 ///
4274 static OMPParallelMasterTaskLoopSimdDirective *
4275 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4276 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4277 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4278
4279 /// Creates an empty directive with the place
4280 /// for \a NumClauses clauses.
4281 ///
4282 /// \param C AST context.
4283 /// \param CollapsedNum Number of collapsed nested loops.
4284 /// \param NumClauses Number of clauses.
4285 ///
4286 static OMPParallelMasterTaskLoopSimdDirective *
4287 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4288 EmptyShell);
4289
4290 static bool classof(const Stmt *T) {
4291 return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass;
4292 }
4293};
4294
4295/// This represents '#pragma omp parallel masked taskloop simd' directive.
4296///
4297/// \code
4298/// #pragma omp parallel masked taskloop simd private(a,b) grainsize(val)
4299/// num_tasks(num)
4300/// \endcode
4301/// In this example directive '#pragma omp parallel masked taskloop simd' has
4302/// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
4303/// expression 'val' and 'num_tasks' with expression 'num'.
4304///
4305class OMPParallelMaskedTaskLoopSimdDirective final : public OMPLoopDirective {
4306 friend class ASTStmtReader;
4307 friend class OMPExecutableDirective;
4308 /// Build directive with the given start and end location.
4309 ///
4310 /// \param StartLoc Starting location of the directive kind.
4311 /// \param EndLoc Ending location of the directive.
4312 /// \param CollapsedNum Number of collapsed nested loops.
4313 ///
4314 OMPParallelMaskedTaskLoopSimdDirective(SourceLocation StartLoc,
4315 SourceLocation EndLoc,
4316 unsigned CollapsedNum)
4317 : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
4318 llvm::omp::OMPD_parallel_masked_taskloop_simd,
4319 StartLoc, EndLoc, CollapsedNum) {}
4320
4321 /// Build an empty directive.
4322 ///
4323 /// \param CollapsedNum Number of collapsed nested loops.
4324 ///
4325 explicit OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
4326 : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
4327 llvm::omp::OMPD_parallel_masked_taskloop_simd,
4328 SourceLocation(), SourceLocation(), CollapsedNum) {}
4329
4330public:
4331 /// Creates directive with a list of \p Clauses.
4332 ///
4333 /// \param C AST context.
4334 /// \param StartLoc Starting location of the directive kind.
4335 /// \param EndLoc Ending Location of the directive.
4336 /// \param CollapsedNum Number of collapsed loops.
4337 /// \param Clauses List of clauses.
4338 /// \param AssociatedStmt Statement, associated with the directive.
4339 /// \param Exprs Helper expressions for CodeGen.
4340 ///
4341 static OMPParallelMaskedTaskLoopSimdDirective *
4342 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4343 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4344 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4345
4346 /// Creates an empty directive with the place
4347 /// for \a NumClauses clauses.
4348 ///
4349 /// \param C AST context.
4350 /// \param CollapsedNum Number of collapsed nested loops.
4351 /// \param NumClauses Number of clauses.
4352 ///
4353 static OMPParallelMaskedTaskLoopSimdDirective *
4354 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4355 EmptyShell);
4356
4357 static bool classof(const Stmt *T) {
4358 return T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass;
4359 }
4360};
4361
4362/// This represents '#pragma omp distribute' directive.
4363///
4364/// \code
4365/// #pragma omp distribute private(a,b)
4366/// \endcode
4367/// In this example directive '#pragma omp distribute' has clauses 'private'
4368/// with the variables 'a' and 'b'
4369///
4370class OMPDistributeDirective : public OMPLoopDirective {
4371 friend class ASTStmtReader;
4372 friend class OMPExecutableDirective;
4373
4374 /// Build directive with the given start and end location.
4375 ///
4376 /// \param StartLoc Starting location of the directive kind.
4377 /// \param EndLoc Ending location of the directive.
4378 /// \param CollapsedNum Number of collapsed nested loops.
4379 ///
4380 OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4381 unsigned CollapsedNum)
4382 : OMPLoopDirective(OMPDistributeDirectiveClass,
4383 llvm::omp::OMPD_distribute, StartLoc, EndLoc,
4384 CollapsedNum) {}
4385
4386 /// Build an empty directive.
4387 ///
4388 /// \param CollapsedNum Number of collapsed nested loops.
4389 ///
4390 explicit OMPDistributeDirective(unsigned CollapsedNum)
4391 : OMPLoopDirective(OMPDistributeDirectiveClass,
4392 llvm::omp::OMPD_distribute, SourceLocation(),
4393 SourceLocation(), CollapsedNum) {}
4394
4395public:
4396 /// Creates directive with a list of \a Clauses.
4397 ///
4398 /// \param C AST context.
4399 /// \param StartLoc Starting location of the directive kind.
4400 /// \param EndLoc Ending Location of the directive.
4401 /// \param CollapsedNum Number of collapsed loops.
4402 /// \param Clauses List of clauses.
4403 /// \param AssociatedStmt Statement, associated with the directive.
4404 /// \param Exprs Helper expressions for CodeGen.
4405 ///
4406 static OMPDistributeDirective *
4407 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4408 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4409 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4410
4411 /// Creates an empty directive with the place
4412 /// for \a NumClauses clauses.
4413 ///
4414 /// \param C AST context.
4415 /// \param CollapsedNum Number of collapsed nested loops.
4416 /// \param NumClauses Number of clauses.
4417 ///
4418 static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
4419 unsigned NumClauses,
4420 unsigned CollapsedNum, EmptyShell);
4421
4422 static bool classof(const Stmt *T) {
4423 return T->getStmtClass() == OMPDistributeDirectiveClass;
4424 }
4425};
4426
4427/// This represents '#pragma omp target update' directive.
4428///
4429/// \code
4430/// #pragma omp target update to(a) from(b) device(1)
4431/// \endcode
4432/// In this example directive '#pragma omp target update' has clause 'to' with
4433/// argument 'a', clause 'from' with argument 'b' and clause 'device' with
4434/// argument '1'.
4435///
4436class OMPTargetUpdateDirective : public OMPExecutableDirective {
4437 friend class ASTStmtReader;
4438 friend class OMPExecutableDirective;
4439 /// Build directive with the given start and end location.
4440 ///
4441 /// \param StartLoc Starting location of the directive kind.
4442 /// \param EndLoc Ending Location of the directive.
4443 ///
4444 OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc)
4445 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
4446 llvm::omp::OMPD_target_update, StartLoc,
4447 EndLoc) {}
4448
4449 /// Build an empty directive.
4450 ///
4451 explicit OMPTargetUpdateDirective()
4452 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
4453 llvm::omp::OMPD_target_update, SourceLocation(),
4454 SourceLocation()) {}
4455
4456public:
4457 /// Creates directive with a list of \a Clauses.
4458 ///
4459 /// \param C AST context.
4460 /// \param StartLoc Starting location of the directive kind.
4461 /// \param EndLoc Ending Location of the directive.
4462 /// \param Clauses List of clauses.
4463 /// \param AssociatedStmt Statement, associated with the directive.
4464 ///
4465 static OMPTargetUpdateDirective *
4466 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4467 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
4468
4469 /// Creates an empty directive with the place for \a NumClauses
4470 /// clauses.
4471 ///
4472 /// \param C AST context.
4473 /// \param NumClauses The number of clauses.
4474 ///
4475 static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C,
4476 unsigned NumClauses, EmptyShell);
4477
4478 static bool classof(const Stmt *T) {
4479 return T->getStmtClass() == OMPTargetUpdateDirectiveClass;
4480 }
4481};
4482
4483/// This represents '#pragma omp distribute parallel for' composite
4484/// directive.
4485///
4486/// \code
4487/// #pragma omp distribute parallel for private(a,b)
4488/// \endcode
4489/// In this example directive '#pragma omp distribute parallel for' has clause
4490/// 'private' with the variables 'a' and 'b'
4491///
4492class OMPDistributeParallelForDirective : public OMPLoopDirective {
4493 friend class ASTStmtReader;
4494 friend class OMPExecutableDirective;
4495 /// true if the construct has inner cancel directive.
4496 bool HasCancel = false;
4497
4498 /// Build directive with the given start and end location.
4499 ///
4500 /// \param StartLoc Starting location of the directive kind.
4501 /// \param EndLoc Ending location of the directive.
4502 /// \param CollapsedNum Number of collapsed nested loops.
4503 ///
4504 OMPDistributeParallelForDirective(SourceLocation StartLoc,
4505 SourceLocation EndLoc,
4506 unsigned CollapsedNum)
4507 : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4508 llvm::omp::OMPD_distribute_parallel_for, StartLoc,
4509 EndLoc, CollapsedNum) {}
4510
4511 /// Build an empty directive.
4512 ///
4513 /// \param CollapsedNum Number of collapsed nested loops.
4514 ///
4515 explicit OMPDistributeParallelForDirective(unsigned CollapsedNum)
4516 : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4517 llvm::omp::OMPD_distribute_parallel_for,
4518 SourceLocation(), SourceLocation(), CollapsedNum) {}
4519
4520 /// Sets special task reduction descriptor.
4521 void setTaskReductionRefExpr(Expr *E) {
4522 Data->getChildren()[numLoopChildren(
4523 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E;
4524 }
4525
4526 /// Set cancel state.
4527 void setHasCancel(bool Has) { HasCancel = Has; }
4528
4529public:
4530 /// Creates directive with a list of \a Clauses.
4531 ///
4532 /// \param C AST context.
4533 /// \param StartLoc Starting location of the directive kind.
4534 /// \param EndLoc Ending Location of the directive.
4535 /// \param CollapsedNum Number of collapsed loops.
4536 /// \param Clauses List of clauses.
4537 /// \param AssociatedStmt Statement, associated with the directive.
4538 /// \param Exprs Helper expressions for CodeGen.
4539 /// \param TaskRedRef Task reduction special reference expression to handle
4540 /// taskgroup descriptor.
4541 /// \param HasCancel true if this directive has inner cancel directive.
4542 ///
4543 static OMPDistributeParallelForDirective *
4544 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4545 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4546 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
4547 bool HasCancel);
4548
4549 /// Creates an empty directive with the place
4550 /// for \a NumClauses clauses.
4551 ///
4552 /// \param C AST context.
4553 /// \param CollapsedNum Number of collapsed nested loops.
4554 /// \param NumClauses Number of clauses.
4555 ///
4556 static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C,
4557 unsigned NumClauses,
4558 unsigned CollapsedNum,
4559 EmptyShell);
4560
4561 /// Returns special task reduction reference expression.
4562 Expr *getTaskReductionRefExpr() {
4563 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
4564 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]);
4565 }
4566 const Expr *getTaskReductionRefExpr() const {
4567 return const_cast<OMPDistributeParallelForDirective *>(this)
4568 ->getTaskReductionRefExpr();
4569 }
4570
4571 /// Return true if current directive has inner cancel directive.
4572 bool hasCancel() const { return HasCancel; }
4573
4574 static bool classof(const Stmt *T) {
4575 return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
4576 }
4577};
4578
4579/// This represents '#pragma omp distribute parallel for simd' composite
4580/// directive.
4581///
4582/// \code
4583/// #pragma omp distribute parallel for simd private(x)
4584/// \endcode
4585/// In this example directive '#pragma omp distribute parallel for simd' has
4586/// clause 'private' with the variables 'x'
4587///
4588class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective {
4589 friend class ASTStmtReader;
4590 friend class OMPExecutableDirective;
4591
4592 /// Build directive with the given start and end location.
4593 ///
4594 /// \param StartLoc Starting location of the directive kind.
4595 /// \param EndLoc Ending location of the directive.
4596 /// \param CollapsedNum Number of collapsed nested loops.
4597 ///
4598 OMPDistributeParallelForSimdDirective(SourceLocation StartLoc,
4599 SourceLocation EndLoc,
4600 unsigned CollapsedNum)
4601 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4602 llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc,
4603 EndLoc, CollapsedNum) {}
4604
4605 /// Build an empty directive.
4606 ///
4607 /// \param CollapsedNum Number of collapsed nested loops.
4608 ///
4609 explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum)
4610 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4611 llvm::omp::OMPD_distribute_parallel_for_simd,
4612 SourceLocation(), SourceLocation(), CollapsedNum) {}
4613
4614public:
4615 /// Creates directive with a list of \a Clauses.
4616 ///
4617 /// \param C AST context.
4618 /// \param StartLoc Starting location of the directive kind.
4619 /// \param EndLoc Ending Location of the directive.
4620 /// \param CollapsedNum Number of collapsed loops.
4621 /// \param Clauses List of clauses.
4622 /// \param AssociatedStmt Statement, associated with the directive.
4623 /// \param Exprs Helper expressions for CodeGen.
4624 ///
4625 static OMPDistributeParallelForSimdDirective *Create(
4626 const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4627 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4628 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4629
4630 /// Creates an empty directive with the place for \a NumClauses clauses.
4631 ///
4632 /// \param C AST context.
4633 /// \param CollapsedNum Number of collapsed nested loops.
4634 /// \param NumClauses Number of clauses.
4635 ///
4636 static OMPDistributeParallelForSimdDirective *CreateEmpty(
4637 const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4638 EmptyShell);
4639
4640 static bool classof(const Stmt *T) {
4641 return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass;
4642 }
4643};
4644
4645/// This represents '#pragma omp distribute simd' composite directive.
4646///
4647/// \code
4648/// #pragma omp distribute simd private(x)
4649/// \endcode
4650/// In this example directive '#pragma omp distribute simd' has clause
4651/// 'private' with the variables 'x'
4652///
4653class OMPDistributeSimdDirective final : public OMPLoopDirective {
4654 friend class ASTStmtReader;
4655 friend class OMPExecutableDirective;
4656
4657 /// Build directive with the given start and end location.
4658 ///
4659 /// \param StartLoc Starting location of the directive kind.
4660 /// \param EndLoc Ending location of the directive.
4661 /// \param CollapsedNum Number of collapsed nested loops.
4662 ///
4663 OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4664 unsigned CollapsedNum)
4665 : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4666 llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc,
4667 CollapsedNum) {}
4668
4669 /// Build an empty directive.
4670 ///
4671 /// \param CollapsedNum Number of collapsed nested loops.
4672 ///
4673 explicit OMPDistributeSimdDirective(unsigned CollapsedNum)
4674 : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4675 llvm::omp::OMPD_distribute_simd, SourceLocation(),
4676 SourceLocation(), CollapsedNum) {}
4677
4678public:
4679 /// Creates directive with a list of \a Clauses.
4680 ///
4681 /// \param C AST context.
4682 /// \param StartLoc Starting location of the directive kind.
4683 /// \param EndLoc Ending Location of the directive.
4684 /// \param CollapsedNum Number of collapsed loops.
4685 /// \param Clauses List of clauses.
4686 /// \param AssociatedStmt Statement, associated with the directive.
4687 /// \param Exprs Helper expressions for CodeGen.
4688 ///
4689 static OMPDistributeSimdDirective *
4690 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4691 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4692 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4693
4694 /// Creates an empty directive with the place for \a NumClauses clauses.
4695 ///
4696 /// \param C AST context.
4697 /// \param CollapsedNum Number of collapsed nested loops.
4698 /// \param NumClauses Number of clauses.
4699 ///
4700 static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C,
4701 unsigned NumClauses,
4702 unsigned CollapsedNum,
4703 EmptyShell);
4704
4705 static bool classof(const Stmt *T) {
4706 return T->getStmtClass() == OMPDistributeSimdDirectiveClass;
4707 }
4708};
4709
4710/// This represents '#pragma omp target parallel for simd' directive.
4711///
4712/// \code
4713/// #pragma omp target parallel for simd private(a) map(b) safelen(c)
4714/// \endcode
4715/// In this example directive '#pragma omp target parallel for simd' has clauses
4716/// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen'
4717/// with the variable 'c'.
4718///
4719class OMPTargetParallelForSimdDirective final : public OMPLoopDirective {
4720 friend class ASTStmtReader;
4721 friend class OMPExecutableDirective;
4722
4723 /// Build directive with the given start and end location.
4724 ///
4725 /// \param StartLoc Starting location of the directive kind.
4726 /// \param EndLoc Ending location of the directive.
4727 /// \param CollapsedNum Number of collapsed nested loops.
4728 ///
4729 OMPTargetParallelForSimdDirective(SourceLocation StartLoc,
4730 SourceLocation EndLoc,
4731 unsigned CollapsedNum)
4732 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4733 llvm::omp::OMPD_target_parallel_for_simd, StartLoc,
4734 EndLoc, CollapsedNum) {}
4735
4736 /// Build an empty directive.
4737 ///
4738 /// \param CollapsedNum Number of collapsed nested loops.
4739 ///
4740 explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum)
4741 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4742 llvm::omp::OMPD_target_parallel_for_simd,
4743 SourceLocation(), SourceLocation(), CollapsedNum) {}
4744
4745public:
4746 /// Creates directive with a list of \a Clauses.
4747 ///
4748 /// \param C AST context.
4749 /// \param StartLoc Starting location of the directive kind.
4750 /// \param EndLoc Ending Location of the directive.
4751 /// \param CollapsedNum Number of collapsed loops.
4752 /// \param Clauses List of clauses.
4753 /// \param AssociatedStmt Statement, associated with the directive.
4754 /// \param Exprs Helper expressions for CodeGen.
4755 ///
4756 static OMPTargetParallelForSimdDirective *
4757 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4758 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4759 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4760
4761 /// Creates an empty directive with the place for \a NumClauses clauses.
4762 ///
4763 /// \param C AST context.
4764 /// \param CollapsedNum Number of collapsed nested loops.
4765 /// \param NumClauses Number of clauses.
4766 ///
4767 static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C,
4768 unsigned NumClauses,
4769 unsigned CollapsedNum,
4770 EmptyShell);
4771
4772 static bool classof(const Stmt *T) {
4773 return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
4774 }
4775};
4776
4777/// This represents '#pragma omp target simd' directive.
4778///
4779/// \code
4780/// #pragma omp target simd private(a) map(b) safelen(c)
4781/// \endcode
4782/// In this example directive '#pragma omp target simd' has clauses 'private'
4783/// with the variable 'a', 'map' with the variable 'b' and 'safelen' with
4784/// the variable 'c'.
4785///
4786class OMPTargetSimdDirective final : public OMPLoopDirective {
4787 friend class ASTStmtReader;
4788 friend class OMPExecutableDirective;
4789
4790 /// Build directive with the given start and end location.
4791 ///
4792 /// \param StartLoc Starting location of the directive kind.
4793 /// \param EndLoc Ending location of the directive.
4794 /// \param CollapsedNum Number of collapsed nested loops.
4795 ///
4796 OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4797 unsigned CollapsedNum)
4798 : OMPLoopDirective(OMPTargetSimdDirectiveClass,
4799 llvm::omp::OMPD_target_simd, StartLoc, EndLoc,
4800 CollapsedNum) {}
4801
4802 /// Build an empty directive.
4803 ///
4804 /// \param CollapsedNum Number of collapsed nested loops.
4805 ///
4806 explicit OMPTargetSimdDirective(unsigned CollapsedNum)
4807 : OMPLoopDirective(OMPTargetSimdDirectiveClass,
4808 llvm::omp::OMPD_target_simd, SourceLocation(),
4809 SourceLocation(), CollapsedNum) {}
4810
4811public:
4812 /// Creates directive with a list of \a Clauses.
4813 ///
4814 /// \param C AST context.
4815 /// \param StartLoc Starting location of the directive kind.
4816 /// \param EndLoc Ending Location of the directive.
4817 /// \param CollapsedNum Number of collapsed loops.
4818 /// \param Clauses List of clauses.
4819 /// \param AssociatedStmt Statement, associated with the directive.
4820 /// \param Exprs Helper expressions for CodeGen.
4821 ///
4822 static OMPTargetSimdDirective *
4823 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4824 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4825 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4826
4827 /// Creates an empty directive with the place for \a NumClauses clauses.
4828 ///
4829 /// \param C AST context.
4830 /// \param CollapsedNum Number of collapsed nested loops.
4831 /// \param NumClauses Number of clauses.
4832 ///
4833 static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C,
4834 unsigned NumClauses,
4835 unsigned CollapsedNum,
4836 EmptyShell);
4837
4838 static bool classof(const Stmt *T) {
4839 return T->getStmtClass() == OMPTargetSimdDirectiveClass;
4840 }
4841};
4842
4843/// This represents '#pragma omp teams distribute' directive.
4844///
4845/// \code
4846/// #pragma omp teams distribute private(a,b)
4847/// \endcode
4848/// In this example directive '#pragma omp teams distribute' has clauses
4849/// 'private' with the variables 'a' and 'b'
4850///
4851class OMPTeamsDistributeDirective final : public OMPLoopDirective {
4852 friend class ASTStmtReader;
4853 friend class OMPExecutableDirective;
4854
4855 /// Build directive with the given start and end location.
4856 ///
4857 /// \param StartLoc Starting location of the directive kind.
4858 /// \param EndLoc Ending location of the directive.
4859 /// \param CollapsedNum Number of collapsed nested loops.
4860 ///
4861 OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4862 unsigned CollapsedNum)
4863 : OMPLoopDirective(OMPTeamsDistributeDirectiveClass,
4864 llvm::omp::OMPD_teams_distribute, StartLoc, EndLoc,
4865 CollapsedNum) {}
4866
4867 /// Build an empty directive.
4868 ///
4869 /// \param CollapsedNum Number of collapsed nested loops.
4870 ///
4871 explicit OMPTeamsDistributeDirective(unsigned CollapsedNum)
4872 : OMPLoopDirective(OMPTeamsDistributeDirectiveClass,
4873 llvm::omp::OMPD_teams_distribute, SourceLocation(),
4874 SourceLocation(), CollapsedNum) {}
4875
4876public:
4877 /// Creates directive with a list of \a Clauses.
4878 ///
4879 /// \param C AST context.
4880 /// \param StartLoc Starting location of the directive kind.
4881 /// \param EndLoc Ending Location of the directive.
4882 /// \param CollapsedNum Number of collapsed loops.
4883 /// \param Clauses List of clauses.
4884 /// \param AssociatedStmt Statement, associated with the directive.
4885 /// \param Exprs Helper expressions for CodeGen.
4886 ///
4887 static OMPTeamsDistributeDirective *
4888 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4889 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4890 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4891
4892 /// Creates an empty directive with the place for \a NumClauses clauses.
4893 ///
4894 /// \param C AST context.
4895 /// \param CollapsedNum Number of collapsed nested loops.
4896 /// \param NumClauses Number of clauses.
4897 ///
4898 static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C,
4899 unsigned NumClauses,
4900 unsigned CollapsedNum,
4901 EmptyShell);
4902
4903 static bool classof(const Stmt *T) {
4904 return T->getStmtClass() == OMPTeamsDistributeDirectiveClass;
4905 }
4906};
4907
4908/// This represents '#pragma omp teams distribute simd'
4909/// combined directive.
4910///
4911/// \code
4912/// #pragma omp teams distribute simd private(a,b)
4913/// \endcode
4914/// In this example directive '#pragma omp teams distribute simd'
4915/// has clause 'private' with the variables 'a' and 'b'
4916///
4917class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective {
4918 friend class ASTStmtReader;
4919 friend class OMPExecutableDirective;
4920
4921 /// Build directive with the given start and end location.
4922 ///
4923 /// \param StartLoc Starting location of the directive kind.
4924 /// \param EndLoc Ending location of the directive.
4925 /// \param CollapsedNum Number of collapsed nested loops.
4926 ///
4927 OMPTeamsDistributeSimdDirective(SourceLocation StartLoc,
4928 SourceLocation EndLoc, unsigned CollapsedNum)
4929 : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass,
4930 llvm::omp::OMPD_teams_distribute_simd, StartLoc,
4931 EndLoc, CollapsedNum) {}
4932
4933 /// Build an empty directive.
4934 ///
4935 /// \param CollapsedNum Number of collapsed nested loops.
4936 ///
4937 explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum)
4938 : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass,
4939 llvm::omp::OMPD_teams_distribute_simd,
4940 SourceLocation(), SourceLocation(), CollapsedNum) {}
4941
4942public:
4943 /// Creates directive with a list of \a Clauses.
4944 ///
4945 /// \param C AST context.
4946 /// \param StartLoc Starting location of the directive kind.
4947 /// \param EndLoc Ending Location of the directive.
4948 /// \param CollapsedNum Number of collapsed loops.
4949 /// \param Clauses List of clauses.
4950 /// \param AssociatedStmt Statement, associated with the directive.
4951 /// \param Exprs Helper expressions for CodeGen.
4952 ///
4953 static OMPTeamsDistributeSimdDirective *
4954 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4955 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4956 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4957
4958 /// Creates an empty directive with the place
4959 /// for \a NumClauses clauses.
4960 ///
4961 /// \param C AST context.
4962 /// \param CollapsedNum Number of collapsed nested loops.
4963 /// \param NumClauses Number of clauses.
4964 ///
4965 static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C,
4966 unsigned NumClauses,
4967 unsigned CollapsedNum,
4968 EmptyShell);
4969
4970 static bool classof(const Stmt *T) {
4971 return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass;
4972 }
4973};
4974
4975/// This represents '#pragma omp teams distribute parallel for simd' composite
4976/// directive.
4977///
4978/// \code
4979/// #pragma omp teams distribute parallel for simd private(x)
4980/// \endcode
4981/// In this example directive '#pragma omp teams distribute parallel for simd'
4982/// has clause 'private' with the variables 'x'
4983///
4984class OMPTeamsDistributeParallelForSimdDirective final
4985 : public OMPLoopDirective {
4986 friend class ASTStmtReader;
4987 friend class OMPExecutableDirective;
4988
4989 /// Build directive with the given start and end location.
4990 ///
4991 /// \param StartLoc Starting location of the directive kind.
4992 /// \param EndLoc Ending location of the directive.
4993 /// \param CollapsedNum Number of collapsed nested loops.
4994 ///
4995 OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
4996 SourceLocation EndLoc,
4997 unsigned CollapsedNum)
4998 : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass,
4999 llvm::omp::OMPD_teams_distribute_parallel_for_simd,
5000 StartLoc, EndLoc, CollapsedNum) {}
5001
5002 /// Build an empty directive.
5003 ///
5004 /// \param CollapsedNum Number of collapsed nested loops.
5005 ///
5006 explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum)
5007 : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass,
5008 llvm::omp::OMPD_teams_distribute_parallel_for_simd,
5009 SourceLocation(), SourceLocation(), CollapsedNum) {}
5010
5011public:
5012 /// Creates directive with a list of \a Clauses.
5013 ///
5014 /// \param C AST context.
5015 /// \param StartLoc Starting location of the directive kind.
5016 /// \param EndLoc Ending Location of the directive.
5017 /// \param CollapsedNum Number of collapsed loops.
5018 /// \param Clauses List of clauses.
5019 /// \param AssociatedStmt Statement, associated with the directive.
5020 /// \param Exprs Helper expressions for CodeGen.
5021 ///
5022 static OMPTeamsDistributeParallelForSimdDirective *
5023 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5024 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5025 Stmt *AssociatedStmt, const HelperExprs &Exprs);
5026
5027 /// Creates an empty directive with the place for \a NumClauses clauses.
5028 ///
5029 /// \param C AST context.
5030 /// \param CollapsedNum Number of collapsed nested loops.
5031 /// \param NumClauses Number of clauses.
5032 ///
5033 static OMPTeamsDistributeParallelForSimdDirective *
5034 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5035 EmptyShell);
5036
5037 static bool classof(const Stmt *T) {
5038 return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass;
5039 }
5040};
5041
5042/// This represents '#pragma omp teams distribute parallel for' composite
5043/// directive.
5044///
5045/// \code
5046/// #pragma omp teams distribute parallel for private(x)
5047/// \endcode
5048/// In this example directive '#pragma omp teams distribute parallel for'
5049/// has clause 'private' with the variables 'x'
5050///
5051class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
5052 friend class ASTStmtReader;
5053 friend class OMPExecutableDirective;
5054 /// true if the construct has inner cancel directive.
5055 bool HasCancel = false;
5056
5057 /// Build directive with the given start and end location.
5058 ///
5059 /// \param StartLoc Starting location of the directive kind.
5060 /// \param EndLoc Ending location of the directive.
5061 /// \param CollapsedNum Number of collapsed nested loops.
5062 ///
5063 OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc,
5064 SourceLocation EndLoc,
5065 unsigned CollapsedNum)
5066 : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass,
5067 llvm::omp::OMPD_teams_distribute_parallel_for,
5068 StartLoc, EndLoc, CollapsedNum) {}
5069
5070 /// Build an empty directive.
5071 ///
5072 /// \param CollapsedNum Number of collapsed nested loops.
5073 ///
5074 explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum)
5075 : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass,
5076 llvm::omp::OMPD_teams_distribute_parallel_for,
5077 SourceLocation(), SourceLocation(), CollapsedNum) {}
5078
5079 /// Sets special task reduction descriptor.
5080 void setTaskReductionRefExpr(Expr *E) {
5081 Data->getChildren()[numLoopChildren(
5082 getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)] = E;
5083 }
5084
5085 /// Set cancel state.
5086 void setHasCancel(bool Has) { HasCancel = Has; }
5087
5088public:
5089 /// Creates directive with a list of \a Clauses.
5090 ///
5091 /// \param C AST context.
5092 /// \param StartLoc Starting location of the directive kind.
5093 /// \param EndLoc Ending Location of the directive.
5094 /// \param CollapsedNum Number of collapsed loops.
5095 /// \param Clauses List of clauses.
5096 /// \param AssociatedStmt Statement, associated with the directive.
5097 /// \param Exprs Helper expressions for CodeGen.
5098 /// \param TaskRedRef Task reduction special reference expression to handle
5099 /// taskgroup descriptor.
5100 /// \param HasCancel true if this directive has inner cancel directive.
5101 ///
5102 static OMPTeamsDistributeParallelForDirective *
5103 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5104 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5105 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
5106 bool HasCancel);
5107
5108 /// Creates an empty directive with the place for \a NumClauses clauses.
5109 ///
5110 /// \param C AST context.
5111 /// \param CollapsedNum Number of collapsed nested loops.
5112 /// \param NumClauses Number of clauses.
5113 ///
5114 static OMPTeamsDistributeParallelForDirective *
5115 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5116 EmptyShell);
5117
5118 /// Returns special task reduction reference expression.
5119 Expr *getTaskReductionRefExpr() {
5120 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
5121 getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)]);
5122 }
5123 const Expr *getTaskReductionRefExpr() const {
5124 return const_cast<OMPTeamsDistributeParallelForDirective *>(this)
5125 ->getTaskReductionRefExpr();
5126 }
5127
5128 /// Return true if current directive has inner cancel directive.
5129 bool hasCancel() const { return HasCancel; }
5130
5131 static bool classof(const Stmt *T) {
5132 return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass;
5133 }
5134};
5135
5136/// This represents '#pragma omp target teams' directive.
5137///
5138/// \code
5139/// #pragma omp target teams if(a>0)
5140/// \endcode
5141/// In this example directive '#pragma omp target teams' has clause 'if' with
5142/// condition 'a>0'.
5143///
5144class OMPTargetTeamsDirective final : public OMPExecutableDirective {
5145 friend class ASTStmtReader;
5146 friend class OMPExecutableDirective;
5147 /// Build directive with the given start and end location.
5148 ///
5149 /// \param StartLoc Starting location of the directive kind.
5150 /// \param EndLoc Ending location of the directive.
5151 ///
5152 OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5153 : OMPExecutableDirective(OMPTargetTeamsDirectiveClass,
5154 llvm::omp::OMPD_target_teams, StartLoc, EndLoc) {
5155 }
5156
5157 /// Build an empty directive.
5158 ///
5159 explicit OMPTargetTeamsDirective()
5160 : OMPExecutableDirective(OMPTargetTeamsDirectiveClass,
5161 llvm::omp::OMPD_target_teams, SourceLocation(),
5162 SourceLocation()) {}
5163
5164public:
5165 /// Creates directive with a list of \a Clauses.
5166 ///
5167 /// \param C AST context.
5168 /// \param StartLoc Starting location of the directive kind.
5169 /// \param EndLoc Ending Location of the directive.
5170 /// \param Clauses List of clauses.
5171 /// \param AssociatedStmt Statement, associated with the directive.
5172 ///
5173 static OMPTargetTeamsDirective *Create(const ASTContext &C,
5174 SourceLocation StartLoc,
5175 SourceLocation EndLoc,
5176 ArrayRef<OMPClause *> Clauses,
5177 Stmt *AssociatedStmt);
5178
5179 /// Creates an empty directive with the place for \a NumClauses clauses.
5180 ///
5181 /// \param C AST context.
5182 /// \param NumClauses Number of clauses.
5183 ///
5184 static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C,
5185 unsigned NumClauses, EmptyShell);
5186
5187 static bool classof(const Stmt *T) {
5188 return T->getStmtClass() == OMPTargetTeamsDirectiveClass;
5189 }
5190};
5191
5192/// This represents '#pragma omp target teams distribute' combined directive.
5193///
5194/// \code
5195/// #pragma omp target teams distribute private(x)
5196/// \endcode
5197/// In this example directive '#pragma omp target teams distribute' has clause
5198/// 'private' with the variables 'x'
5199///
5200class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective {
5201 friend class ASTStmtReader;
5202 friend class OMPExecutableDirective;
5203
5204 /// Build directive with the given start and end location.
5205 ///
5206 /// \param StartLoc Starting location of the directive kind.
5207 /// \param EndLoc Ending location of the directive.
5208 /// \param CollapsedNum Number of collapsed nested loops.
5209 ///
5210 OMPTargetTeamsDistributeDirective(SourceLocation StartLoc,
5211 SourceLocation EndLoc,
5212 unsigned CollapsedNum)
5213 : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass,
5214 llvm::omp::OMPD_target_teams_distribute, StartLoc,
5215 EndLoc, CollapsedNum) {}
5216
5217 /// Build an empty directive.
5218 ///
5219 /// \param CollapsedNum Number of collapsed nested loops.
5220 ///
5221 explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum)
5222 : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass,
5223 llvm::omp::OMPD_target_teams_distribute,
5224 SourceLocation(), SourceLocation(), CollapsedNum) {}
5225
5226public:
5227 /// Creates directive with a list of \a Clauses.
5228 ///
5229 /// \param C AST context.
5230 /// \param StartLoc Starting location of the directive kind.
5231 /// \param EndLoc Ending Location of the directive.
5232 /// \param CollapsedNum Number of collapsed loops.
5233 /// \param Clauses List of clauses.
5234 /// \param AssociatedStmt Statement, associated with the directive.
5235 /// \param Exprs Helper expressions for CodeGen.
5236 ///
5237 static OMPTargetTeamsDistributeDirective *
5238 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5239 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5240 Stmt *AssociatedStmt, const HelperExprs &Exprs);
5241
5242 /// Creates an empty directive with the place for \a NumClauses clauses.
5243 ///
5244 /// \param C AST context.
5245 /// \param CollapsedNum Number of collapsed nested loops.
5246 /// \param NumClauses Number of clauses.
5247 ///
5248 static OMPTargetTeamsDistributeDirective *
5249 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5250 EmptyShell);
5251
5252 static bool classof(const Stmt *T) {
5253 return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass;
5254 }
5255};
5256
5257/// This represents '#pragma omp target teams distribute parallel for' combined
5258/// directive.
5259///
5260/// \code
5261/// #pragma omp target teams distribute parallel for private(x)
5262/// \endcode
5263/// In this example directive '#pragma omp target teams distribute parallel
5264/// for' has clause 'private' with the variables 'x'
5265///
5266class OMPTargetTeamsDistributeParallelForDirective final
5267 : public OMPLoopDirective {
5268 friend class ASTStmtReader;
5269 friend class OMPExecutableDirective;
5270 /// true if the construct has inner cancel directive.
5271 bool HasCancel = false;
5272
5273 /// Build directive with the given start and end location.
5274 ///
5275 /// \param StartLoc Starting location of the directive kind.
5276 /// \param EndLoc Ending location of the directive.
5277 /// \param CollapsedNum Number of collapsed nested loops.
5278 ///
5279 OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc,
5280 SourceLocation EndLoc,
5281 unsigned CollapsedNum)
5282 : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass,
5283 llvm::omp::OMPD_target_teams_distribute_parallel_for,
5284 StartLoc, EndLoc, CollapsedNum) {}
5285
5286 /// Build an empty directive.
5287 ///
5288 /// \param CollapsedNum Number of collapsed nested loops.
5289 ///
5290 explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum)
5291 : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass,
5292 llvm::omp::OMPD_target_teams_distribute_parallel_for,
5293 SourceLocation(), SourceLocation(), CollapsedNum) {}
5294
5295 /// Sets special task reduction descriptor.
5296 void setTaskReductionRefExpr(Expr *E) {
5297 Data->getChildren()[numLoopChildren(
5298 getLoopsNumber(),
5299 llvm::omp::OMPD_target_teams_distribute_parallel_for)] = E;
5300 }
5301
5302 /// Set cancel state.
5303 void setHasCancel(bool Has) { HasCancel = Has; }
5304
5305public:
5306 /// Creates directive with a list of \a Clauses.
5307 ///
5308 /// \param C AST context.
5309 /// \param StartLoc Starting location of the directive kind.
5310 /// \param EndLoc Ending Location of the directive.
5311 /// \param CollapsedNum Number of collapsed loops.
5312 /// \param Clauses List of clauses.
5313 /// \param AssociatedStmt Statement, associated with the directive.
5314 /// \param Exprs Helper expressions for CodeGen.
5315 /// \param TaskRedRef Task reduction special reference expression to handle
5316 /// taskgroup descriptor.
5317 /// \param HasCancel true if this directive has inner cancel directive.
5318 ///
5319 static OMPTargetTeamsDistributeParallelForDirective *
5320 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5321 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5322 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
5323 bool HasCancel);
5324
5325 /// Creates an empty directive with the place for \a NumClauses clauses.
5326 ///
5327 /// \param C AST context.
5328 /// \param CollapsedNum Number of collapsed nested loops.
5329 /// \param NumClauses Number of clauses.
5330 ///
5331 static OMPTargetTeamsDistributeParallelForDirective *
5332 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5333 EmptyShell);
5334
5335 /// Returns special task reduction reference expression.
5336 Expr *getTaskReductionRefExpr() {
5337 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
5338 getLoopsNumber(),
5339 llvm::omp::OMPD_target_teams_distribute_parallel_for)]);
5340 }
5341 const Expr *getTaskReductionRefExpr() const {
5342 return const_cast<OMPTargetTeamsDistributeParallelForDirective *>(this)
5343 ->getTaskReductionRefExpr();
5344 }
5345
5346 /// Return true if current directive has inner cancel directive.
5347 bool hasCancel() const { return HasCancel; }
5348
5349 static bool classof(const Stmt *T) {
5350 return T->getStmtClass() ==
5351 OMPTargetTeamsDistributeParallelForDirectiveClass;
5352 }
5353};
5354
5355/// This represents '#pragma omp target teams distribute parallel for simd'
5356/// combined directive.
5357///
5358/// \code
5359/// #pragma omp target teams distribute parallel for simd private(x)
5360/// \endcode
5361/// In this example directive '#pragma omp target teams distribute parallel
5362/// for simd' has clause 'private' with the variables 'x'
5363///
5364class OMPTargetTeamsDistributeParallelForSimdDirective final
5365 : public OMPLoopDirective {
5366 friend class ASTStmtReader;
5367 friend class OMPExecutableDirective;
5368
5369 /// Build directive with the given start and end location.
5370 ///
5371 /// \param StartLoc Starting location of the directive kind.
5372 /// \param EndLoc Ending location of the directive.
5373 /// \param CollapsedNum Number of collapsed nested loops.
5374 ///
5375 OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
5376 SourceLocation EndLoc,
5377 unsigned CollapsedNum)
5378 : OMPLoopDirective(
5379 OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
5380 llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, StartLoc,
5381 EndLoc, CollapsedNum) {}
5382
5383 /// Build an empty directive.
5384 ///
5385 /// \param CollapsedNum Number of collapsed nested loops.
5386 ///
5387 explicit OMPTargetTeamsDistributeParallelForSimdDirective(
5388 unsigned CollapsedNum)
5389 : OMPLoopDirective(
5390 OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
5391 llvm::omp::OMPD_target_teams_distribute_parallel_for_simd,
5392 SourceLocation(), SourceLocation(), CollapsedNum) {}
5393
5394public:
5395 /// Creates directive with a list of \a Clauses.
5396 ///
5397 /// \param C AST context.
5398 /// \param StartLoc Starting location of the directive kind.
5399 /// \param EndLoc Ending Location of the directive.
5400 /// \param CollapsedNum Number of collapsed loops.
5401 /// \param Clauses List of clauses.
5402 /// \param AssociatedStmt Statement, associated with the directive.
5403 /// \param Exprs Helper expressions for CodeGen.
5404 ///
5405 static OMPTargetTeamsDistributeParallelForSimdDirective *
5406 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5407 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5408 Stmt *AssociatedStmt, const HelperExprs &Exprs);
5409
5410 /// Creates an empty directive with the place for \a NumClauses clauses.
5411 ///
5412 /// \param C AST context.
5413 /// \param CollapsedNum Number of collapsed nested loops.
5414 /// \param NumClauses Number of clauses.
5415 ///
5416 static OMPTargetTeamsDistributeParallelForSimdDirective *
5417 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5418 EmptyShell);
5419
5420 static bool classof(const Stmt *T) {
5421 return T->getStmtClass() ==
5422 OMPTargetTeamsDistributeParallelForSimdDirectiveClass;
5423 }
5424};
5425
5426/// This represents '#pragma omp target teams distribute simd' combined
5427/// directive.
5428///
5429/// \code
5430/// #pragma omp target teams distribute simd private(x)
5431/// \endcode
5432/// In this example directive '#pragma omp target teams distribute simd'
5433/// has clause 'private' with the variables 'x'
5434///
5435class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective {
5436 friend class ASTStmtReader;
5437 friend class OMPExecutableDirective;
5438
5439 /// Build directive with the given start and end location.
5440 ///
5441 /// \param StartLoc Starting location of the directive kind.
5442 /// \param EndLoc Ending location of the directive.
5443 /// \param CollapsedNum Number of collapsed nested loops.
5444 ///
5445 OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc,
5446 SourceLocation EndLoc,
5447 unsigned CollapsedNum)
5448 : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass,
5449 llvm::omp::OMPD_target_teams_distribute_simd, StartLoc,
5450 EndLoc, CollapsedNum) {}
5451
5452 /// Build an empty directive.
5453 ///
5454 /// \param CollapsedNum Number of collapsed nested loops.
5455 ///
5456 explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum)
5457 : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass,
5458 llvm::omp::OMPD_target_teams_distribute_simd,
5459 SourceLocation(), SourceLocation(), CollapsedNum) {}
5460
5461public:
5462 /// Creates directive with a list of \a Clauses.
5463 ///
5464 /// \param C AST context.
5465 /// \param StartLoc Starting location of the directive kind.
5466 /// \param EndLoc Ending Location of the directive.
5467 /// \param CollapsedNum Number of collapsed loops.
5468 /// \param Clauses List of clauses.
5469 /// \param AssociatedStmt Statement, associated with the directive.
5470 /// \param Exprs Helper expressions for CodeGen.
5471 ///
5472 static OMPTargetTeamsDistributeSimdDirective *
5473 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5474 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5475 Stmt *AssociatedStmt, const HelperExprs &Exprs);
5476
5477 /// Creates an empty directive with the place for \a NumClauses clauses.
5478 ///
5479 /// \param C AST context.
5480 /// \param CollapsedNum Number of collapsed nested loops.
5481 /// \param NumClauses Number of clauses.
5482 ///
5483 static OMPTargetTeamsDistributeSimdDirective *
5484 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5485 EmptyShell);
5486
5487 static bool classof(const Stmt *T) {
5488 return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
5489 }
5490};
5491
5492/// This represents the '#pragma omp tile' loop transformation directive.
5493class OMPTileDirective final : public OMPLoopTransformationDirective {
5494 friend class ASTStmtReader;
5495 friend class OMPExecutableDirective;
5496
5497 /// Default list of offsets.
5498 enum {
5499 PreInitsOffset = 0,
5500 TransformedStmtOffset,
5501 };
5502
5503 explicit OMPTileDirective(SourceLocation StartLoc, SourceLocation EndLoc,
5504 unsigned NumLoops)
5505 : OMPLoopTransformationDirective(OMPTileDirectiveClass,
5506 llvm::omp::OMPD_tile, StartLoc, EndLoc,
5507 NumLoops) {
5508 setNumGeneratedLoops(3 * NumLoops);
5509 }
5510
5511 void setPreInits(Stmt *PreInits) {
5512 Data->getChildren()[PreInitsOffset] = PreInits;
5513 }
5514
5515 void setTransformedStmt(Stmt *S) {
5516 Data->getChildren()[TransformedStmtOffset] = S;
5517 }
5518
5519public:
5520 /// Create a new AST node representation for '#pragma omp tile'.
5521 ///
5522 /// \param C Context of the AST.
5523 /// \param StartLoc Location of the introducer (e.g. the 'omp' token).
5524 /// \param EndLoc Location of the directive's end (e.g. the tok::eod).
5525 /// \param Clauses The directive's clauses.
5526 /// \param NumLoops Number of associated loops (number of items in the
5527 /// 'sizes' clause).
5528 /// \param AssociatedStmt The outermost associated loop.
5529 /// \param TransformedStmt The loop nest after tiling, or nullptr in
5530 /// dependent contexts.
5531 /// \param PreInits Helper preinits statements for the loop nest.
5532 static OMPTileDirective *Create(const ASTContext &C, SourceLocation StartLoc,
5533 SourceLocation EndLoc,
5534 ArrayRef<OMPClause *> Clauses,
5535 unsigned NumLoops, Stmt *AssociatedStmt,
5536 Stmt *TransformedStmt, Stmt *PreInits);
5537
5538 /// Build an empty '#pragma omp tile' AST node for deserialization.
5539 ///
5540 /// \param C Context of the AST.
5541 /// \param NumClauses Number of clauses to allocate.
5542 /// \param NumLoops Number of associated loops to allocate.
5543 static OMPTileDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
5544 unsigned NumLoops);
5545
5546 /// Gets/sets the associated loops after tiling.
5547 ///
5548 /// This is in de-sugared format stored as a CompoundStmt.
5549 ///
5550 /// \code
5551 /// for (...)
5552 /// ...
5553 /// \endcode
5554 ///
5555 /// Note that if the generated loops a become associated loops of another
5556 /// directive, they may need to be hoisted before them.
5557 Stmt *getTransformedStmt() const {
5558 return Data->getChildren()[TransformedStmtOffset];
5559 }
5560
5561 /// Return preinits statement.
5562 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
5563
5564 static bool classof(const Stmt *T) {
5565 return T->getStmtClass() == OMPTileDirectiveClass;
5566 }
5567};
5568
5569/// This represents the '#pragma omp unroll' loop transformation directive.
5570///
5571/// \code
5572/// #pragma omp unroll
5573/// for (int i = 0; i < 64; ++i)
5574/// \endcode
5575class OMPUnrollDirective final : public OMPLoopTransformationDirective {
5576 friend class ASTStmtReader;
5577 friend class OMPExecutableDirective;
5578
5579 /// Default list of offsets.
5580 enum {
5581 PreInitsOffset = 0,
5582 TransformedStmtOffset,
5583 };
5584
5585 explicit OMPUnrollDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5586 : OMPLoopTransformationDirective(OMPUnrollDirectiveClass,
5587 llvm::omp::OMPD_unroll, StartLoc, EndLoc,
5588 1) {}
5589
5590 /// Set the pre-init statements.
5591 void setPreInits(Stmt *PreInits) {
5592 Data->getChildren()[PreInitsOffset] = PreInits;
5593 }
5594
5595 /// Set the de-sugared statement.
5596 void setTransformedStmt(Stmt *S) {
5597 Data->getChildren()[TransformedStmtOffset] = S;
5598 }
5599
5600public:
5601 /// Create a new AST node representation for '#pragma omp unroll'.
5602 ///
5603 /// \param C Context of the AST.
5604 /// \param StartLoc Location of the introducer (e.g. the 'omp' token).
5605 /// \param EndLoc Location of the directive's end (e.g. the tok::eod).
5606 /// \param Clauses The directive's clauses.
5607 /// \param AssociatedStmt The outermost associated loop.
5608 /// \param TransformedStmt The loop nest after tiling, or nullptr in
5609 /// dependent contexts.
5610 /// \param PreInits Helper preinits statements for the loop nest.
5611 static OMPUnrollDirective *
5612 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5613 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
5614 unsigned NumGeneratedLoops, Stmt *TransformedStmt, Stmt *PreInits);
5615
5616 /// Build an empty '#pragma omp unroll' AST node for deserialization.
5617 ///
5618 /// \param C Context of the AST.
5619 /// \param NumClauses Number of clauses to allocate.
5620 static OMPUnrollDirective *CreateEmpty(const ASTContext &C,
5621 unsigned NumClauses);
5622
5623 /// Get the de-sugared associated loops after unrolling.
5624 ///
5625 /// This is only used if the unrolled loop becomes an associated loop of
5626 /// another directive, otherwise the loop is emitted directly using loop
5627 /// transformation metadata. When the unrolled loop cannot be used by another
5628 /// directive (e.g. because of the full clause), the transformed stmt can also
5629 /// be nullptr.
5630 Stmt *getTransformedStmt() const {
5631 return Data->getChildren()[TransformedStmtOffset];
5632 }
5633
5634 /// Return the pre-init statements.
5635 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
5636
5637 static bool classof(const Stmt *T) {
5638 return T->getStmtClass() == OMPUnrollDirectiveClass;
5639 }
5640};
5641
5642/// This represents '#pragma omp scan' directive.
5643///
5644/// \code
5645/// #pragma omp scan inclusive(a)
5646/// \endcode
5647/// In this example directive '#pragma omp scan' has clause 'inclusive' with
5648/// list item 'a'.
5649class OMPScanDirective final : public OMPExecutableDirective {
5650 friend class ASTStmtReader;
5651 friend class OMPExecutableDirective;
5652 /// Build directive with the given start and end location.
5653 ///
5654 /// \param StartLoc Starting location of the directive kind.
5655 /// \param EndLoc Ending location of the directive.
5656 ///
5657 OMPScanDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5658 : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan,
5659 StartLoc, EndLoc) {}
5660
5661 /// Build an empty directive.
5662 ///
5663 explicit OMPScanDirective()
5664 : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan,
5665 SourceLocation(), SourceLocation()) {}
5666
5667public:
5668 /// Creates directive with a list of \a Clauses.
5669 ///
5670 /// \param C AST context.
5671 /// \param StartLoc Starting location of the directive kind.
5672 /// \param EndLoc Ending Location of the directive.
5673 /// \param Clauses List of clauses (only single OMPFlushClause clause is
5674 /// allowed).
5675 ///
5676 static OMPScanDirective *Create(const ASTContext &C, SourceLocation StartLoc,
5677 SourceLocation EndLoc,
5678 ArrayRef<OMPClause *> Clauses);
5679
5680 /// Creates an empty directive with the place for \a NumClauses
5681 /// clauses.
5682 ///
5683 /// \param C AST context.
5684 /// \param NumClauses Number of clauses.
5685 ///
5686 static OMPScanDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
5687 EmptyShell);
5688
5689 static bool classof(const Stmt *T) {
5690 return T->getStmtClass() == OMPScanDirectiveClass;
5691 }
5692};
5693
5694/// This represents '#pragma omp interop' directive.
5695///
5696/// \code
5697/// #pragma omp interop init(target:obj) device(x) depend(inout:y) nowait
5698/// \endcode
5699/// In this example directive '#pragma omp interop' has
5700/// clauses 'init', 'device', 'depend' and 'nowait'.
5701///
5702class OMPInteropDirective final : public OMPExecutableDirective {
5703 friend class ASTStmtReader;
5704 friend class OMPExecutableDirective;
5705
5706 /// Build directive with the given start and end location.
5707 ///
5708 /// \param StartLoc Starting location of the directive.
5709 /// \param EndLoc Ending location of the directive.
5710 ///
5711 OMPInteropDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5712 : OMPExecutableDirective(OMPInteropDirectiveClass,
5713 llvm::omp::OMPD_interop, StartLoc, EndLoc) {}
5714
5715 /// Build an empty directive.
5716 ///
5717 explicit OMPInteropDirective()
5718 : OMPExecutableDirective(OMPInteropDirectiveClass,
5719 llvm::omp::OMPD_interop, SourceLocation(),
5720 SourceLocation()) {}
5721
5722public:
5723 /// Creates directive.
5724 ///
5725 /// \param C AST context.
5726 /// \param StartLoc Starting location of the directive.
5727 /// \param EndLoc Ending Location of the directive.
5728 /// \param Clauses The directive's clauses.
5729 ///
5730 static OMPInteropDirective *Create(const ASTContext &C,
5731 SourceLocation StartLoc,
5732 SourceLocation EndLoc,
5733 ArrayRef<OMPClause *> Clauses);
5734
5735 /// Creates an empty directive.
5736 ///
5737 /// \param C AST context.
5738 ///
5739 static OMPInteropDirective *CreateEmpty(const ASTContext &C,
5740 unsigned NumClauses, EmptyShell);
5741
5742 static bool classof(const Stmt *T) {
5743 return T->getStmtClass() == OMPInteropDirectiveClass;
5744 }
5745};
5746
5747/// This represents '#pragma omp dispatch' directive.
5748///
5749/// \code
5750/// #pragma omp dispatch device(dnum)
5751/// \endcode
5752/// This example shows a directive '#pragma omp dispatch' with a
5753/// device clause with variable 'dnum'.
5754///
5755class OMPDispatchDirective final : public OMPExecutableDirective {
5756 friend class ASTStmtReader;
5757 friend class OMPExecutableDirective;
5758
5759 /// The location of the target-call.
5760 SourceLocation TargetCallLoc;
5761
5762 /// Set the location of the target-call.
5763 void setTargetCallLoc(SourceLocation Loc) { TargetCallLoc = Loc; }
5764
5765 /// Build directive with the given start and end location.
5766 ///
5767 /// \param StartLoc Starting location of the directive kind.
5768 /// \param EndLoc Ending location of the directive.
5769 ///
5770 OMPDispatchDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5771 : OMPExecutableDirective(OMPDispatchDirectiveClass,
5772 llvm::omp::OMPD_dispatch, StartLoc, EndLoc) {}
5773
5774 /// Build an empty directive.
5775 ///
5776 explicit OMPDispatchDirective()
5777 : OMPExecutableDirective(OMPDispatchDirectiveClass,
5778 llvm::omp::OMPD_dispatch, SourceLocation(),
5779 SourceLocation()) {}
5780
5781public:
5782 /// Creates directive with a list of \a Clauses.
5783 ///
5784 /// \param C AST context.
5785 /// \param StartLoc Starting location of the directive kind.
5786 /// \param EndLoc Ending Location of the directive.
5787 /// \param Clauses List of clauses.
5788 /// \param AssociatedStmt Statement, associated with the directive.
5789 /// \param TargetCallLoc Location of the target-call.
5790 ///
5791 static OMPDispatchDirective *
5792 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5793 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
5794 SourceLocation TargetCallLoc);
5795
5796 /// Creates an empty directive with the place for \a NumClauses
5797 /// clauses.
5798 ///
5799 /// \param C AST context.
5800 /// \param NumClauses Number of clauses.
5801 ///
5802 static OMPDispatchDirective *CreateEmpty(const ASTContext &C,
5803 unsigned NumClauses, EmptyShell);
5804
5805 /// Return location of target-call.
5806 SourceLocation getTargetCallLoc() const { return TargetCallLoc; }
5807
5808 static bool classof(const Stmt *T) {
5809 return T->getStmtClass() == OMPDispatchDirectiveClass;
5810 }
5811};
5812
5813/// This represents '#pragma omp masked' directive.
5814/// \code
5815/// #pragma omp masked filter(tid)
5816/// \endcode
5817/// This example shows a directive '#pragma omp masked' with a filter clause
5818/// with variable 'tid'.
5819///
5820class OMPMaskedDirective final : public OMPExecutableDirective {
5821 friend class ASTStmtReader;
5822 friend class OMPExecutableDirective;
5823
5824 /// Build directive with the given start and end location.
5825 ///
5826 /// \param StartLoc Starting location of the directive kind.
5827 /// \param EndLoc Ending location of the directive.
5828 ///
5829 OMPMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5830 : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked,
5831 StartLoc, EndLoc) {}
5832
5833 /// Build an empty directive.
5834 ///
5835 explicit OMPMaskedDirective()
5836 : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked,
5837 SourceLocation(), SourceLocation()) {}
5838
5839public:
5840 /// Creates directive.
5841 ///
5842 /// \param C AST context.
5843 /// \param StartLoc Starting location of the directive kind.
5844 /// \param EndLoc Ending Location of the directive.
5845 /// \param AssociatedStmt Statement, associated with the directive.
5846 ///
5847 static OMPMaskedDirective *
5848 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5849 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
5850
5851 /// Creates an empty directive.
5852 ///
5853 /// \param C AST context.
5854 ///
5855 static OMPMaskedDirective *CreateEmpty(const ASTContext &C,
5856 unsigned NumClauses, EmptyShell);
5857
5858 static bool classof(const Stmt *T) {
5859 return T->getStmtClass() == OMPMaskedDirectiveClass;
5860 }
5861};
5862
5863/// This represents '#pragma omp metadirective' directive.
5864///
5865/// \code
5866/// #pragma omp metadirective when(user={condition(N>10)}: parallel for)
5867/// \endcode
5868/// In this example directive '#pragma omp metadirective' has clauses 'when'
5869/// with a dynamic user condition to check if a variable 'N > 10'
5870///
5871class OMPMetaDirective final : public OMPExecutableDirective {
5872 friend class ASTStmtReader;
5873 friend class OMPExecutableDirective;
5874 Stmt *IfStmt;
5875
5876 OMPMetaDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5877 : OMPExecutableDirective(OMPMetaDirectiveClass,
5878 llvm::omp::OMPD_metadirective, StartLoc,
5879 EndLoc) {}
5880 explicit OMPMetaDirective()
5881 : OMPExecutableDirective(OMPMetaDirectiveClass,
5882 llvm::omp::OMPD_metadirective, SourceLocation(),
5883 SourceLocation()) {}
5884
5885 void setIfStmt(Stmt *S) { IfStmt = S; }
5886
5887public:
5888 static OMPMetaDirective *Create(const ASTContext &C, SourceLocation StartLoc,
5889 SourceLocation EndLoc,
5890 ArrayRef<OMPClause *> Clauses,
5891 Stmt *AssociatedStmt, Stmt *IfStmt);
5892 static OMPMetaDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
5893 EmptyShell);
5894 Stmt *getIfStmt() const { return IfStmt; }
5895
5896 static bool classof(const Stmt *T) {
5897 return T->getStmtClass() == OMPMetaDirectiveClass;
5898 }
5899};
5900
5901/// This represents '#pragma omp loop' directive.
5902///
5903/// \code
5904/// #pragma omp loop private(a,b) binding(parallel) order(concurrent)
5905/// \endcode
5906/// In this example directive '#pragma omp loop' has
5907/// clauses 'private' with the variables 'a' and 'b', 'binding' with
5908/// modifier 'parallel' and 'order(concurrent).
5909///
5910class OMPGenericLoopDirective final : public OMPLoopDirective {
5911 friend class ASTStmtReader;
5912 friend class OMPExecutableDirective;
5913 /// Build directive with the given start and end location.
5914 ///
5915 /// \param StartLoc Starting location of the directive kind.
5916 /// \param EndLoc Ending location of the directive.
5917 /// \param CollapsedNum Number of collapsed nested loops.
5918 ///
5919 OMPGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
5920 unsigned CollapsedNum)
5921 : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop,
5922 StartLoc, EndLoc, CollapsedNum) {}
5923
5924 /// Build an empty directive.
5925 ///
5926 /// \param CollapsedNum Number of collapsed nested loops.
5927 ///
5928 explicit OMPGenericLoopDirective(unsigned CollapsedNum)
5929 : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop,
5930 SourceLocation(), SourceLocation(), CollapsedNum) {}
5931
5932public:
5933 /// Creates directive with a list of \p Clauses.
5934 ///
5935 /// \param C AST context.
5936 /// \param StartLoc Starting location of the directive kind.
5937 /// \param EndLoc Ending Location of the directive.
5938 /// \param CollapsedNum Number of collapsed loops.
5939 /// \param Clauses List of clauses.
5940 /// \param AssociatedStmt Statement, associated with the directive.
5941 /// \param Exprs Helper expressions for CodeGen.
5942 ///
5943 static OMPGenericLoopDirective *
5944 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5945 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5946 Stmt *AssociatedStmt, const HelperExprs &Exprs);
5947
5948 /// Creates an empty directive with a place for \a NumClauses clauses.
5949 ///
5950 /// \param C AST context.
5951 /// \param NumClauses Number of clauses.
5952 /// \param CollapsedNum Number of collapsed nested loops.
5953 ///
5954 static OMPGenericLoopDirective *CreateEmpty(const ASTContext &C,
5955 unsigned NumClauses,
5956 unsigned CollapsedNum,
5957 EmptyShell);
5958
5959 static bool classof(const Stmt *T) {
5960 return T->getStmtClass() == OMPGenericLoopDirectiveClass;
5961 }
5962};
5963
5964/// This represents '#pragma omp teams loop' directive.
5965///
5966/// \code
5967/// #pragma omp teams loop private(a,b) order(concurrent)
5968/// \endcode
5969/// In this example directive '#pragma omp teams loop' has
5970/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
5971///
5972class OMPTeamsGenericLoopDirective final : public OMPLoopDirective {
5973 friend class ASTStmtReader;
5974 friend class OMPExecutableDirective;
5975 /// Build directive with the given start and end location.
5976 ///
5977 /// \param StartLoc Starting location of the directive kind.
5978 /// \param EndLoc Ending location of the directive.
5979 /// \param CollapsedNum Number of collapsed nested loops.
5980 ///
5981 OMPTeamsGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
5982 unsigned CollapsedNum)
5983 : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass,
5984 llvm::omp::OMPD_teams_loop, StartLoc, EndLoc,
5985 CollapsedNum) {}
5986
5987 /// Build an empty directive.
5988 ///
5989 /// \param CollapsedNum Number of collapsed nested loops.
5990 ///
5991 explicit OMPTeamsGenericLoopDirective(unsigned CollapsedNum)
5992 : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass,
5993 llvm::omp::OMPD_teams_loop, SourceLocation(),
5994 SourceLocation(), CollapsedNum) {}
5995
5996public:
5997 /// Creates directive with a list of \p Clauses.
5998 ///
5999 /// \param C AST context.
6000 /// \param StartLoc Starting location of the directive kind.
6001 /// \param EndLoc Ending Location of the directive.
6002 /// \param CollapsedNum Number of collapsed loops.
6003 /// \param Clauses List of clauses.
6004 /// \param AssociatedStmt Statement, associated with the directive.
6005 /// \param Exprs Helper expressions for CodeGen.
6006 ///
6007 static OMPTeamsGenericLoopDirective *
6008 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
6009 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
6010 Stmt *AssociatedStmt, const HelperExprs &Exprs);
6011
6012 /// Creates an empty directive with the place
6013 /// for \a NumClauses clauses.
6014 ///
6015 /// \param C AST context.
6016 /// \param CollapsedNum Number of collapsed nested loops.
6017 /// \param NumClauses Number of clauses.
6018 ///
6019 static OMPTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C,
6020 unsigned NumClauses,
6021 unsigned CollapsedNum,
6022 EmptyShell);
6023
6024 static bool classof(const Stmt *T) {
6025 return T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass;
6026 }
6027};
6028
6029/// This represents '#pragma omp target teams loop' directive.
6030///
6031/// \code
6032/// #pragma omp target teams loop private(a,b) order(concurrent)
6033/// \endcode
6034/// In this example directive '#pragma omp target teams loop' has
6035/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
6036///
6037class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective {
6038 friend class ASTStmtReader;
6039 friend class OMPExecutableDirective;
6040 /// Build directive with the given start and end location.
6041 ///
6042 /// \param StartLoc Starting location of the directive kind.
6043 /// \param EndLoc Ending location of the directive.
6044 /// \param CollapsedNum Number of collapsed nested loops.
6045 ///
6046 OMPTargetTeamsGenericLoopDirective(SourceLocation StartLoc,
6047 SourceLocation EndLoc,
6048 unsigned CollapsedNum)
6049 : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass,
6050 llvm::omp::OMPD_target_teams_loop, StartLoc, EndLoc,
6051 CollapsedNum) {}
6052
6053 /// Build an empty directive.
6054 ///
6055 /// \param CollapsedNum Number of collapsed nested loops.
6056 ///
6057 explicit OMPTargetTeamsGenericLoopDirective(unsigned CollapsedNum)
6058 : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass,
6059 llvm::omp::OMPD_target_teams_loop, SourceLocation(),
6060 SourceLocation(), CollapsedNum) {}
6061
6062public:
6063 /// Creates directive with a list of \p Clauses.
6064 ///
6065 /// \param C AST context.
6066 /// \param StartLoc Starting location of the directive kind.
6067 /// \param EndLoc Ending Location of the directive.
6068 /// \param CollapsedNum Number of collapsed loops.
6069 /// \param Clauses List of clauses.
6070 /// \param AssociatedStmt Statement, associated with the directive.
6071 /// \param Exprs Helper expressions for CodeGen.
6072 ///
6073 static OMPTargetTeamsGenericLoopDirective *
6074 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
6075 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
6076 Stmt *AssociatedStmt, const HelperExprs &Exprs);
6077
6078 /// Creates an empty directive with the place
6079 /// for \a NumClauses clauses.
6080 ///
6081 /// \param C AST context.
6082 /// \param CollapsedNum Number of collapsed nested loops.
6083 /// \param NumClauses Number of clauses.
6084 ///
6085 static OMPTargetTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C,
6086 unsigned NumClauses,
6087 unsigned CollapsedNum,
6088 EmptyShell);
6089
6090 static bool classof(const Stmt *T) {
6091 return T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass;
6092 }
6093};
6094
6095/// This represents '#pragma omp parallel loop' directive.
6096///
6097/// \code
6098/// #pragma omp parallel loop private(a,b) order(concurrent)
6099/// \endcode
6100/// In this example directive '#pragma omp parallel loop' has
6101/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
6102///
6103class OMPParallelGenericLoopDirective final : public OMPLoopDirective {
6104 friend class ASTStmtReader;
6105 friend class OMPExecutableDirective;
6106 /// Build directive with the given start and end location.
6107 ///
6108 /// \param StartLoc Starting location of the directive kind.
6109 /// \param EndLoc Ending location of the directive.
6110 /// \param CollapsedNum Number of collapsed nested loops.
6111 ///
6112 OMPParallelGenericLoopDirective(SourceLocation StartLoc,
6113 SourceLocation EndLoc, unsigned CollapsedNum)
6114 : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass,
6115 llvm::omp::OMPD_parallel_loop, StartLoc, EndLoc,
6116 CollapsedNum) {}
6117
6118 /// Build an empty directive.
6119 ///
6120 /// \param CollapsedNum Number of collapsed nested loops.
6121 ///
6122 explicit OMPParallelGenericLoopDirective(unsigned CollapsedNum)
6123 : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass,
6124 llvm::omp::OMPD_parallel_loop, SourceLocation(),
6125 SourceLocation(), CollapsedNum) {}
6126
6127public:
6128 /// Creates directive with a list of \p Clauses.
6129 ///
6130 /// \param C AST context.
6131 /// \param StartLoc Starting location of the directive kind.
6132 /// \param EndLoc Ending Location of the directive.
6133 /// \param CollapsedNum Number of collapsed loops.
6134 /// \param Clauses List of clauses.
6135 /// \param AssociatedStmt Statement, associated with the directive.
6136 /// \param Exprs Helper expressions for CodeGen.
6137 ///
6138 static OMPParallelGenericLoopDirective *
6139 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
6140 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
6141 Stmt *AssociatedStmt, const HelperExprs &Exprs);
6142
6143 /// Creates an empty directive with the place
6144 /// for \a NumClauses clauses.
6145 ///
6146 /// \param C AST context.
6147 /// \param CollapsedNum Number of collapsed nested loops.
6148 /// \param NumClauses Number of clauses.
6149 ///
6150 static OMPParallelGenericLoopDirective *CreateEmpty(const ASTContext &C,
6151 unsigned NumClauses,
6152 unsigned CollapsedNum,
6153 EmptyShell);
6154
6155 static bool classof(const Stmt *T) {
6156 return T->getStmtClass() == OMPParallelGenericLoopDirectiveClass;
6157 }
6158};
6159
6160/// This represents '#pragma omp target parallel loop' directive.
6161///
6162/// \code
6163/// #pragma omp target parallel loop private(a,b) order(concurrent)
6164/// \endcode
6165/// In this example directive '#pragma omp target parallel loop' has
6166/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
6167///
6168class OMPTargetParallelGenericLoopDirective final : public OMPLoopDirective {
6169 friend class ASTStmtReader;
6170 friend class OMPExecutableDirective;
6171 /// Build directive with the given start and end location.
6172 ///
6173 /// \param StartLoc Starting location of the directive kind.
6174 /// \param EndLoc Ending location of the directive.
6175 /// \param CollapsedNum Number of collapsed nested loops.
6176 ///
6177 OMPTargetParallelGenericLoopDirective(SourceLocation StartLoc,
6178 SourceLocation EndLoc,
6179 unsigned CollapsedNum)
6180 : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass,
6181 llvm::omp::OMPD_target_parallel_loop, StartLoc, EndLoc,
6182 CollapsedNum) {}
6183
6184 /// Build an empty directive.
6185 ///
6186 /// \param CollapsedNum Number of collapsed nested loops.
6187 ///
6188 explicit OMPTargetParallelGenericLoopDirective(unsigned CollapsedNum)
6189 : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass,
6190 llvm::omp::OMPD_target_parallel_loop, SourceLocation(),
6191 SourceLocation(), CollapsedNum) {}
6192
6193public:
6194 /// Creates directive with a list of \p Clauses.
6195 ///
6196 /// \param C AST context.
6197 /// \param StartLoc Starting location of the directive kind.
6198 /// \param EndLoc Ending Location of the directive.
6199 /// \param CollapsedNum Number of collapsed loops.
6200 /// \param Clauses List of clauses.
6201 /// \param AssociatedStmt Statement, associated with the directive.
6202 /// \param Exprs Helper expressions for CodeGen.
6203 ///
6204 static OMPTargetParallelGenericLoopDirective *
6205 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
6206 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
6207 Stmt *AssociatedStmt, const HelperExprs &Exprs);
6208
6209 /// Creates an empty directive with the place
6210 /// for \a NumClauses clauses.
6211 ///
6212 /// \param C AST context.
6213 /// \param CollapsedNum Number of collapsed nested loops.
6214 /// \param NumClauses Number of clauses.
6215 ///
6216 static OMPTargetParallelGenericLoopDirective *
6217 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
6218 EmptyShell);
6219
6220 static bool classof(const Stmt *T) {
6221 return T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass;
6222 }
6223};
6224
6225/// This represents '#pragma omp error' directive.
6226///
6227/// \code
6228/// #pragma omp error
6229/// \endcode
6230class OMPErrorDirective final : public OMPExecutableDirective {
6231 friend class ASTStmtReader;
6232 friend class OMPExecutableDirective;
6233 /// Build directive with the given start and end location.
6234 ///
6235 /// \param StartLoc Starting location of the directive kind.
6236 /// \param EndLoc Ending location of the directive.
6237 ///
6238 OMPErrorDirective(SourceLocation StartLoc, SourceLocation EndLoc)
6239 : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error,
6240 StartLoc, EndLoc) {}
6241 /// Build an empty directive.
6242 ///
6243 explicit OMPErrorDirective()
6244 : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error,
6245 SourceLocation(), SourceLocation()) {}
6246
6247public:
6248 ///
6249 /// \param C AST context.
6250 /// \param StartLoc Starting location of the directive kind.
6251 /// \param EndLoc Ending Location of the directive.
6252 /// \param Clauses List of clauses.
6253 ///
6254 static OMPErrorDirective *Create(const ASTContext &C, SourceLocation StartLoc,
6255 SourceLocation EndLoc,
6256 ArrayRef<OMPClause *> Clauses);
6257
6258 /// Creates an empty directive.
6259 ///
6260 /// \param C AST context.
6261 ///
6262 static OMPErrorDirective *CreateEmpty(const ASTContext &C,
6263 unsigned NumClauses, EmptyShell);
6264
6265 static bool classof(const Stmt *T) {
6266 return T->getStmtClass() == OMPErrorDirectiveClass;
6267 }
6268};
6269} // end namespace clang
6270
6271#endif
6272