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