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