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