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