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