Thanks to visit codestin.com
Credit goes to clang.llvm.org

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