clang 24.0.0git
StmtOpenMP.h
Go to the documentation of this file.
1//===- StmtOpenMP.h - Classes for OpenMP directives ------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file defines OpenMP AST classes for executable directives and
10/// clauses.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_STMTOPENMP_H
15#define LLVM_CLANG_AST_STMTOPENMP_H
16
18#include "clang/AST/Expr.h"
20#include "clang/AST/Stmt.h"
21#include "clang/AST/StmtCXX.h"
24#include "llvm/Support/Casting.h"
25
26namespace clang {
27
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 standalone '#pragma omp ordered' directive.
2935///
2936/// \code
2937/// #pragma omp ordered
2938/// \endcode
2939///
2940class OMPOrderedStandaloneDirective : 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 OMPOrderedStandaloneDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2949 : OMPExecutableDirective(OMPOrderedStandaloneDirectiveClass,
2950 llvm::omp::OMPD_ordered_standalone, StartLoc,
2951 EndLoc) {}
2952
2953 /// Build an empty directive.
2954 ///
2955 explicit OMPOrderedStandaloneDirective()
2956 : OMPExecutableDirective(OMPOrderedStandaloneDirectiveClass,
2957 llvm::omp::OMPD_ordered_standalone,
2958 SourceLocation(), SourceLocation()) {}
2959
2960public:
2961 /// Creates directive.
2962 ///
2963 /// \param C AST context.
2964 /// \param StartLoc Starting location of the directive kind.
2965 /// \param EndLoc Ending Location of the directive.
2966 /// \param Clauses List of clauses.
2967 ///
2968 static OMPOrderedStandaloneDirective *Create(const ASTContext &C,
2969 SourceLocation StartLoc,
2970 SourceLocation EndLoc,
2971 ArrayRef<OMPClause *> Clauses);
2972
2973 /// Creates an empty directive.
2974 ///
2975 /// \param C AST context.
2976 /// \param NumClauses Number of clauses.
2977 ///
2978 static OMPOrderedStandaloneDirective *
2979 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2980
2981 static bool classof(const Stmt *T) {
2982 return T->getStmtClass() == OMPOrderedStandaloneDirectiveClass;
2983 }
2984};
2985
2986/// This represents block-associated '#pragma omp ordered' directive.
2987///
2988/// \code
2989/// #pragma omp ordered
2990/// { body }
2991/// \endcode
2992///
2993class OMPOrderedBlockAssocDirective : public OMPExecutableDirective {
2994 friend class ASTStmtReader;
2995 friend class OMPExecutableDirective;
2996 /// Build directive with the given start and end location.
2997 ///
2998 /// \param StartLoc Starting location of the directive kind.
2999 /// \param EndLoc Ending location of the directive.
3000 ///
3001 OMPOrderedBlockAssocDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3002 : OMPExecutableDirective(OMPOrderedBlockAssocDirectiveClass,
3003 llvm::omp::OMPD_ordered_blockassoc, StartLoc,
3004 EndLoc) {}
3005
3006 /// Build an empty directive.
3007 ///
3008 explicit OMPOrderedBlockAssocDirective()
3009 : OMPExecutableDirective(OMPOrderedBlockAssocDirectiveClass,
3010 llvm::omp::OMPD_ordered_blockassoc,
3011 SourceLocation(), SourceLocation()) {}
3012
3013public:
3014 /// Creates directive.
3015 ///
3016 /// \param C AST context.
3017 /// \param StartLoc Starting location of the directive kind.
3018 /// \param EndLoc Ending Location of the directive.
3019 /// \param Clauses List of clauses.
3020 /// \param AssociatedStmt Statement, associated with the directive.
3021 ///
3022 static OMPOrderedBlockAssocDirective *
3023 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3024 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3025
3026 /// Creates an empty directive.
3027 ///
3028 /// \param C AST context.
3029 /// \param NumClauses Number of clauses.
3030 ///
3031 static OMPOrderedBlockAssocDirective *
3032 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
3033
3034 static bool classof(const Stmt *T) {
3035 return T->getStmtClass() == OMPOrderedBlockAssocDirectiveClass;
3036 }
3037};
3038
3039/// This represents '#pragma omp atomic' directive.
3040///
3041/// \code
3042/// #pragma omp atomic capture
3043/// \endcode
3044/// In this example directive '#pragma omp atomic' has clause 'capture'.
3045///
3046class OMPAtomicDirective : public OMPExecutableDirective {
3047 friend class ASTStmtReader;
3048 friend class OMPExecutableDirective;
3049
3050 struct FlagTy {
3051 /// Used for 'atomic update' or 'atomic capture' constructs. They may
3052 /// have atomic expressions of forms:
3053 /// \code
3054 /// x = x binop expr;
3055 /// x = expr binop x;
3056 /// \endcode
3057 /// This field is 1 for the first form of the expression and 0 for the
3058 /// second. Required for correct codegen of non-associative operations (like
3059 /// << or >>).
3060 LLVM_PREFERRED_TYPE(bool)
3062 /// Used for 'atomic update' or 'atomic capture' constructs. They may
3063 /// have atomic expressions of forms:
3064 /// \code
3065 /// v = x; <update x>;
3066 /// <update x>; v = x;
3067 /// \endcode
3068 /// This field is 1 for the first(postfix) form of the expression and 0
3069 /// otherwise.
3070 LLVM_PREFERRED_TYPE(bool)
3072 /// 1 if 'v' is updated only when the condition is false (compare capture
3073 /// only).
3074 LLVM_PREFERRED_TYPE(bool)
3075 uint8_t IsFailOnly : 1;
3076 } Flags;
3077
3078 /// Build directive with the given start and end location.
3079 ///
3080 /// \param StartLoc Starting location of the directive kind.
3081 /// \param EndLoc Ending location of the directive.
3082 ///
3083 OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3084 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
3085 StartLoc, EndLoc) {}
3086
3087 /// Build an empty directive.
3088 ///
3089 explicit OMPAtomicDirective()
3090 : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
3091 SourceLocation(), SourceLocation()) {}
3092
3093 enum DataPositionTy : size_t {
3094 POS_X = 0,
3095 POS_V,
3096 POS_E,
3097 POS_UpdateExpr,
3098 POS_D,
3099 POS_Cond,
3100 POS_R,
3101 };
3102
3103 /// Set 'x' part of the associated expression/statement.
3104 void setX(Expr *X) { Data->getChildren()[DataPositionTy::POS_X] = X; }
3105 /// Set helper expression of the form
3106 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
3107 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3108 void setUpdateExpr(Expr *UE) {
3109 Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE;
3110 }
3111 /// Set 'v' part of the associated expression/statement.
3112 void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; }
3113 /// Set 'r' part of the associated expression/statement.
3114 void setR(Expr *R) { Data->getChildren()[DataPositionTy::POS_R] = R; }
3115 /// Set 'expr' part of the associated expression/statement.
3116 void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; }
3117 /// Set 'd' part of the associated expression/statement.
3118 void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; }
3119 /// Set conditional expression in `atomic compare`.
3120 void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; }
3121
3122public:
3123 struct Expressions {
3124 /// 'x' part of the associated expression/statement.
3125 Expr *X = nullptr;
3126 /// 'v' part of the associated expression/statement.
3127 Expr *V = nullptr;
3128 // 'r' part of the associated expression/statement.
3129 Expr *R = nullptr;
3130 /// 'expr' part of the associated expression/statement.
3131 Expr *E = nullptr;
3132 /// UE Helper expression of the form:
3133 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
3134 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3135 Expr *UE = nullptr;
3136 /// 'd' part of the associated expression/statement.
3137 Expr *D = nullptr;
3138 /// Conditional expression in `atomic compare` construct.
3139 Expr *Cond = nullptr;
3140 /// True if UE has the first form and false if the second.
3142 /// True if original value of 'x' must be stored in 'v', not an updated one.
3144 /// True if 'v' is updated only when the condition is false (compare capture
3145 /// only).
3147 };
3148
3149 /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
3150 /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
3151 /// detailed description of 'x', 'v' and 'expr').
3152 ///
3153 /// \param C AST context.
3154 /// \param StartLoc Starting location of the directive kind.
3155 /// \param EndLoc Ending Location of the directive.
3156 /// \param Clauses List of clauses.
3157 /// \param AssociatedStmt Statement, associated with the directive.
3158 /// \param Exprs Associated expressions or statements.
3159 static OMPAtomicDirective *Create(const ASTContext &C,
3160 SourceLocation StartLoc,
3161 SourceLocation EndLoc,
3162 ArrayRef<OMPClause *> Clauses,
3163 Stmt *AssociatedStmt, Expressions Exprs);
3164
3165 /// Creates an empty directive with the place for \a NumClauses
3166 /// clauses.
3167 ///
3168 /// \param C AST context.
3169 /// \param NumClauses Number of clauses.
3170 ///
3171 static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
3172 unsigned NumClauses, EmptyShell);
3173
3174 /// Get 'x' part of the associated expression/statement.
3175 Expr *getX() {
3176 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
3177 }
3178 const Expr *getX() const {
3179 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
3180 }
3181 /// Get helper expression of the form
3182 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
3183 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3185 return cast_or_null<Expr>(
3186 Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
3187 }
3188 const Expr *getUpdateExpr() const {
3189 return cast_or_null<Expr>(
3190 Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
3191 }
3192 /// Return true if helper update expression has form
3193 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
3194 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3195 bool isXLHSInRHSPart() const { return Flags.IsXLHSInRHSPart; }
3196 /// Return true if 'v' expression must be updated to original value of
3197 /// 'x', false if 'v' must be updated to the new value of 'x'.
3198 bool isPostfixUpdate() const { return Flags.IsPostfixUpdate; }
3199 /// Return true if 'v' is updated only when the condition is evaluated false
3200 /// (compare capture only).
3201 bool isFailOnly() const { return Flags.IsFailOnly; }
3202 /// Get 'v' part of the associated expression/statement.
3203 Expr *getV() {
3204 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
3205 }
3206 const Expr *getV() const {
3207 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
3208 }
3209 /// Get 'r' part of the associated expression/statement.
3210 Expr *getR() {
3211 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
3212 }
3213 const Expr *getR() const {
3214 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
3215 }
3216 /// Get 'expr' part of the associated expression/statement.
3217 Expr *getExpr() {
3218 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
3219 }
3220 const Expr *getExpr() const {
3221 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
3222 }
3223 /// Get 'd' part of the associated expression/statement.
3224 Expr *getD() {
3225 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
3226 }
3227 Expr *getD() const {
3228 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
3229 }
3230 /// Get the 'cond' part of the source atomic expression.
3231 Expr *getCondExpr() {
3232 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
3233 }
3234 Expr *getCondExpr() const {
3235 return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
3236 }
3237
3238 static bool classof(const Stmt *T) {
3239 return T->getStmtClass() == OMPAtomicDirectiveClass;
3240 }
3241};
3242
3243/// This represents '#pragma omp target' directive.
3244///
3245/// \code
3246/// #pragma omp target if(a)
3247/// \endcode
3248/// In this example directive '#pragma omp target' has clause 'if' with
3249/// condition 'a'.
3250///
3251class OMPTargetDirective : public OMPExecutableDirective {
3252 friend class ASTStmtReader;
3254 /// Build directive with the given start and end location.
3255 ///
3256 /// \param StartLoc Starting location of the directive kind.
3257 /// \param EndLoc Ending location of the directive.
3258 ///
3259 OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3260 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
3261 StartLoc, EndLoc) {}
3262
3263 /// Build an empty directive.
3264 ///
3265 explicit OMPTargetDirective()
3266 : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
3267 SourceLocation(), SourceLocation()) {}
3268
3269public:
3270 /// Creates directive with a list of \a Clauses.
3271 ///
3272 /// \param C AST context.
3273 /// \param StartLoc Starting location of the directive kind.
3274 /// \param EndLoc Ending Location of the directive.
3275 /// \param Clauses List of clauses.
3276 /// \param AssociatedStmt Statement, associated with the directive.
3277 ///
3278 static OMPTargetDirective *
3279 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3280 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3281
3282 /// Creates an empty directive with the place for \a NumClauses
3283 /// clauses.
3284 ///
3285 /// \param C AST context.
3286 /// \param NumClauses Number of clauses.
3287 ///
3288 static OMPTargetDirective *CreateEmpty(const ASTContext &C,
3289 unsigned NumClauses, EmptyShell);
3290
3291 static bool classof(const Stmt *T) {
3292 return T->getStmtClass() == OMPTargetDirectiveClass;
3293 }
3294};
3295
3296/// This represents '#pragma omp target data' directive.
3297///
3298/// \code
3299/// #pragma omp target data device(0) if(a) map(b[:])
3300/// \endcode
3301/// In this example directive '#pragma omp target data' has clauses 'device'
3302/// with the value '0', 'if' with condition 'a' and 'map' with array
3303/// section 'b[:]'.
3304///
3305class OMPTargetDataDirective : public OMPExecutableDirective {
3306 friend class ASTStmtReader;
3308 /// Build directive with the given start and end location.
3309 ///
3310 /// \param StartLoc Starting location of the directive kind.
3311 /// \param EndLoc Ending Location of the directive.
3312 ///
3313 OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3314 : OMPExecutableDirective(OMPTargetDataDirectiveClass,
3315 llvm::omp::OMPD_target_data, StartLoc, EndLoc) {}
3316
3317 /// Build an empty directive.
3318 ///
3319 explicit OMPTargetDataDirective()
3320 : OMPExecutableDirective(OMPTargetDataDirectiveClass,
3321 llvm::omp::OMPD_target_data, SourceLocation(),
3322 SourceLocation()) {}
3323
3324public:
3325 /// Creates directive with a list of \a Clauses.
3326 ///
3327 /// \param C AST context.
3328 /// \param StartLoc Starting location of the directive kind.
3329 /// \param EndLoc Ending Location of the directive.
3330 /// \param Clauses List of clauses.
3331 /// \param AssociatedStmt Statement, associated with the directive.
3332 ///
3333 static OMPTargetDataDirective *
3334 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3335 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3336
3337 /// Creates an empty directive with the place for \a N clauses.
3338 ///
3339 /// \param C AST context.
3340 /// \param N The number of clauses.
3341 ///
3342 static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
3343 EmptyShell);
3344
3345 static bool classof(const Stmt *T) {
3346 return T->getStmtClass() == OMPTargetDataDirectiveClass;
3347 }
3348};
3349
3350/// This represents '#pragma omp target enter data' directive.
3351///
3352/// \code
3353/// #pragma omp target enter data device(0) if(a) map(b[:])
3354/// \endcode
3355/// In this example directive '#pragma omp target enter data' has clauses
3356/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
3357/// section 'b[:]'.
3358///
3359class OMPTargetEnterDataDirective : public OMPExecutableDirective {
3360 friend class ASTStmtReader;
3362 /// Build directive with the given start and end location.
3363 ///
3364 /// \param StartLoc Starting location of the directive kind.
3365 /// \param EndLoc Ending Location of the directive.
3366 ///
3367 OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3368 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3369 llvm::omp::OMPD_target_enter_data, StartLoc,
3370 EndLoc) {}
3371
3372 /// Build an empty directive.
3373 ///
3375 : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3376 llvm::omp::OMPD_target_enter_data,
3377 SourceLocation(), SourceLocation()) {}
3378
3379public:
3380 /// Creates directive with a list of \a Clauses.
3381 ///
3382 /// \param C AST context.
3383 /// \param StartLoc Starting location of the directive kind.
3384 /// \param EndLoc Ending Location of the directive.
3385 /// \param Clauses List of clauses.
3386 /// \param AssociatedStmt Statement, associated with the directive.
3387 ///
3388 static OMPTargetEnterDataDirective *
3389 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3390 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3391
3392 /// Creates an empty directive with the place for \a N clauses.
3393 ///
3394 /// \param C AST context.
3395 /// \param N The number of clauses.
3396 ///
3397 static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C,
3398 unsigned N, EmptyShell);
3399
3400 static bool classof(const Stmt *T) {
3401 return T->getStmtClass() == OMPTargetEnterDataDirectiveClass;
3402 }
3403};
3404
3405/// This represents '#pragma omp target exit data' directive.
3406///
3407/// \code
3408/// #pragma omp target exit data device(0) if(a) map(b[:])
3409/// \endcode
3410/// In this example directive '#pragma omp target exit data' has clauses
3411/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
3412/// section 'b[:]'.
3413///
3414class OMPTargetExitDataDirective : public OMPExecutableDirective {
3415 friend class ASTStmtReader;
3417 /// Build directive with the given start and end location.
3418 ///
3419 /// \param StartLoc Starting location of the directive kind.
3420 /// \param EndLoc Ending Location of the directive.
3421 ///
3422 OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3423 : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3424 llvm::omp::OMPD_target_exit_data, StartLoc,
3425 EndLoc) {}
3426
3427 /// Build an empty directive.
3428 ///
3430 : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3431 llvm::omp::OMPD_target_exit_data,
3432 SourceLocation(), SourceLocation()) {}
3433
3434public:
3435 /// Creates directive with a list of \a Clauses.
3436 ///
3437 /// \param C AST context.
3438 /// \param StartLoc Starting location of the directive kind.
3439 /// \param EndLoc Ending Location of the directive.
3440 /// \param Clauses List of clauses.
3441 /// \param AssociatedStmt Statement, associated with the directive.
3442 ///
3443 static OMPTargetExitDataDirective *
3444 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3445 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3446
3447 /// Creates an empty directive with the place for \a N clauses.
3448 ///
3449 /// \param C AST context.
3450 /// \param N The number of clauses.
3451 ///
3452 static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
3453 unsigned N, EmptyShell);
3454
3455 static bool classof(const Stmt *T) {
3456 return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
3457 }
3458};
3459
3460/// This represents '#pragma omp target parallel' directive.
3461///
3462/// \code
3463/// #pragma omp target parallel if(a)
3464/// \endcode
3465/// In this example directive '#pragma omp target parallel' has clause 'if' with
3466/// condition 'a'.
3467///
3468class OMPTargetParallelDirective : public OMPExecutableDirective {
3469 friend class ASTStmtReader;
3471 /// true if the construct has inner cancel directive.
3472 bool HasCancel = false;
3473
3474 /// Build directive with the given start and end location.
3475 ///
3476 /// \param StartLoc Starting location of the directive kind.
3477 /// \param EndLoc Ending location of the directive.
3478 ///
3479 OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3480 : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3481 llvm::omp::OMPD_target_parallel, StartLoc,
3482 EndLoc) {}
3483
3484 /// Build an empty directive.
3485 ///
3487 : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3488 llvm::omp::OMPD_target_parallel,
3489 SourceLocation(), SourceLocation()) {}
3490
3491 /// Sets special task reduction descriptor.
3492 void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
3493 /// Set cancel state.
3494 void setHasCancel(bool Has) { HasCancel = Has; }
3495
3496public:
3497 /// Creates directive with a list of \a Clauses.
3498 ///
3499 /// \param C AST context.
3500 /// \param StartLoc Starting location of the directive kind.
3501 /// \param EndLoc Ending Location of the directive.
3502 /// \param Clauses List of clauses.
3503 /// \param AssociatedStmt Statement, associated with the directive.
3504 /// \param TaskRedRef Task reduction special reference expression to handle
3505 /// taskgroup descriptor.
3506 /// \param HasCancel true if this directive has inner cancel directive.
3507 ///
3508 static OMPTargetParallelDirective *
3509 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3510 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
3511 bool HasCancel);
3512
3513 /// Creates an empty directive with the place for \a NumClauses
3514 /// clauses.
3515 ///
3516 /// \param C AST context.
3517 /// \param NumClauses Number of clauses.
3518 ///
3519 static OMPTargetParallelDirective *
3520 CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
3521
3522 /// Returns special task reduction reference expression.
3524 return cast_or_null<Expr>(Data->getChildren()[0]);
3525 }
3526 const Expr *getTaskReductionRefExpr() const {
3527 return const_cast<OMPTargetParallelDirective *>(this)
3529 }
3530
3531 /// Return true if current directive has inner cancel directive.
3532 bool hasCancel() const { return HasCancel; }
3533
3534 static bool classof(const Stmt *T) {
3535 return T->getStmtClass() == OMPTargetParallelDirectiveClass;
3536 }
3537};
3538
3539/// This represents '#pragma omp target parallel for' directive.
3540///
3541/// \code
3542/// #pragma omp target parallel for private(a,b) reduction(+:c,d)
3543/// \endcode
3544/// In this example directive '#pragma omp target parallel for' has clauses
3545/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
3546/// and variables 'c' and 'd'.
3547///
3548class OMPTargetParallelForDirective : public OMPLoopDirective {
3549 friend class ASTStmtReader;
3551
3552 /// true if current region has inner cancel directive.
3553 bool HasCancel = false;
3554
3555 /// Build directive with the given start and end location.
3556 ///
3557 /// \param StartLoc Starting location of the directive kind.
3558 /// \param EndLoc Ending location of the directive.
3559 /// \param CollapsedNum Number of collapsed nested loops.
3560 ///
3561 OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3562 unsigned CollapsedNum)
3563 : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3564 llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc,
3565 CollapsedNum) {}
3566
3567 /// Build an empty directive.
3568 ///
3569 /// \param CollapsedNum Number of collapsed nested loops.
3570 ///
3571 explicit OMPTargetParallelForDirective(unsigned CollapsedNum)
3572 : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3573 llvm::omp::OMPD_target_parallel_for, SourceLocation(),
3574 SourceLocation(), CollapsedNum) {}
3575
3576 /// Sets special task reduction descriptor.
3577 void setTaskReductionRefExpr(Expr *E) {
3578 Data->getChildren()[numLoopChildren(
3579 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E;
3580 }
3581
3582 /// Set cancel state.
3583 void setHasCancel(bool Has) { HasCancel = Has; }
3584
3585public:
3586 /// Creates directive with a list of \a Clauses.
3587 ///
3588 /// \param C AST context.
3589 /// \param StartLoc Starting location of the directive kind.
3590 /// \param EndLoc Ending Location of the directive.
3591 /// \param CollapsedNum Number of collapsed loops.
3592 /// \param Clauses List of clauses.
3593 /// \param AssociatedStmt Statement, associated with the directive.
3594 /// \param Exprs Helper expressions for CodeGen.
3595 /// \param TaskRedRef Task reduction special reference expression to handle
3596 /// taskgroup descriptor.
3597 /// \param HasCancel true if current directive has inner cancel directive.
3598 ///
3599 static OMPTargetParallelForDirective *
3600 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3601 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3602 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
3603 bool HasCancel);
3604
3605 /// Creates an empty directive with the place
3606 /// for \a NumClauses clauses.
3607 ///
3608 /// \param C AST context.
3609 /// \param CollapsedNum Number of collapsed nested loops.
3610 /// \param NumClauses Number of clauses.
3611 ///
3612 static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C,
3613 unsigned NumClauses,
3614 unsigned CollapsedNum,
3615 EmptyShell);
3616
3617 /// Returns special task reduction reference expression.
3619 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
3620 getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]);
3621 }
3622 const Expr *getTaskReductionRefExpr() const {
3623 return const_cast<OMPTargetParallelForDirective *>(this)
3625 }
3626
3627 /// Return true if current directive has inner cancel directive.
3628 bool hasCancel() const { return HasCancel; }
3629
3630 static bool classof(const Stmt *T) {
3631 return T->getStmtClass() == OMPTargetParallelForDirectiveClass;
3632 }
3633};
3634
3635/// This represents '#pragma omp teams' directive.
3636///
3637/// \code
3638/// #pragma omp teams if(a)
3639/// \endcode
3640/// In this example directive '#pragma omp teams' has clause 'if' with
3641/// condition 'a'.
3642///
3643class OMPTeamsDirective : public OMPExecutableDirective {
3644 friend class ASTStmtReader;
3646 /// Build directive with the given start and end location.
3647 ///
3648 /// \param StartLoc Starting location of the directive kind.
3649 /// \param EndLoc Ending location of the directive.
3650 ///
3651 OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3652 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3653 StartLoc, EndLoc) {}
3654
3655 /// Build an empty directive.
3656 ///
3657 explicit OMPTeamsDirective()
3658 : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3659 SourceLocation(), SourceLocation()) {}
3660
3661public:
3662 /// Creates directive with a list of \a Clauses.
3663 ///
3664 /// \param C AST context.
3665 /// \param StartLoc Starting location of the directive kind.
3666 /// \param EndLoc Ending Location of the directive.
3667 /// \param Clauses List of clauses.
3668 /// \param AssociatedStmt Statement, associated with the directive.
3669 ///
3670 static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
3671 SourceLocation EndLoc,
3672 ArrayRef<OMPClause *> Clauses,
3673 Stmt *AssociatedStmt);
3674
3675 /// Creates an empty directive with the place for \a NumClauses
3676 /// clauses.
3677 ///
3678 /// \param C AST context.
3679 /// \param NumClauses Number of clauses.
3680 ///
3681 static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
3682 unsigned NumClauses, EmptyShell);
3683
3684 static bool classof(const Stmt *T) {
3685 return T->getStmtClass() == OMPTeamsDirectiveClass;
3686 }
3687};
3688
3689/// This represents '#pragma omp cancellation point' directive.
3690///
3691/// \code
3692/// #pragma omp cancellation point for
3693/// \endcode
3694///
3695/// In this example a cancellation point is created for innermost 'for' region.
3696class OMPCancellationPointDirective : public OMPExecutableDirective {
3697 friend class ASTStmtReader;
3699 OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
3700 /// Build directive with the given start and end location.
3701 ///
3702 /// \param StartLoc Starting location of the directive kind.
3703 /// \param EndLoc Ending location of the directive.
3704 /// statements and child expressions.
3705 ///
3706 OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3707 : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3708 llvm::omp::OMPD_cancellation_point, StartLoc,
3709 EndLoc) {}
3710
3711 /// Build an empty directive.
3713 : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3714 llvm::omp::OMPD_cancellation_point,
3715 SourceLocation(), SourceLocation()) {}
3716
3717 /// Set cancel region for current cancellation point.
3718 /// \param CR Cancellation region.
3719 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
3720
3721public:
3722 /// Creates directive.
3723 ///
3724 /// \param C AST context.
3725 /// \param StartLoc Starting location of the directive kind.
3726 /// \param EndLoc Ending Location of the directive.
3727 ///
3728 static OMPCancellationPointDirective *
3729 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3730 OpenMPDirectiveKind CancelRegion);
3731
3732 /// Creates an empty directive.
3733 ///
3734 /// \param C AST context.
3735 ///
3736 static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
3737 EmptyShell);
3738
3739 /// Get cancellation region for the current cancellation point.
3740 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
3741
3742 static bool classof(const Stmt *T) {
3743 return T->getStmtClass() == OMPCancellationPointDirectiveClass;
3744 }
3745};
3746
3747/// This represents '#pragma omp cancel' directive.
3748///
3749/// \code
3750/// #pragma omp cancel for
3751/// \endcode
3752///
3753/// In this example a cancel is created for innermost 'for' region.
3754class OMPCancelDirective : public OMPExecutableDirective {
3755 friend class ASTStmtReader;
3757 OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
3758 /// Build directive with the given start and end location.
3759 ///
3760 /// \param StartLoc Starting location of the directive kind.
3761 /// \param EndLoc Ending location of the directive.
3762 ///
3763 OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc)
3764 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3765 StartLoc, EndLoc) {}
3766
3767 /// Build an empty directive.
3768 ///
3769 explicit OMPCancelDirective()
3770 : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3771 SourceLocation(), SourceLocation()) {}
3772
3773 /// Set cancel region for current cancellation point.
3774 /// \param CR Cancellation region.
3775 void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
3776
3777public:
3778 /// Creates directive.
3779 ///
3780 /// \param C AST context.
3781 /// \param StartLoc Starting location of the directive kind.
3782 /// \param EndLoc Ending Location of the directive.
3783 /// \param Clauses List of clauses.
3784 ///
3785 static OMPCancelDirective *
3786 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3787 ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
3788
3789 /// Creates an empty directive.
3790 ///
3791 /// \param C AST context.
3792 /// \param NumClauses Number of clauses.
3793 ///
3794 static OMPCancelDirective *CreateEmpty(const ASTContext &C,
3795 unsigned NumClauses, EmptyShell);
3796
3797 /// Get cancellation region for the current cancellation point.
3798 OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
3799
3800 static bool classof(const Stmt *T) {
3801 return T->getStmtClass() == OMPCancelDirectiveClass;
3802 }
3803};
3804
3805/// This represents '#pragma omp taskloop' directive.
3806///
3807/// \code
3808/// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
3809/// \endcode
3810/// In this example directive '#pragma omp taskloop' has clauses 'private'
3811/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
3812/// 'num_tasks' with expression 'num'.
3813///
3814class OMPTaskLoopDirective : public OMPLoopDirective {
3815 friend class ASTStmtReader;
3817 /// true if the construct has inner cancel directive.
3818 bool HasCancel = false;
3819
3820 /// Build directive with the given start and end location.
3821 ///
3822 /// \param StartLoc Starting location of the directive kind.
3823 /// \param EndLoc Ending location of the directive.
3824 /// \param CollapsedNum Number of collapsed nested loops.
3825 ///
3826 OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3827 unsigned CollapsedNum)
3828 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3829 StartLoc, EndLoc, CollapsedNum) {}
3830
3831 /// Build an empty directive.
3832 ///
3833 /// \param CollapsedNum Number of collapsed nested loops.
3834 ///
3835 explicit OMPTaskLoopDirective(unsigned CollapsedNum)
3836 : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3837 SourceLocation(), SourceLocation(), CollapsedNum) {}
3838
3839 /// Set cancel state.
3840 void setHasCancel(bool Has) { HasCancel = Has; }
3841
3842public:
3843 /// Creates directive with a list of \a Clauses.
3844 ///
3845 /// \param C AST context.
3846 /// \param StartLoc Starting location of the directive kind.
3847 /// \param EndLoc Ending Location of the directive.
3848 /// \param CollapsedNum Number of collapsed loops.
3849 /// \param Clauses List of clauses.
3850 /// \param AssociatedStmt Statement, associated with the directive.
3851 /// \param Exprs Helper expressions for CodeGen.
3852 /// \param HasCancel true if this directive has inner cancel directive.
3853 ///
3854 static OMPTaskLoopDirective *
3855 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3856 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3857 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3858
3859 /// Creates an empty directive with the place
3860 /// for \a NumClauses clauses.
3861 ///
3862 /// \param C AST context.
3863 /// \param CollapsedNum Number of collapsed nested loops.
3864 /// \param NumClauses Number of clauses.
3865 ///
3866 static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
3867 unsigned NumClauses,
3868 unsigned CollapsedNum, EmptyShell);
3869
3870 /// Return true if current directive has inner cancel directive.
3871 bool hasCancel() const { return HasCancel; }
3872
3873 static bool classof(const Stmt *T) {
3874 return T->getStmtClass() == OMPTaskLoopDirectiveClass;
3875 }
3876};
3877
3878/// This represents '#pragma omp taskloop simd' directive.
3879///
3880/// \code
3881/// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
3882/// \endcode
3883/// In this example directive '#pragma omp taskloop simd' has clauses 'private'
3884/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
3885/// 'num_tasks' with expression 'num'.
3886///
3887class OMPTaskLoopSimdDirective : public OMPLoopDirective {
3888 friend class ASTStmtReader;
3890 /// Build directive with the given start and end location.
3891 ///
3892 /// \param StartLoc Starting location of the directive kind.
3893 /// \param EndLoc Ending location of the directive.
3894 /// \param CollapsedNum Number of collapsed nested loops.
3895 ///
3896 OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3897 unsigned CollapsedNum)
3898 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3899 llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc,
3900 CollapsedNum) {}
3901
3902 /// Build an empty directive.
3903 ///
3904 /// \param CollapsedNum Number of collapsed nested loops.
3905 ///
3906 explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum)
3907 : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3908 llvm::omp::OMPD_taskloop_simd, SourceLocation(),
3909 SourceLocation(), CollapsedNum) {}
3910
3911public:
3912 /// Creates directive with a list of \a Clauses.
3913 ///
3914 /// \param C AST context.
3915 /// \param StartLoc Starting location of the directive kind.
3916 /// \param EndLoc Ending Location of the directive.
3917 /// \param CollapsedNum Number of collapsed loops.
3918 /// \param Clauses List of clauses.
3919 /// \param AssociatedStmt Statement, associated with the directive.
3920 /// \param Exprs Helper expressions for CodeGen.
3921 ///
3922 static OMPTaskLoopSimdDirective *
3923 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3924 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3925 Stmt *AssociatedStmt, const HelperExprs &Exprs);
3926
3927 /// Creates an empty directive with the place
3928 /// for \a NumClauses clauses.
3929 ///
3930 /// \param C AST context.
3931 /// \param CollapsedNum Number of collapsed nested loops.
3932 /// \param NumClauses Number of clauses.
3933 ///
3934 static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
3935 unsigned NumClauses,
3936 unsigned CollapsedNum,
3937 EmptyShell);
3938
3939 static bool classof(const Stmt *T) {
3940 return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
3941 }
3942};
3943
3944/// This represents '#pragma omp master taskloop' directive.
3945///
3946/// \code
3947/// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num)
3948/// \endcode
3949/// In this example directive '#pragma omp master taskloop' has clauses
3950/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3951/// and 'num_tasks' with expression 'num'.
3952///
3953class OMPMasterTaskLoopDirective : public OMPLoopDirective {
3954 friend class ASTStmtReader;
3956 /// true if the construct has inner cancel directive.
3957 bool HasCancel = false;
3958
3959 /// Build directive with the given start and end location.
3960 ///
3961 /// \param StartLoc Starting location of the directive kind.
3962 /// \param EndLoc Ending location of the directive.
3963 /// \param CollapsedNum Number of collapsed nested loops.
3964 ///
3965 OMPMasterTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3966 unsigned CollapsedNum)
3967 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3968 llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc,
3969 CollapsedNum) {}
3970
3971 /// Build an empty directive.
3972 ///
3973 /// \param CollapsedNum Number of collapsed nested loops.
3974 ///
3975 explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum)
3976 : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3977 llvm::omp::OMPD_master_taskloop, SourceLocation(),
3978 SourceLocation(), CollapsedNum) {}
3979
3980 /// Set cancel state.
3981 void setHasCancel(bool Has) { HasCancel = Has; }
3982
3983public:
3984 /// Creates directive with a list of \a Clauses.
3985 ///
3986 /// \param C AST context.
3987 /// \param StartLoc Starting location of the directive kind.
3988 /// \param EndLoc Ending Location of the directive.
3989 /// \param CollapsedNum Number of collapsed loops.
3990 /// \param Clauses List of clauses.
3991 /// \param AssociatedStmt Statement, associated with the directive.
3992 /// \param Exprs Helper expressions for CodeGen.
3993 /// \param HasCancel true if this directive has inner cancel directive.
3994 ///
3995 static OMPMasterTaskLoopDirective *
3996 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3997 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3998 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3999
4000 /// Creates an empty directive with the place
4001 /// for \a NumClauses clauses.
4002 ///
4003 /// \param C AST context.
4004 /// \param CollapsedNum Number of collapsed nested loops.
4005 /// \param NumClauses Number of clauses.
4006 ///
4007 static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
4008 unsigned NumClauses,
4009 unsigned CollapsedNum,
4010 EmptyShell);
4011
4012 /// Return true if current directive has inner cancel directive.
4013 bool hasCancel() const { return HasCancel; }
4014
4015 static bool classof(const Stmt *T) {
4016 return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass;
4017 }
4018};
4019
4020/// This represents '#pragma omp masked taskloop' directive.
4021///
4022/// \code
4023/// #pragma omp masked taskloop private(a,b) grainsize(val) num_tasks(num)
4024/// \endcode
4025/// In this example directive '#pragma omp masked taskloop' has clauses
4026/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4027/// and 'num_tasks' with expression 'num'.
4028///
4029class OMPMaskedTaskLoopDirective final : public OMPLoopDirective {
4030 friend class ASTStmtReader;
4032 /// true if the construct has inner cancel directive.
4033 bool HasCancel = false;
4034
4035 /// Build directive with the given start and end location.
4036 ///
4037 /// \param StartLoc Starting location of the directive kind.
4038 /// \param EndLoc Ending location of the directive.
4039 /// \param CollapsedNum Number of collapsed nested loops.
4040 ///
4041 OMPMaskedTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4042 unsigned CollapsedNum)
4043 : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
4044 llvm::omp::OMPD_masked_taskloop, StartLoc, EndLoc,
4045 CollapsedNum) {}
4046
4047 /// Build an empty directive.
4048 ///
4049 /// \param CollapsedNum Number of collapsed nested loops.
4050 ///
4051 explicit OMPMaskedTaskLoopDirective(unsigned CollapsedNum)
4052 : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
4053 llvm::omp::OMPD_masked_taskloop, SourceLocation(),
4054 SourceLocation(), CollapsedNum) {}
4055
4056 /// Set cancel state.
4057 void setHasCancel(bool Has) { HasCancel = Has; }
4058
4059public:
4060 /// Creates directive with a list of \a Clauses.
4061 ///
4062 /// \param C AST context.
4063 /// \param StartLoc Starting location of the directive kind.
4064 /// \param EndLoc Ending Location of the directive.
4065 /// \param CollapsedNum Number of collapsed loops.
4066 /// \param Clauses List of clauses.
4067 /// \param AssociatedStmt Statement, associated with the directive.
4068 /// \param Exprs Helper expressions for CodeGen.
4069 /// \param HasCancel true if this directive has inner cancel directive.
4070 ///
4071 static OMPMaskedTaskLoopDirective *
4072 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4073 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4074 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
4075
4076 /// Creates an empty directive with the place
4077 /// for \a NumClauses clauses.
4078 ///
4079 /// \param C AST context.
4080 /// \param CollapsedNum Number of collapsed nested loops.
4081 /// \param NumClauses Number of clauses.
4082 ///
4083 static OMPMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
4084 unsigned NumClauses,
4085 unsigned CollapsedNum,
4086 EmptyShell);
4087
4088 /// Return true if current directive has inner cancel directive.
4089 bool hasCancel() const { return HasCancel; }
4090
4091 static bool classof(const Stmt *T) {
4092 return T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass;
4093 }
4094};
4095
4096/// This represents '#pragma omp master taskloop simd' directive.
4097///
4098/// \code
4099/// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num)
4100/// \endcode
4101/// In this example directive '#pragma omp master taskloop simd' has clauses
4102/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4103/// and 'num_tasks' with expression 'num'.
4104///
4105class OMPMasterTaskLoopSimdDirective : public OMPLoopDirective {
4106 friend class ASTStmtReader;
4108 /// Build directive with the given start and end location.
4109 ///
4110 /// \param StartLoc Starting location of the directive kind.
4111 /// \param EndLoc Ending location of the directive.
4112 /// \param CollapsedNum Number of collapsed nested loops.
4113 ///
4114 OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4115 unsigned CollapsedNum)
4116 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
4117 llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc,
4118 CollapsedNum) {}
4119
4120 /// Build an empty directive.
4121 ///
4122 /// \param CollapsedNum Number of collapsed nested loops.
4123 ///
4124 explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum)
4125 : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
4126 llvm::omp::OMPD_master_taskloop_simd, SourceLocation(),
4127 SourceLocation(), CollapsedNum) {}
4128
4129public:
4130 /// Creates directive with a list of \p Clauses.
4131 ///
4132 /// \param C AST context.
4133 /// \param StartLoc Starting location of the directive kind.
4134 /// \param EndLoc Ending Location of the directive.
4135 /// \param CollapsedNum Number of collapsed loops.
4136 /// \param Clauses List of clauses.
4137 /// \param AssociatedStmt Statement, associated with the directive.
4138 /// \param Exprs Helper expressions for CodeGen.
4139 ///
4140 static OMPMasterTaskLoopSimdDirective *
4141 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4142 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4143 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4144
4145 /// Creates an empty directive with the place for \p NumClauses clauses.
4146 ///
4147 /// \param C AST context.
4148 /// \param CollapsedNum Number of collapsed nested loops.
4149 /// \param NumClauses Number of clauses.
4150 ///
4151 static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
4152 unsigned NumClauses,
4153 unsigned CollapsedNum,
4154 EmptyShell);
4155
4156 static bool classof(const Stmt *T) {
4157 return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass;
4158 }
4159};
4160
4161/// This represents '#pragma omp masked taskloop simd' directive.
4162///
4163/// \code
4164/// #pragma omp masked taskloop simd private(a,b) grainsize(val) num_tasks(num)
4165/// \endcode
4166/// In this example directive '#pragma omp masked taskloop simd' has clauses
4167/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4168/// and 'num_tasks' with expression 'num'.
4169///
4170class OMPMaskedTaskLoopSimdDirective final : public OMPLoopDirective {
4171 friend class ASTStmtReader;
4173 /// Build directive with the given start and end location.
4174 ///
4175 /// \param StartLoc Starting location of the directive kind.
4176 /// \param EndLoc Ending location of the directive.
4177 /// \param CollapsedNum Number of collapsed nested loops.
4178 ///
4179 OMPMaskedTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4180 unsigned CollapsedNum)
4181 : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
4182 llvm::omp::OMPD_masked_taskloop_simd, StartLoc, EndLoc,
4183 CollapsedNum) {}
4184
4185 /// Build an empty directive.
4186 ///
4187 /// \param CollapsedNum Number of collapsed nested loops.
4188 ///
4189 explicit OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
4190 : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
4191 llvm::omp::OMPD_masked_taskloop_simd, SourceLocation(),
4192 SourceLocation(), CollapsedNum) {}
4193
4194public:
4195 /// Creates directive with a list of \p Clauses.
4196 ///
4197 /// \param C AST context.
4198 /// \param StartLoc Starting location of the directive kind.
4199 /// \param EndLoc Ending Location of the directive.
4200 /// \param CollapsedNum Number of collapsed loops.
4201 /// \param Clauses List of clauses.
4202 /// \param AssociatedStmt Statement, associated with the directive.
4203 /// \param Exprs Helper expressions for CodeGen.
4204 ///
4205 static OMPMaskedTaskLoopSimdDirective *
4206 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4207 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4208 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4209
4210 /// Creates an empty directive with the place for \p NumClauses clauses.
4211 ///
4212 /// \param C AST context.
4213 /// \param CollapsedNum Number of collapsed nested loops.
4214 /// \param NumClauses Number of clauses.
4215 ///
4216 static OMPMaskedTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
4217 unsigned NumClauses,
4218 unsigned CollapsedNum,
4219 EmptyShell);
4220
4221 static bool classof(const Stmt *T) {
4222 return T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass;
4223 }
4224};
4225
4226/// This represents '#pragma omp parallel master taskloop' directive.
4227///
4228/// \code
4229/// #pragma omp parallel master taskloop private(a,b) grainsize(val)
4230/// num_tasks(num)
4231/// \endcode
4232/// In this example directive '#pragma omp parallel master taskloop' has clauses
4233/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4234/// and 'num_tasks' with expression 'num'.
4235///
4236class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective {
4237 friend class ASTStmtReader;
4239 /// true if the construct has inner cancel directive.
4240 bool HasCancel = false;
4241
4242 /// Build directive with the given start and end location.
4243 ///
4244 /// \param StartLoc Starting location of the directive kind.
4245 /// \param EndLoc Ending location of the directive.
4246 /// \param CollapsedNum Number of collapsed nested loops.
4247 ///
4248 OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc,
4249 SourceLocation EndLoc,
4250 unsigned CollapsedNum)
4251 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
4252 llvm::omp::OMPD_parallel_master_taskloop, StartLoc,
4253 EndLoc, CollapsedNum) {}
4254
4255 /// Build an empty directive.
4256 ///
4257 /// \param CollapsedNum Number of collapsed nested loops.
4258 ///
4259 explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum)
4260 : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
4261 llvm::omp::OMPD_parallel_master_taskloop,
4262 SourceLocation(), SourceLocation(), CollapsedNum) {}
4263
4264 /// Set cancel state.
4265 void setHasCancel(bool Has) { HasCancel = Has; }
4266
4267public:
4268 /// Creates directive with a list of \a Clauses.
4269 ///
4270 /// \param C AST context.
4271 /// \param StartLoc Starting location of the directive kind.
4272 /// \param EndLoc Ending Location of the directive.
4273 /// \param CollapsedNum Number of collapsed loops.
4274 /// \param Clauses List of clauses.
4275 /// \param AssociatedStmt Statement, associated with the directive.
4276 /// \param Exprs Helper expressions for CodeGen.
4277 /// \param HasCancel true if this directive has inner cancel directive.
4278 ///
4279 static OMPParallelMasterTaskLoopDirective *
4280 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4281 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4282 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
4283
4284 /// Creates an empty directive with the place
4285 /// for \a NumClauses clauses.
4286 ///
4287 /// \param C AST context.
4288 /// \param CollapsedNum Number of collapsed nested loops.
4289 /// \param NumClauses Number of clauses.
4290 ///
4291 static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
4292 unsigned NumClauses,
4293 unsigned CollapsedNum,
4294 EmptyShell);
4295
4296 /// Return true if current directive has inner cancel directive.
4297 bool hasCancel() const { return HasCancel; }
4298
4299 static bool classof(const Stmt *T) {
4300 return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass;
4301 }
4302};
4303
4304/// This represents '#pragma omp parallel masked taskloop' directive.
4305///
4306/// \code
4307/// #pragma omp parallel masked taskloop private(a,b) grainsize(val)
4308/// num_tasks(num)
4309/// \endcode
4310/// In this example directive '#pragma omp parallel masked taskloop' has clauses
4311/// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4312/// and 'num_tasks' with expression 'num'.
4313///
4314class OMPParallelMaskedTaskLoopDirective final : public OMPLoopDirective {
4315 friend class ASTStmtReader;
4317 /// true if the construct has inner cancel directive.
4318 bool HasCancel = false;
4319
4320 /// Build directive with the given start and end location.
4321 ///
4322 /// \param StartLoc Starting location of the directive kind.
4323 /// \param EndLoc Ending location of the directive.
4324 /// \param CollapsedNum Number of collapsed nested loops.
4325 ///
4326 OMPParallelMaskedTaskLoopDirective(SourceLocation StartLoc,
4327 SourceLocation EndLoc,
4328 unsigned CollapsedNum)
4329 : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
4330 llvm::omp::OMPD_parallel_masked_taskloop, StartLoc,
4331 EndLoc, CollapsedNum) {}
4332
4333 /// Build an empty directive.
4334 ///
4335 /// \param CollapsedNum Number of collapsed nested loops.
4336 ///
4337 explicit OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum)
4338 : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
4339 llvm::omp::OMPD_parallel_masked_taskloop,
4340 SourceLocation(), SourceLocation(), CollapsedNum) {}
4341
4342 /// Set cancel state.
4343 void setHasCancel(bool Has) { HasCancel = Has; }
4344
4345public:
4346 /// Creates directive with a list of \a Clauses.
4347 ///
4348 /// \param C AST context.
4349 /// \param StartLoc Starting location of the directive kind.
4350 /// \param EndLoc Ending Location of the directive.
4351 /// \param CollapsedNum Number of collapsed loops.
4352 /// \param Clauses List of clauses.
4353 /// \param AssociatedStmt Statement, associated with the directive.
4354 /// \param Exprs Helper expressions for CodeGen.
4355 /// \param HasCancel true if this directive has inner cancel directive.
4356 ///
4357 static OMPParallelMaskedTaskLoopDirective *
4358 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4359 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4360 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
4361
4362 /// Creates an empty directive with the place
4363 /// for \a NumClauses clauses.
4364 ///
4365 /// \param C AST context.
4366 /// \param CollapsedNum Number of collapsed nested loops.
4367 /// \param NumClauses Number of clauses.
4368 ///
4369 static OMPParallelMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
4370 unsigned NumClauses,
4371 unsigned CollapsedNum,
4372 EmptyShell);
4373
4374 /// Return true if current directive has inner cancel directive.
4375 bool hasCancel() const { return HasCancel; }
4376
4377 static bool classof(const Stmt *T) {
4378 return T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass;
4379 }
4380};
4381
4382/// This represents '#pragma omp parallel master taskloop simd' directive.
4383///
4384/// \code
4385/// #pragma omp parallel master taskloop simd private(a,b) grainsize(val)
4386/// num_tasks(num)
4387/// \endcode
4388/// In this example directive '#pragma omp parallel master taskloop simd' has
4389/// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
4390/// expression 'val' and 'num_tasks' with expression 'num'.
4391///
4392class OMPParallelMasterTaskLoopSimdDirective : public OMPLoopDirective {
4393 friend class ASTStmtReader;
4395 /// Build directive with the given start and end location.
4396 ///
4397 /// \param StartLoc Starting location of the directive kind.
4398 /// \param EndLoc Ending location of the directive.
4399 /// \param CollapsedNum Number of collapsed nested loops.
4400 ///
4401 OMPParallelMasterTaskLoopSimdDirective(SourceLocation StartLoc,
4402 SourceLocation EndLoc,
4403 unsigned CollapsedNum)
4404 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
4405 llvm::omp::OMPD_parallel_master_taskloop_simd,
4406 StartLoc, EndLoc, CollapsedNum) {}
4407
4408 /// Build an empty directive.
4409 ///
4410 /// \param CollapsedNum Number of collapsed nested loops.
4411 ///
4412 explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum)
4413 : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
4414 llvm::omp::OMPD_parallel_master_taskloop_simd,
4415 SourceLocation(), SourceLocation(), CollapsedNum) {}
4416
4417public:
4418 /// Creates directive with a list of \p Clauses.
4419 ///
4420 /// \param C AST context.
4421 /// \param StartLoc Starting location of the directive kind.
4422 /// \param EndLoc Ending Location of the directive.
4423 /// \param CollapsedNum Number of collapsed loops.
4424 /// \param Clauses List of clauses.
4425 /// \param AssociatedStmt Statement, associated with the directive.
4426 /// \param Exprs Helper expressions for CodeGen.
4427 ///
4428 static OMPParallelMasterTaskLoopSimdDirective *
4429 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4430 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4431 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4432
4433 /// Creates an empty directive with the place
4434 /// for \a NumClauses clauses.
4435 ///
4436 /// \param C AST context.
4437 /// \param CollapsedNum Number of collapsed nested loops.
4438 /// \param NumClauses Number of clauses.
4439 ///
4440 static OMPParallelMasterTaskLoopSimdDirective *
4441 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4442 EmptyShell);
4443
4444 static bool classof(const Stmt *T) {
4445 return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass;
4446 }
4447};
4448
4449/// This represents '#pragma omp parallel masked taskloop simd' directive.
4450///
4451/// \code
4452/// #pragma omp parallel masked taskloop simd private(a,b) grainsize(val)
4453/// num_tasks(num)
4454/// \endcode
4455/// In this example directive '#pragma omp parallel masked taskloop simd' has
4456/// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
4457/// expression 'val' and 'num_tasks' with expression 'num'.
4458///
4459class OMPParallelMaskedTaskLoopSimdDirective final : public OMPLoopDirective {
4460 friend class ASTStmtReader;
4462 /// Build directive with the given start and end location.
4463 ///
4464 /// \param StartLoc Starting location of the directive kind.
4465 /// \param EndLoc Ending location of the directive.
4466 /// \param CollapsedNum Number of collapsed nested loops.
4467 ///
4468 OMPParallelMaskedTaskLoopSimdDirective(SourceLocation StartLoc,
4469 SourceLocation EndLoc,
4470 unsigned CollapsedNum)
4471 : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
4472 llvm::omp::OMPD_parallel_masked_taskloop_simd,
4473 StartLoc, EndLoc, CollapsedNum) {}
4474
4475 /// Build an empty directive.
4476 ///
4477 /// \param CollapsedNum Number of collapsed nested loops.
4478 ///
4479 explicit OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
4480 : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
4481 llvm::omp::OMPD_parallel_masked_taskloop_simd,
4482 SourceLocation(), SourceLocation(), CollapsedNum) {}
4483
4484public:
4485 /// Creates directive with a list of \p Clauses.
4486 ///
4487 /// \param C AST context.
4488 /// \param StartLoc Starting location of the directive kind.
4489 /// \param EndLoc Ending Location of the directive.
4490 /// \param CollapsedNum Number of collapsed loops.
4491 /// \param Clauses List of clauses.
4492 /// \param AssociatedStmt Statement, associated with the directive.
4493 /// \param Exprs Helper expressions for CodeGen.
4494 ///
4495 static OMPParallelMaskedTaskLoopSimdDirective *
4496 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4497 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4498 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4499
4500 /// Creates an empty directive with the place
4501 /// for \a NumClauses clauses.
4502 ///
4503 /// \param C AST context.
4504 /// \param CollapsedNum Number of collapsed nested loops.
4505 /// \param NumClauses Number of clauses.
4506 ///
4507 static OMPParallelMaskedTaskLoopSimdDirective *
4508 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4509 EmptyShell);
4510
4511 static bool classof(const Stmt *T) {
4512 return T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass;
4513 }
4514};
4515
4516/// This represents '#pragma omp distribute' directive.
4517///
4518/// \code
4519/// #pragma omp distribute private(a,b)
4520/// \endcode
4521/// In this example directive '#pragma omp distribute' has clauses 'private'
4522/// with the variables 'a' and 'b'
4523///
4524class OMPDistributeDirective : public OMPLoopDirective {
4525 friend class ASTStmtReader;
4527
4528 /// Build directive with the given start and end location.
4529 ///
4530 /// \param StartLoc Starting location of the directive kind.
4531 /// \param EndLoc Ending location of the directive.
4532 /// \param CollapsedNum Number of collapsed nested loops.
4533 ///
4534 OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4535 unsigned CollapsedNum)
4536 : OMPLoopDirective(OMPDistributeDirectiveClass,
4537 llvm::omp::OMPD_distribute, StartLoc, EndLoc,
4538 CollapsedNum) {}
4539
4540 /// Build an empty directive.
4541 ///
4542 /// \param CollapsedNum Number of collapsed nested loops.
4543 ///
4544 explicit OMPDistributeDirective(unsigned CollapsedNum)
4545 : OMPLoopDirective(OMPDistributeDirectiveClass,
4546 llvm::omp::OMPD_distribute, SourceLocation(),
4547 SourceLocation(), CollapsedNum) {}
4548
4549public:
4550 /// Creates directive with a list of \a Clauses.
4551 ///
4552 /// \param C AST context.
4553 /// \param StartLoc Starting location of the directive kind.
4554 /// \param EndLoc Ending Location of the directive.
4555 /// \param CollapsedNum Number of collapsed loops.
4556 /// \param Clauses List of clauses.
4557 /// \param AssociatedStmt Statement, associated with the directive.
4558 /// \param Exprs Helper expressions for CodeGen.
4559 ///
4560 static OMPDistributeDirective *
4561 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4562 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4563 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4564
4565 /// Creates an empty directive with the place
4566 /// for \a NumClauses clauses.
4567 ///
4568 /// \param C AST context.
4569 /// \param CollapsedNum Number of collapsed nested loops.
4570 /// \param NumClauses Number of clauses.
4571 ///
4572 static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
4573 unsigned NumClauses,
4574 unsigned CollapsedNum, EmptyShell);
4575
4576 static bool classof(const Stmt *T) {
4577 return T->getStmtClass() == OMPDistributeDirectiveClass;
4578 }
4579};
4580
4581/// This represents '#pragma omp target update' directive.
4582///
4583/// \code
4584/// #pragma omp target update to(a) from(b) device(1)
4585/// \endcode
4586/// In this example directive '#pragma omp target update' has clause 'to' with
4587/// argument 'a', clause 'from' with argument 'b' and clause 'device' with
4588/// argument '1'.
4589///
4590class OMPTargetUpdateDirective : public OMPExecutableDirective {
4591 friend class ASTStmtReader;
4593 /// Build directive with the given start and end location.
4594 ///
4595 /// \param StartLoc Starting location of the directive kind.
4596 /// \param EndLoc Ending Location of the directive.
4597 ///
4598 OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc)
4599 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
4600 llvm::omp::OMPD_target_update, StartLoc,
4601 EndLoc) {}
4602
4603 /// Build an empty directive.
4604 ///
4605 explicit OMPTargetUpdateDirective()
4606 : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
4607 llvm::omp::OMPD_target_update, SourceLocation(),
4608 SourceLocation()) {}
4609
4610public:
4611 /// Creates directive with a list of \a Clauses.
4612 ///
4613 /// \param C AST context.
4614 /// \param StartLoc Starting location of the directive kind.
4615 /// \param EndLoc Ending Location of the directive.
4616 /// \param Clauses List of clauses.
4617 /// \param AssociatedStmt Statement, associated with the directive.
4618 ///
4619 static OMPTargetUpdateDirective *
4620 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4621 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
4622
4623 /// Creates an empty directive with the place for \a NumClauses
4624 /// clauses.
4625 ///
4626 /// \param C AST context.
4627 /// \param NumClauses The number of clauses.
4628 ///
4629 static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C,
4630 unsigned NumClauses, EmptyShell);
4631
4632 static bool classof(const Stmt *T) {
4633 return T->getStmtClass() == OMPTargetUpdateDirectiveClass;
4634 }
4635};
4636
4637/// This represents '#pragma omp distribute parallel for' composite
4638/// directive.
4639///
4640/// \code
4641/// #pragma omp distribute parallel for private(a,b)
4642/// \endcode
4643/// In this example directive '#pragma omp distribute parallel for' has clause
4644/// 'private' with the variables 'a' and 'b'
4645///
4646class OMPDistributeParallelForDirective : public OMPLoopDirective {
4647 friend class ASTStmtReader;
4649 /// true if the construct has inner cancel directive.
4650 bool HasCancel = false;
4651
4652 /// Build directive with the given start and end location.
4653 ///
4654 /// \param StartLoc Starting location of the directive kind.
4655 /// \param EndLoc Ending location of the directive.
4656 /// \param CollapsedNum Number of collapsed nested loops.
4657 ///
4658 OMPDistributeParallelForDirective(SourceLocation StartLoc,
4659 SourceLocation EndLoc,
4660 unsigned CollapsedNum)
4661 : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4662 llvm::omp::OMPD_distribute_parallel_for, StartLoc,
4663 EndLoc, CollapsedNum) {}
4664
4665 /// Build an empty directive.
4666 ///
4667 /// \param CollapsedNum Number of collapsed nested loops.
4668 ///
4669 explicit OMPDistributeParallelForDirective(unsigned CollapsedNum)
4670 : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4671 llvm::omp::OMPD_distribute_parallel_for,
4672 SourceLocation(), SourceLocation(), CollapsedNum) {}
4673
4674 /// Sets special task reduction descriptor.
4675 void setTaskReductionRefExpr(Expr *E) {
4676 Data->getChildren()[numLoopChildren(
4677 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E;
4678 }
4679
4680 /// Set cancel state.
4681 void setHasCancel(bool Has) { HasCancel = Has; }
4682
4683public:
4684 /// Creates directive with a list of \a Clauses.
4685 ///
4686 /// \param C AST context.
4687 /// \param StartLoc Starting location of the directive kind.
4688 /// \param EndLoc Ending Location of the directive.
4689 /// \param CollapsedNum Number of collapsed loops.
4690 /// \param Clauses List of clauses.
4691 /// \param AssociatedStmt Statement, associated with the directive.
4692 /// \param Exprs Helper expressions for CodeGen.
4693 /// \param TaskRedRef Task reduction special reference expression to handle
4694 /// taskgroup descriptor.
4695 /// \param HasCancel true if this directive has inner cancel directive.
4696 ///
4697 static OMPDistributeParallelForDirective *
4698 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4699 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4700 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
4701 bool HasCancel);
4702
4703 /// Creates an empty directive with the place
4704 /// for \a NumClauses clauses.
4705 ///
4706 /// \param C AST context.
4707 /// \param CollapsedNum Number of collapsed nested loops.
4708 /// \param NumClauses Number of clauses.
4709 ///
4710 static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C,
4711 unsigned NumClauses,
4712 unsigned CollapsedNum,
4713 EmptyShell);
4714
4715 /// Returns special task reduction reference expression.
4717 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
4718 getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]);
4719 }
4720 const Expr *getTaskReductionRefExpr() const {
4721 return const_cast<OMPDistributeParallelForDirective *>(this)
4723 }
4724
4725 /// Return true if current directive has inner cancel directive.
4726 bool hasCancel() const { return HasCancel; }
4727
4728 static bool classof(const Stmt *T) {
4729 return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
4730 }
4731};
4732
4733/// This represents '#pragma omp distribute parallel for simd' composite
4734/// directive.
4735///
4736/// \code
4737/// #pragma omp distribute parallel for simd private(x)
4738/// \endcode
4739/// In this example directive '#pragma omp distribute parallel for simd' has
4740/// clause 'private' with the variables 'x'
4741///
4742class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective {
4743 friend class ASTStmtReader;
4745
4746 /// Build directive with the given start and end location.
4747 ///
4748 /// \param StartLoc Starting location of the directive kind.
4749 /// \param EndLoc Ending location of the directive.
4750 /// \param CollapsedNum Number of collapsed nested loops.
4751 ///
4752 OMPDistributeParallelForSimdDirective(SourceLocation StartLoc,
4753 SourceLocation EndLoc,
4754 unsigned CollapsedNum)
4755 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4756 llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc,
4757 EndLoc, CollapsedNum) {}
4758
4759 /// Build an empty directive.
4760 ///
4761 /// \param CollapsedNum Number of collapsed nested loops.
4762 ///
4763 explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum)
4764 : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4765 llvm::omp::OMPD_distribute_parallel_for_simd,
4766 SourceLocation(), SourceLocation(), CollapsedNum) {}
4767
4768public:
4769 /// Creates directive with a list of \a Clauses.
4770 ///
4771 /// \param C AST context.
4772 /// \param StartLoc Starting location of the directive kind.
4773 /// \param EndLoc Ending Location of the directive.
4774 /// \param CollapsedNum Number of collapsed loops.
4775 /// \param Clauses List of clauses.
4776 /// \param AssociatedStmt Statement, associated with the directive.
4777 /// \param Exprs Helper expressions for CodeGen.
4778 ///
4779 static OMPDistributeParallelForSimdDirective *Create(
4780 const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4781 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4782 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4783
4784 /// Creates an empty directive with the place for \a NumClauses clauses.
4785 ///
4786 /// \param C AST context.
4787 /// \param CollapsedNum Number of collapsed nested loops.
4788 /// \param NumClauses Number of clauses.
4789 ///
4790 static OMPDistributeParallelForSimdDirective *CreateEmpty(
4791 const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4792 EmptyShell);
4793
4794 static bool classof(const Stmt *T) {
4795 return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass;
4796 }
4797};
4798
4799/// This represents '#pragma omp distribute simd' composite directive.
4800///
4801/// \code
4802/// #pragma omp distribute simd private(x)
4803/// \endcode
4804/// In this example directive '#pragma omp distribute simd' has clause
4805/// 'private' with the variables 'x'
4806///
4807class OMPDistributeSimdDirective final : public OMPLoopDirective {
4808 friend class ASTStmtReader;
4810
4811 /// Build directive with the given start and end location.
4812 ///
4813 /// \param StartLoc Starting location of the directive kind.
4814 /// \param EndLoc Ending location of the directive.
4815 /// \param CollapsedNum Number of collapsed nested loops.
4816 ///
4817 OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4818 unsigned CollapsedNum)
4819 : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4820 llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc,
4821 CollapsedNum) {}
4822
4823 /// Build an empty directive.
4824 ///
4825 /// \param CollapsedNum Number of collapsed nested loops.
4826 ///
4827 explicit OMPDistributeSimdDirective(unsigned CollapsedNum)
4828 : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4829 llvm::omp::OMPD_distribute_simd, SourceLocation(),
4830 SourceLocation(), CollapsedNum) {}
4831
4832public:
4833 /// Creates directive with a list of \a Clauses.
4834 ///
4835 /// \param C AST context.
4836 /// \param StartLoc Starting location of the directive kind.
4837 /// \param EndLoc Ending Location of the directive.
4838 /// \param CollapsedNum Number of collapsed loops.
4839 /// \param Clauses List of clauses.
4840 /// \param AssociatedStmt Statement, associated with the directive.
4841 /// \param Exprs Helper expressions for CodeGen.
4842 ///
4843 static OMPDistributeSimdDirective *
4844 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4845 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4846 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4847
4848 /// Creates an empty directive with the place for \a NumClauses clauses.
4849 ///
4850 /// \param C AST context.
4851 /// \param CollapsedNum Number of collapsed nested loops.
4852 /// \param NumClauses Number of clauses.
4853 ///
4854 static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C,
4855 unsigned NumClauses,
4856 unsigned CollapsedNum,
4857 EmptyShell);
4858
4859 static bool classof(const Stmt *T) {
4860 return T->getStmtClass() == OMPDistributeSimdDirectiveClass;
4861 }
4862};
4863
4864/// This represents '#pragma omp target parallel for simd' directive.
4865///
4866/// \code
4867/// #pragma omp target parallel for simd private(a) map(b) safelen(c)
4868/// \endcode
4869/// In this example directive '#pragma omp target parallel for simd' has clauses
4870/// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen'
4871/// with the variable 'c'.
4872///
4873class OMPTargetParallelForSimdDirective final : public OMPLoopDirective {
4874 friend class ASTStmtReader;
4876
4877 /// Build directive with the given start and end location.
4878 ///
4879 /// \param StartLoc Starting location of the directive kind.
4880 /// \param EndLoc Ending location of the directive.
4881 /// \param CollapsedNum Number of collapsed nested loops.
4882 ///
4883 OMPTargetParallelForSimdDirective(SourceLocation StartLoc,
4884 SourceLocation EndLoc,
4885 unsigned CollapsedNum)
4886 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4887 llvm::omp::OMPD_target_parallel_for_simd, StartLoc,
4888 EndLoc, CollapsedNum) {}
4889
4890 /// Build an empty directive.
4891 ///
4892 /// \param CollapsedNum Number of collapsed nested loops.
4893 ///
4894 explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum)
4895 : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4896 llvm::omp::OMPD_target_parallel_for_simd,
4897 SourceLocation(), SourceLocation(), CollapsedNum) {}
4898
4899public:
4900 /// Creates directive with a list of \a Clauses.
4901 ///
4902 /// \param C AST context.
4903 /// \param StartLoc Starting location of the directive kind.
4904 /// \param EndLoc Ending Location of the directive.
4905 /// \param CollapsedNum Number of collapsed loops.
4906 /// \param Clauses List of clauses.
4907 /// \param AssociatedStmt Statement, associated with the directive.
4908 /// \param Exprs Helper expressions for CodeGen.
4909 ///
4910 static OMPTargetParallelForSimdDirective *
4911 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4912 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4913 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4914
4915 /// Creates an empty directive with the place for \a NumClauses clauses.
4916 ///
4917 /// \param C AST context.
4918 /// \param CollapsedNum Number of collapsed nested loops.
4919 /// \param NumClauses Number of clauses.
4920 ///
4921 static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C,
4922 unsigned NumClauses,
4923 unsigned CollapsedNum,
4924 EmptyShell);
4925
4926 static bool classof(const Stmt *T) {
4927 return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
4928 }
4929};
4930
4931/// This represents '#pragma omp target simd' directive.
4932///
4933/// \code
4934/// #pragma omp target simd private(a) map(b) safelen(c)
4935/// \endcode
4936/// In this example directive '#pragma omp target simd' has clauses 'private'
4937/// with the variable 'a', 'map' with the variable 'b' and 'safelen' with
4938/// the variable 'c'.
4939///
4940class OMPTargetSimdDirective final : public OMPLoopDirective {
4941 friend class ASTStmtReader;
4943
4944 /// Build directive with the given start and end location.
4945 ///
4946 /// \param StartLoc Starting location of the directive kind.
4947 /// \param EndLoc Ending location of the directive.
4948 /// \param CollapsedNum Number of collapsed nested loops.
4949 ///
4950 OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
4951 unsigned CollapsedNum)
4952 : OMPLoopDirective(OMPTargetSimdDirectiveClass,
4953 llvm::omp::OMPD_target_simd, StartLoc, EndLoc,
4954 CollapsedNum) {}
4955
4956 /// Build an empty directive.
4957 ///
4958 /// \param CollapsedNum Number of collapsed nested loops.
4959 ///
4960 explicit OMPTargetSimdDirective(unsigned CollapsedNum)
4961 : OMPLoopDirective(OMPTargetSimdDirectiveClass,
4962 llvm::omp::OMPD_target_simd, SourceLocation(),
4963 SourceLocation(), CollapsedNum) {}
4964
4965public:
4966 /// Creates directive with a list of \a Clauses.
4967 ///
4968 /// \param C AST context.
4969 /// \param StartLoc Starting location of the directive kind.
4970 /// \param EndLoc Ending Location of the directive.
4971 /// \param CollapsedNum Number of collapsed loops.
4972 /// \param Clauses List of clauses.
4973 /// \param AssociatedStmt Statement, associated with the directive.
4974 /// \param Exprs Helper expressions for CodeGen.
4975 ///
4976 static OMPTargetSimdDirective *
4977 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4978 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4979 Stmt *AssociatedStmt, const HelperExprs &Exprs);
4980
4981 /// Creates an empty directive with the place for \a NumClauses clauses.
4982 ///
4983 /// \param C AST context.
4984 /// \param CollapsedNum Number of collapsed nested loops.
4985 /// \param NumClauses Number of clauses.
4986 ///
4987 static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C,
4988 unsigned NumClauses,
4989 unsigned CollapsedNum,
4990 EmptyShell);
4991
4992 static bool classof(const Stmt *T) {
4993 return T->getStmtClass() == OMPTargetSimdDirectiveClass;
4994 }
4995};
4996
4997/// This represents '#pragma omp teams distribute' directive.
4998///
4999/// \code
5000/// #pragma omp teams distribute private(a,b)
5001/// \endcode
5002/// In this example directive '#pragma omp teams distribute' has clauses
5003/// 'private' with the variables 'a' and 'b'
5004///
5005class OMPTeamsDistributeDirective final : public OMPLoopDirective {
5006 friend class ASTStmtReader;
5008
5009 /// Build directive with the given start and end location.
5010 ///
5011 /// \param StartLoc Starting location of the directive kind.
5012 /// \param EndLoc Ending location of the directive.
5013 /// \param CollapsedNum Number of collapsed nested loops.
5014 ///
5015 OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
5016 unsigned CollapsedNum)
5017 : OMPLoopDirective(OMPTeamsDistributeDirectiveClass,
5018 llvm::omp::OMPD_teams_distribute, StartLoc, EndLoc,
5019 CollapsedNum) {}
5020
5021 /// Build an empty directive.
5022 ///
5023 /// \param CollapsedNum Number of collapsed nested loops.
5024 ///
5025 explicit OMPTeamsDistributeDirective(unsigned CollapsedNum)
5026 : OMPLoopDirective(OMPTeamsDistributeDirectiveClass,
5027 llvm::omp::OMPD_teams_distribute, SourceLocation(),
5028 SourceLocation(), CollapsedNum) {}
5029
5030public:
5031 /// Creates directive with a list of \a Clauses.
5032 ///
5033 /// \param C AST context.
5034 /// \param StartLoc Starting location of the directive kind.
5035 /// \param EndLoc Ending Location of the directive.
5036 /// \param CollapsedNum Number of collapsed loops.
5037 /// \param Clauses List of clauses.
5038 /// \param AssociatedStmt Statement, associated with the directive.
5039 /// \param Exprs Helper expressions for CodeGen.
5040 ///
5041 static OMPTeamsDistributeDirective *
5042 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5043 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5044 Stmt *AssociatedStmt, const HelperExprs &Exprs);
5045
5046 /// Creates an empty directive with the place for \a NumClauses clauses.
5047 ///
5048 /// \param C AST context.
5049 /// \param CollapsedNum Number of collapsed nested loops.
5050 /// \param NumClauses Number of clauses.
5051 ///
5052 static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C,
5053 unsigned NumClauses,
5054 unsigned CollapsedNum,
5055 EmptyShell);
5056
5057 static bool classof(const Stmt *T) {
5058 return T->getStmtClass() == OMPTeamsDistributeDirectiveClass;
5059 }
5060};
5061
5062/// This represents '#pragma omp teams distribute simd'
5063/// combined directive.
5064///
5065/// \code
5066/// #pragma omp teams distribute simd private(a,b)
5067/// \endcode
5068/// In this example directive '#pragma omp teams distribute simd'
5069/// has clause 'private' with the variables 'a' and 'b'
5070///
5071class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective {
5072 friend class ASTStmtReader;
5074
5075 /// Build directive with the given start and end location.
5076 ///
5077 /// \param StartLoc Starting location of the directive kind.
5078 /// \param EndLoc Ending location of the directive.
5079 /// \param CollapsedNum Number of collapsed nested loops.
5080 ///
5081 OMPTeamsDistributeSimdDirective(SourceLocation StartLoc,
5082 SourceLocation EndLoc, unsigned CollapsedNum)
5083 : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass,
5084 llvm::omp::OMPD_teams_distribute_simd, StartLoc,
5085 EndLoc, CollapsedNum) {}
5086
5087 /// Build an empty directive.
5088 ///
5089 /// \param CollapsedNum Number of collapsed nested loops.
5090 ///
5091 explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum)
5092 : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass,
5093 llvm::omp::OMPD_teams_distribute_simd,
5094 SourceLocation(), SourceLocation(), CollapsedNum) {}
5095
5096public:
5097 /// Creates directive with a list of \a Clauses.
5098 ///
5099 /// \param C AST context.
5100 /// \param StartLoc Starting location of the directive kind.
5101 /// \param EndLoc Ending Location of the directive.
5102 /// \param CollapsedNum Number of collapsed loops.
5103 /// \param Clauses List of clauses.
5104 /// \param AssociatedStmt Statement, associated with the directive.
5105 /// \param Exprs Helper expressions for CodeGen.
5106 ///
5107 static OMPTeamsDistributeSimdDirective *
5108 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5109 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5110 Stmt *AssociatedStmt, const HelperExprs &Exprs);
5111
5112 /// Creates an empty directive with the place
5113 /// for \a NumClauses clauses.
5114 ///
5115 /// \param C AST context.
5116 /// \param CollapsedNum Number of collapsed nested loops.
5117 /// \param NumClauses Number of clauses.
5118 ///
5119 static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C,
5120 unsigned NumClauses,
5121 unsigned CollapsedNum,
5122 EmptyShell);
5123
5124 static bool classof(const Stmt *T) {
5125 return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass;
5126 }
5127};
5128
5129/// This represents '#pragma omp teams distribute parallel for simd' composite
5130/// directive.
5131///
5132/// \code
5133/// #pragma omp teams distribute parallel for simd private(x)
5134/// \endcode
5135/// In this example directive '#pragma omp teams distribute parallel for simd'
5136/// has clause 'private' with the variables 'x'
5137///
5138class OMPTeamsDistributeParallelForSimdDirective final
5139 : public OMPLoopDirective {
5140 friend class ASTStmtReader;
5142
5143 /// Build directive with the given start and end location.
5144 ///
5145 /// \param StartLoc Starting location of the directive kind.
5146 /// \param EndLoc Ending location of the directive.
5147 /// \param CollapsedNum Number of collapsed nested loops.
5148 ///
5149 OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
5150 SourceLocation EndLoc,
5151 unsigned CollapsedNum)
5152 : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass,
5153 llvm::omp::OMPD_teams_distribute_parallel_for_simd,
5154 StartLoc, EndLoc, CollapsedNum) {}
5155
5156 /// Build an empty directive.
5157 ///
5158 /// \param CollapsedNum Number of collapsed nested loops.
5159 ///
5160 explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum)
5161 : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass,
5162 llvm::omp::OMPD_teams_distribute_parallel_for_simd,
5163 SourceLocation(), SourceLocation(), CollapsedNum) {}
5164
5165public:
5166 /// Creates directive with a list of \a Clauses.
5167 ///
5168 /// \param C AST context.
5169 /// \param StartLoc Starting location of the directive kind.
5170 /// \param EndLoc Ending Location of the directive.
5171 /// \param CollapsedNum Number of collapsed loops.
5172 /// \param Clauses List of clauses.
5173 /// \param AssociatedStmt Statement, associated with the directive.
5174 /// \param Exprs Helper expressions for CodeGen.
5175 ///
5176 static OMPTeamsDistributeParallelForSimdDirective *
5177 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5178 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5179 Stmt *AssociatedStmt, const HelperExprs &Exprs);
5180
5181 /// Creates an empty directive with the place for \a NumClauses clauses.
5182 ///
5183 /// \param C AST context.
5184 /// \param CollapsedNum Number of collapsed nested loops.
5185 /// \param NumClauses Number of clauses.
5186 ///
5187 static OMPTeamsDistributeParallelForSimdDirective *
5188 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5189 EmptyShell);
5190
5191 static bool classof(const Stmt *T) {
5192 return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass;
5193 }
5194};
5195
5196/// This represents '#pragma omp teams distribute parallel for' composite
5197/// directive.
5198///
5199/// \code
5200/// #pragma omp teams distribute parallel for private(x)
5201/// \endcode
5202/// In this example directive '#pragma omp teams distribute parallel for'
5203/// has clause 'private' with the variables 'x'
5204///
5205class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
5206 friend class ASTStmtReader;
5208 /// true if the construct has inner cancel directive.
5209 bool HasCancel = false;
5210
5211 /// Build directive with the given start and end location.
5212 ///
5213 /// \param StartLoc Starting location of the directive kind.
5214 /// \param EndLoc Ending location of the directive.
5215 /// \param CollapsedNum Number of collapsed nested loops.
5216 ///
5217 OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc,
5218 SourceLocation EndLoc,
5219 unsigned CollapsedNum)
5220 : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass,
5221 llvm::omp::OMPD_teams_distribute_parallel_for,
5222 StartLoc, EndLoc, CollapsedNum) {}
5223
5224 /// Build an empty directive.
5225 ///
5226 /// \param CollapsedNum Number of collapsed nested loops.
5227 ///
5228 explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum)
5229 : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass,
5230 llvm::omp::OMPD_teams_distribute_parallel_for,
5231 SourceLocation(), SourceLocation(), CollapsedNum) {}
5232
5233 /// Sets special task reduction descriptor.
5234 void setTaskReductionRefExpr(Expr *E) {
5235 Data->getChildren()[numLoopChildren(
5236 getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)] = E;
5237 }
5238
5239 /// Set cancel state.
5240 void setHasCancel(bool Has) { HasCancel = Has; }
5241
5242public:
5243 /// Creates directive with a list of \a Clauses.
5244 ///
5245 /// \param C AST context.
5246 /// \param StartLoc Starting location of the directive kind.
5247 /// \param EndLoc Ending Location of the directive.
5248 /// \param CollapsedNum Number of collapsed loops.
5249 /// \param Clauses List of clauses.
5250 /// \param AssociatedStmt Statement, associated with the directive.
5251 /// \param Exprs Helper expressions for CodeGen.
5252 /// \param TaskRedRef Task reduction special reference expression to handle
5253 /// taskgroup descriptor.
5254 /// \param HasCancel true if this directive has inner cancel directive.
5255 ///
5256 static OMPTeamsDistributeParallelForDirective *
5257 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5258 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5259 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
5260 bool HasCancel);
5261
5262 /// Creates an empty directive with the place for \a NumClauses clauses.
5263 ///
5264 /// \param C AST context.
5265 /// \param CollapsedNum Number of collapsed nested loops.
5266 /// \param NumClauses Number of clauses.
5267 ///
5268 static OMPTeamsDistributeParallelForDirective *
5269 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5270 EmptyShell);
5271
5272 /// Returns special task reduction reference expression.
5274 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
5275 getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)]);
5276 }
5277 const Expr *getTaskReductionRefExpr() const {
5278 return const_cast<OMPTeamsDistributeParallelForDirective *>(this)
5280 }
5281
5282 /// Return true if current directive has inner cancel directive.
5283 bool hasCancel() const { return HasCancel; }
5284
5285 static bool classof(const Stmt *T) {
5286 return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass;
5287 }
5288};
5289
5290/// This represents '#pragma omp target teams' directive.
5291///
5292/// \code
5293/// #pragma omp target teams if(a>0)
5294/// \endcode
5295/// In this example directive '#pragma omp target teams' has clause 'if' with
5296/// condition 'a>0'.
5297///
5298class OMPTargetTeamsDirective final : public OMPExecutableDirective {
5299 friend class ASTStmtReader;
5301 /// Build directive with the given start and end location.
5302 ///
5303 /// \param StartLoc Starting location of the directive kind.
5304 /// \param EndLoc Ending location of the directive.
5305 ///
5306 OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5307 : OMPExecutableDirective(OMPTargetTeamsDirectiveClass,
5308 llvm::omp::OMPD_target_teams, StartLoc, EndLoc) {
5309 }
5310
5311 /// Build an empty directive.
5312 ///
5313 explicit OMPTargetTeamsDirective()
5314 : OMPExecutableDirective(OMPTargetTeamsDirectiveClass,
5315 llvm::omp::OMPD_target_teams, SourceLocation(),
5316 SourceLocation()) {}
5317
5318public:
5319 /// Creates directive with a list of \a Clauses.
5320 ///
5321 /// \param C AST context.
5322 /// \param StartLoc Starting location of the directive kind.
5323 /// \param EndLoc Ending Location of the directive.
5324 /// \param Clauses List of clauses.
5325 /// \param AssociatedStmt Statement, associated with the directive.
5326 ///
5327 static OMPTargetTeamsDirective *Create(const ASTContext &C,
5328 SourceLocation StartLoc,
5329 SourceLocation EndLoc,
5330 ArrayRef<OMPClause *> Clauses,
5331 Stmt *AssociatedStmt);
5332
5333 /// Creates an empty directive with the place for \a NumClauses clauses.
5334 ///
5335 /// \param C AST context.
5336 /// \param NumClauses Number of clauses.
5337 ///
5338 static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C,
5339 unsigned NumClauses, EmptyShell);
5340
5341 static bool classof(const Stmt *T) {
5342 return T->getStmtClass() == OMPTargetTeamsDirectiveClass;
5343 }
5344};
5345
5346/// This represents '#pragma omp target teams distribute' combined directive.
5347///
5348/// \code
5349/// #pragma omp target teams distribute private(x)
5350/// \endcode
5351/// In this example directive '#pragma omp target teams distribute' has clause
5352/// 'private' with the variables 'x'
5353///
5354class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective {
5355 friend class ASTStmtReader;
5357
5358 /// Build directive with the given start and end location.
5359 ///
5360 /// \param StartLoc Starting location of the directive kind.
5361 /// \param EndLoc Ending location of the directive.
5362 /// \param CollapsedNum Number of collapsed nested loops.
5363 ///
5364 OMPTargetTeamsDistributeDirective(SourceLocation StartLoc,
5365 SourceLocation EndLoc,
5366 unsigned CollapsedNum)
5367 : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass,
5368 llvm::omp::OMPD_target_teams_distribute, StartLoc,
5369 EndLoc, CollapsedNum) {}
5370
5371 /// Build an empty directive.
5372 ///
5373 /// \param CollapsedNum Number of collapsed nested loops.
5374 ///
5375 explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum)
5376 : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass,
5377 llvm::omp::OMPD_target_teams_distribute,
5378 SourceLocation(), SourceLocation(), CollapsedNum) {}
5379
5380public:
5381 /// Creates directive with a list of \a Clauses.
5382 ///
5383 /// \param C AST context.
5384 /// \param StartLoc Starting location of the directive kind.
5385 /// \param EndLoc Ending Location of the directive.
5386 /// \param CollapsedNum Number of collapsed loops.
5387 /// \param Clauses List of clauses.
5388 /// \param AssociatedStmt Statement, associated with the directive.
5389 /// \param Exprs Helper expressions for CodeGen.
5390 ///
5391 static OMPTargetTeamsDistributeDirective *
5392 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5393 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5394 Stmt *AssociatedStmt, const HelperExprs &Exprs);
5395
5396 /// Creates an empty directive with the place for \a NumClauses clauses.
5397 ///
5398 /// \param C AST context.
5399 /// \param CollapsedNum Number of collapsed nested loops.
5400 /// \param NumClauses Number of clauses.
5401 ///
5402 static OMPTargetTeamsDistributeDirective *
5403 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5404 EmptyShell);
5405
5406 static bool classof(const Stmt *T) {
5407 return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass;
5408 }
5409};
5410
5411/// This represents '#pragma omp target teams distribute parallel for' combined
5412/// directive.
5413///
5414/// \code
5415/// #pragma omp target teams distribute parallel for private(x)
5416/// \endcode
5417/// In this example directive '#pragma omp target teams distribute parallel
5418/// for' has clause 'private' with the variables 'x'
5419///
5420class OMPTargetTeamsDistributeParallelForDirective final
5421 : public OMPLoopDirective {
5422 friend class ASTStmtReader;
5424 /// true if the construct has inner cancel directive.
5425 bool HasCancel = false;
5426
5427 /// Build directive with the given start and end location.
5428 ///
5429 /// \param StartLoc Starting location of the directive kind.
5430 /// \param EndLoc Ending location of the directive.
5431 /// \param CollapsedNum Number of collapsed nested loops.
5432 ///
5433 OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc,
5434 SourceLocation EndLoc,
5435 unsigned CollapsedNum)
5436 : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass,
5437 llvm::omp::OMPD_target_teams_distribute_parallel_for,
5438 StartLoc, EndLoc, CollapsedNum) {}
5439
5440 /// Build an empty directive.
5441 ///
5442 /// \param CollapsedNum Number of collapsed nested loops.
5443 ///
5444 explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum)
5445 : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass,
5446 llvm::omp::OMPD_target_teams_distribute_parallel_for,
5447 SourceLocation(), SourceLocation(), CollapsedNum) {}
5448
5449 /// Sets special task reduction descriptor.
5450 void setTaskReductionRefExpr(Expr *E) {
5451 Data->getChildren()[numLoopChildren(
5452 getLoopsNumber(),
5453 llvm::omp::OMPD_target_teams_distribute_parallel_for)] = E;
5454 }
5455
5456 /// Set cancel state.
5457 void setHasCancel(bool Has) { HasCancel = Has; }
5458
5459public:
5460 /// Creates directive with a list of \a Clauses.
5461 ///
5462 /// \param C AST context.
5463 /// \param StartLoc Starting location of the directive kind.
5464 /// \param EndLoc Ending Location of the directive.
5465 /// \param CollapsedNum Number of collapsed loops.
5466 /// \param Clauses List of clauses.
5467 /// \param AssociatedStmt Statement, associated with the directive.
5468 /// \param Exprs Helper expressions for CodeGen.
5469 /// \param TaskRedRef Task reduction special reference expression to handle
5470 /// taskgroup descriptor.
5471 /// \param HasCancel true if this directive has inner cancel directive.
5472 ///
5473 static OMPTargetTeamsDistributeParallelForDirective *
5474 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5475 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5476 Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
5477 bool HasCancel);
5478
5479 /// Creates an empty directive with the place for \a NumClauses clauses.
5480 ///
5481 /// \param C AST context.
5482 /// \param CollapsedNum Number of collapsed nested loops.
5483 /// \param NumClauses Number of clauses.
5484 ///
5485 static OMPTargetTeamsDistributeParallelForDirective *
5486 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5487 EmptyShell);
5488
5489 /// Returns special task reduction reference expression.
5491 return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
5492 getLoopsNumber(),
5493 llvm::omp::OMPD_target_teams_distribute_parallel_for)]);
5494 }
5495 const Expr *getTaskReductionRefExpr() const {
5496 return const_cast<OMPTargetTeamsDistributeParallelForDirective *>(this)
5498 }
5499
5500 /// Return true if current directive has inner cancel directive.
5501 bool hasCancel() const { return HasCancel; }
5502
5503 static bool classof(const Stmt *T) {
5504 return T->getStmtClass() ==
5505 OMPTargetTeamsDistributeParallelForDirectiveClass;
5506 }
5507};
5508
5509/// This represents '#pragma omp target teams distribute parallel for simd'
5510/// combined directive.
5511///
5512/// \code
5513/// #pragma omp target teams distribute parallel for simd private(x)
5514/// \endcode
5515/// In this example directive '#pragma omp target teams distribute parallel
5516/// for simd' has clause 'private' with the variables 'x'
5517///
5518class OMPTargetTeamsDistributeParallelForSimdDirective final
5519 : public OMPLoopDirective {
5520 friend class ASTStmtReader;
5522
5523 /// Build directive with the given start and end location.
5524 ///
5525 /// \param StartLoc Starting location of the directive kind.
5526 /// \param EndLoc Ending location of the directive.
5527 /// \param CollapsedNum Number of collapsed nested loops.
5528 ///
5529 OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
5530 SourceLocation EndLoc,
5531 unsigned CollapsedNum)
5533 OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
5534 llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, StartLoc,
5535 EndLoc, CollapsedNum) {}
5536
5537 /// Build an empty directive.
5538 ///
5539 /// \param CollapsedNum Number of collapsed nested loops.
5540 ///
5542 unsigned CollapsedNum)
5544 OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
5545 llvm::omp::OMPD_target_teams_distribute_parallel_for_simd,
5546 SourceLocation(), SourceLocation(), CollapsedNum) {}
5547
5548public:
5549 /// Creates directive with a list of \a Clauses.
5550 ///
5551 /// \param C AST context.
5552 /// \param StartLoc Starting location of the directive kind.
5553 /// \param EndLoc Ending Location of the directive.
5554 /// \param CollapsedNum Number of collapsed loops.
5555 /// \param Clauses List of clauses.
5556 /// \param AssociatedStmt Statement, associated with the directive.
5557 /// \param Exprs Helper expressions for CodeGen.
5558 ///
5559 static OMPTargetTeamsDistributeParallelForSimdDirective *
5560 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5561 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5562 Stmt *AssociatedStmt, const HelperExprs &Exprs);
5563
5564 /// Creates an empty directive with the place for \a NumClauses clauses.
5565 ///
5566 /// \param C AST context.
5567 /// \param CollapsedNum Number of collapsed nested loops.
5568 /// \param NumClauses Number of clauses.
5569 ///
5570 static OMPTargetTeamsDistributeParallelForSimdDirective *
5571 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5572 EmptyShell);
5573
5574 static bool classof(const Stmt *T) {
5575 return T->getStmtClass() ==
5576 OMPTargetTeamsDistributeParallelForSimdDirectiveClass;
5577 }
5578};
5579
5580/// This represents '#pragma omp target teams distribute simd' combined
5581/// directive.
5582///
5583/// \code
5584/// #pragma omp target teams distribute simd private(x)
5585/// \endcode
5586/// In this example directive '#pragma omp target teams distribute simd'
5587/// has clause 'private' with the variables 'x'
5588///
5589class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective {
5590 friend class ASTStmtReader;
5592
5593 /// Build directive with the given start and end location.
5594 ///
5595 /// \param StartLoc Starting location of the directive kind.
5596 /// \param EndLoc Ending location of the directive.
5597 /// \param CollapsedNum Number of collapsed nested loops.
5598 ///
5599 OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc,
5600 SourceLocation EndLoc,
5601 unsigned CollapsedNum)
5602 : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass,
5603 llvm::omp::OMPD_target_teams_distribute_simd, StartLoc,
5604 EndLoc, CollapsedNum) {}
5605
5606 /// Build an empty directive.
5607 ///
5608 /// \param CollapsedNum Number of collapsed nested loops.
5609 ///
5610 explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum)
5611 : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass,
5612 llvm::omp::OMPD_target_teams_distribute_simd,
5613 SourceLocation(), SourceLocation(), CollapsedNum) {}
5614
5615public:
5616 /// Creates directive with a list of \a Clauses.
5617 ///
5618 /// \param C AST context.
5619 /// \param StartLoc Starting location of the directive kind.
5620 /// \param EndLoc Ending Location of the directive.
5621 /// \param CollapsedNum Number of collapsed loops.
5622 /// \param Clauses List of clauses.
5623 /// \param AssociatedStmt Statement, associated with the directive.
5624 /// \param Exprs Helper expressions for CodeGen.
5625 ///
5626 static OMPTargetTeamsDistributeSimdDirective *
5627 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5628 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5629 Stmt *AssociatedStmt, const HelperExprs &Exprs);
5630
5631 /// Creates an empty directive with the place for \a NumClauses clauses.
5632 ///
5633 /// \param C AST context.
5634 /// \param CollapsedNum Number of collapsed nested loops.
5635 /// \param NumClauses Number of clauses.
5636 ///
5637 static OMPTargetTeamsDistributeSimdDirective *
5638 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5639 EmptyShell);
5640
5641 static bool classof(const Stmt *T) {
5642 return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
5643 }
5644};
5645
5646/// This represents the '#pragma omp tile' loop transformation directive.
5647class OMPTileDirective final
5649 friend class ASTStmtReader;
5651
5652 /// Default list of offsets.
5653 enum {
5654 PreInitsOffset = 0,
5655 TransformedStmtOffset,
5656 };
5657
5658 explicit OMPTileDirective(SourceLocation StartLoc, SourceLocation EndLoc,
5659 unsigned NumLoops)
5661 OMPTileDirectiveClass, llvm::omp::OMPD_tile, StartLoc, EndLoc,
5662 NumLoops) {}
5663
5664 void setPreInits(Stmt *PreInits) {
5665 Data->getChildren()[PreInitsOffset] = PreInits;
5666 }
5667
5668 void setTransformedStmt(Stmt *S) {
5669 Data->getChildren()[TransformedStmtOffset] = S;
5670 }
5671
5672public:
5673 /// Create a new AST node representation for '#pragma omp tile'.
5674 ///
5675 /// \param C Context of the AST.
5676 /// \param StartLoc Location of the introducer (e.g. the 'omp' token).
5677 /// \param EndLoc Location of the directive's end (e.g. the tok::eod).
5678 /// \param Clauses The directive's clauses.
5679 /// \param NumLoops Number of associated loops (number of items in the
5680 /// 'sizes' clause).
5681 /// \param AssociatedStmt The outermost associated loop.
5682 /// \param TransformedStmt The loop nest after tiling, or nullptr in
5683 /// dependent contexts.
5684 /// \param PreInits Helper preinits statements for the loop nest.
5685 static OMPTileDirective *Create(const ASTContext &C, SourceLocation StartLoc,
5686 SourceLocation EndLoc,
5687 ArrayRef<OMPClause *> Clauses,
5688 unsigned NumLoops, Stmt *AssociatedStmt,
5689 Stmt *TransformedStmt, Stmt *PreInits);
5690
5691 /// Build an empty '#pragma omp tile' AST node for deserialization.
5692 ///
5693 /// \param C Context of the AST.
5694 /// \param NumClauses Number of clauses to allocate.
5695 /// \param NumLoops Number of associated loops to allocate.
5696 static OMPTileDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
5697 unsigned NumLoops);
5698
5699 /// Gets/sets the associated loops after tiling.
5700 ///
5701 /// This is in de-sugared format stored as a CompoundStmt.
5702 ///
5703 /// \code
5704 /// for (...)
5705 /// ...
5706 /// \endcode
5707 ///
5708 /// Note that if the generated loops a become associated loops of another
5709 /// directive, they may need to be hoisted before them.
5710 Stmt *getTransformedStmt() const {
5711 return Data->getChildren()[TransformedStmtOffset];
5712 }
5713
5714 /// Return preinits statement.
5715 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
5716
5717 static bool classof(const Stmt *T) {
5718 return T->getStmtClass() == OMPTileDirectiveClass;
5719 }
5720};
5721
5722/// This represents the '#pragma omp stripe' loop transformation directive.
5723class OMPStripeDirective final
5725 friend class ASTStmtReader;
5727
5728 /// Default list of offsets.
5729 enum {
5730 PreInitsOffset = 0,
5731 TransformedStmtOffset,
5732 };
5733
5734 explicit OMPStripeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
5735 unsigned NumLoops)
5737 OMPStripeDirectiveClass, llvm::omp::OMPD_stripe, StartLoc, EndLoc,
5738 NumLoops) {}
5739
5740 void setPreInits(Stmt *PreInits) {
5741 Data->getChildren()[PreInitsOffset] = PreInits;
5742 }
5743
5744 void setTransformedStmt(Stmt *S) {
5745 Data->getChildren()[TransformedStmtOffset] = S;
5746 }
5747
5748public:
5749 /// Create a new AST node representation for '#pragma omp stripe'.
5750 ///
5751 /// \param C Context of the AST.
5752 /// \param StartLoc Location of the introducer (e.g. the 'omp' token).
5753 /// \param EndLoc Location of the directive's end (e.g. the tok::eod).
5754 /// \param Clauses The directive's clauses.
5755 /// \param NumLoops Number of associated loops (number of items in the
5756 /// 'sizes' clause).
5757 /// \param AssociatedStmt The outermost associated loop.
5758 /// \param TransformedStmt The loop nest after striping, or nullptr in
5759 /// dependent contexts.
5760 /// \param PreInits Helper preinits statements for the loop nest.
5761 static OMPStripeDirective *
5762 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5763 ArrayRef<OMPClause *> Clauses, unsigned NumLoops, Stmt *AssociatedStmt,
5764 Stmt *TransformedStmt, Stmt *PreInits);
5765
5766 /// Build an empty '#pragma omp stripe' AST node for deserialization.
5767 ///
5768 /// \param C Context of the AST.
5769 /// \param NumClauses Number of clauses to allocate.
5770 /// \param NumLoops Number of associated loops to allocate.
5771 static OMPStripeDirective *
5772 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned NumLoops);
5773 /// Gets/sets the associated loops after striping.
5774 ///
5775 /// This is in de-sugared format stored as a CompoundStmt.
5776 ///
5777 /// \code
5778 /// for (...)
5779 /// ...
5780 /// \endcode
5781 ///
5782 /// Note that if the generated loops a become associated loops of another
5783 /// directive, they may need to be hoisted before them.
5784 Stmt *getTransformedStmt() const {
5785 return Data->getChildren()[TransformedStmtOffset];
5786 }
5787
5788 /// Return preinits statement.
5789 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
5790
5791 static bool classof(const Stmt *T) {
5792 return T->getStmtClass() == OMPStripeDirectiveClass;
5793 }
5794};
5795
5796/// This represents the '#pragma omp unroll' loop transformation directive.
5797///
5798/// \code
5799/// #pragma omp unroll
5800/// for (int i = 0; i < 64; ++i)
5801/// \endcode
5802class OMPUnrollDirective final
5804 friend class ASTStmtReader;
5806
5807 /// Default list of offsets.
5808 enum {
5809 PreInitsOffset = 0,
5810 TransformedStmtOffset,
5811 };
5812
5813 explicit OMPUnrollDirective(SourceLocation StartLoc, SourceLocation EndLoc)
5814 : OMPCanonicalLoopNestTransformationDirective(OMPUnrollDirectiveClass,
5815 llvm::omp::OMPD_unroll,
5816 StartLoc, EndLoc, 1) {}
5817
5818 /// Set the pre-init statements.
5819 void setPreInits(Stmt *PreInits) {
5820 Data->getChildren()[PreInitsOffset] = PreInits;
5821 }
5822
5823 /// Set the de-sugared statement.
5824 void setTransformedStmt(Stmt *S) {
5825 Data->getChildren()[TransformedStmtOffset] = S;
5826 }
5827
5828public:
5829 /// Create a new AST node representation for '#pragma omp unroll'.
5830 ///
5831 /// \param C Context of the AST.
5832 /// \param StartLoc Location of the introducer (e.g. the 'omp' token).
5833 /// \param EndLoc Location of the directive's end (e.g. the tok::eod).
5834 /// \param Clauses The directive's clauses.
5835 /// \param AssociatedStmt The outermost associated loop.
5836 /// \param TransformedStmt The loop nest after tiling, or nullptr in
5837 /// dependent contexts.
5838 /// \param PreInits Helper preinits statements for the loop nest.
5839 static OMPUnrollDirective *
5840 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5841 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
5842 unsigned NumGeneratedTopLevelLoops, Stmt *TransformedStmt,
5843 Stmt *PreInits);
5844
5845 /// Build an empty '#pragma omp unroll' AST node for deserialization.
5846 ///
5847 /// \param C Context of the AST.
5848 /// \param NumClauses Number of clauses to allocate.
5849 static OMPUnrollDirective *CreateEmpty(const ASTContext &C,
5850 unsigned NumClauses);
5851
5852 /// Get the de-sugared associated loops after unrolling.
5853 ///
5854 /// This is only used if the unrolled loop becomes an associated loop of
5855 /// another directive, otherwise the loop is emitted directly using loop
5856 /// transformation metadata. When the unrolled loop cannot be used by another
5857 /// directive (e.g. because of the full clause), the transformed stmt can also
5858 /// be nullptr.
5859 Stmt *getTransformedStmt() const {
5860 return Data->getChildren()[TransformedStmtOffset];
5861 }
5862
5863 /// Return the pre-init statements.
5864 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
5865
5866 static bool classof(const Stmt *T) {
5867 return T->getStmtClass() == OMPUnrollDirectiveClass;
5868 }
5869};
5870
5871/// Represents the '#pragma omp reverse' loop transformation directive.
5872///
5873/// \code
5874/// #pragma omp reverse
5875/// for (int i = 0; i < n; ++i)
5876/// ...
5877/// \endcode
5878class OMPReverseDirective final
5880 friend class ASTStmtReader;
5882
5883 /// Offsets of child members.
5884 enum {
5885 PreInitsOffset = 0,
5886 TransformedStmtOffset,
5887 };
5888
5889 explicit OMPReverseDirective(SourceLocation StartLoc, SourceLocation EndLoc,
5890 unsigned NumLoops)
5892 OMPReverseDirectiveClass, llvm::omp::OMPD_reverse, StartLoc, EndLoc,
5893 NumLoops) {}
5894
5895 void setPreInits(Stmt *PreInits) {
5896 Data->getChildren()[PreInitsOffset] = PreInits;
5897 }
5898
5899 void setTransformedStmt(Stmt *S) {
5900 Data->getChildren()[TransformedStmtOffset] = S;
5901 }
5902
5903public:
5904 /// Create a new AST node representation for '#pragma omp reverse'.
5905 ///
5906 /// \param C Context of the AST.
5907 /// \param StartLoc Location of the introducer (e.g. the 'omp' token).
5908 /// \param EndLoc Location of the directive's end (e.g. the tok::eod).
5909 /// \param NumLoops Number of affected loops
5910 /// \param AssociatedStmt The outermost associated loop.
5911 /// \param TransformedStmt The loop nest after tiling, or nullptr in
5912 /// dependent contexts.
5913 /// \param PreInits Helper preinits statements for the loop nest.
5914 static OMPReverseDirective *Create(const ASTContext &C,
5915 SourceLocation StartLoc,
5916 SourceLocation EndLoc,
5917 Stmt *AssociatedStmt, unsigned NumLoops,
5918 Stmt *TransformedStmt, Stmt *PreInits);
5919
5920 /// Build an empty '#pragma omp reverse' AST node for deserialization.
5921 ///
5922 /// \param C Context of the AST.
5923 /// \param NumLoops Number of associated loops to allocate
5924 static OMPReverseDirective *CreateEmpty(const ASTContext &C,
5925 unsigned NumLoops);
5926
5927 /// Gets/sets the associated loops after the transformation, i.e. after
5928 /// de-sugaring.
5929 Stmt *getTransformedStmt() const {
5930 return Data->getChildren()[TransformedStmtOffset];
5931 }
5932
5933 /// Return preinits statement.
5934 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
5935
5936 static bool classof(const Stmt *T) {
5937 return T->getStmtClass() == OMPReverseDirectiveClass;
5938 }
5939};
5940
5941/// Represents the '#pragma omp interchange' loop transformation directive.
5942///
5943/// \code{c}
5944/// #pragma omp interchange
5945/// for (int i = 0; i < m; ++i)
5946/// for (int j = 0; j < n; ++j)
5947/// ..
5948/// \endcode
5949class OMPInterchangeDirective final
5951 friend class ASTStmtReader;
5953
5954 /// Offsets of child members.
5955 enum {
5956 PreInitsOffset = 0,
5957 TransformedStmtOffset,
5958 };
5959
5960 explicit OMPInterchangeDirective(SourceLocation StartLoc,
5961 SourceLocation EndLoc, unsigned NumLoops)
5963 OMPInterchangeDirectiveClass, llvm::omp::OMPD_interchange, StartLoc,
5964 EndLoc, NumLoops) {}
5965
5966 void setPreInits(Stmt *PreInits) {
5967 Data->getChildren()[PreInitsOffset] = PreInits;
5968 }
5969
5970 void setTransformedStmt(Stmt *S) {
5971 Data->getChildren()[TransformedStmtOffset] = S;
5972 }
5973
5974public:
5975 /// Create a new AST node representation for '#pragma omp interchange'.
5976 ///
5977 /// \param C Context of the AST.
5978 /// \param StartLoc Location of the introducer (e.g. the 'omp' token).
5979 /// \param EndLoc Location of the directive's end (e.g. the tok::eod).
5980 /// \param Clauses The directive's clauses.
5981 /// \param NumLoops Number of affected loops
5982 /// (number of items in the 'permutation' clause if present).
5983 /// \param AssociatedStmt The outermost associated loop.
5984 /// \param TransformedStmt The loop nest after tiling, or nullptr in
5985 /// dependent contexts.
5986 /// \param PreInits Helper preinits statements for the loop nest.
5987 static OMPInterchangeDirective *
5988 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5989 ArrayRef<OMPClause *> Clauses, unsigned NumLoops, Stmt *AssociatedStmt,
5990 Stmt *TransformedStmt, Stmt *PreInits);
5991
5992 /// Build an empty '#pragma omp interchange' AST node for deserialization.
5993 ///
5994 /// \param C Context of the AST.
5995 /// \param NumClauses Number of clauses to allocate.
5996 /// \param NumLoops Number of associated loops to allocate.
5997 static OMPInterchangeDirective *
5998 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned NumLoops);
5999
6000 /// Gets the associated loops after the transformation. This is the de-sugared
6001 /// replacement or nullptr in dependent contexts.
6002 Stmt *getTransformedStmt() const {
6003 return Data->getChildren()[TransformedStmtOffset];
6004 }
6005
6006 /// Return preinits statement.
6007 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
6008
6009 static bool classof(const Stmt *T) {
6010 return T->getStmtClass() == OMPInterchangeDirectiveClass;
6011 }
6012};
6013
6014/// The base class for all transformation directives of canonical loop
6015/// sequences (currently only 'fuse')
6017 : public OMPExecutableDirective,
6019 friend class ASTStmtReader;
6020
6021protected:
6023 StmtClass SC, OpenMPDirectiveKind Kind, SourceLocation StartLoc,
6024 SourceLocation EndLoc)
6025 : OMPExecutableDirective(SC, Kind, StartLoc, EndLoc),
6027
6028public:
6029 /// Get the de-sugared statements after the loop transformation.
6030 ///
6031 /// Might be nullptr if either the directive generates no loops and is handled
6032 /// directly in CodeGen, or resolving a template-dependence context is
6033 /// required.
6034 Stmt *getTransformedStmt() const;
6035
6036 /// Return preinits statement.
6037 Stmt *getPreInits() const;
6038
6039 static bool classof(const Stmt *T) {
6040 Stmt::StmtClass C = T->getStmtClass();
6041 return C == OMPFuseDirectiveClass;
6042 }
6043};
6044
6045/// Represents the '#pragma omp fuse' loop transformation directive
6046///
6047/// \code{c}
6048/// #pragma omp fuse
6049/// {
6050/// for(int i = 0; i < m1; ++i) {...}
6051/// for(int j = 0; j < m2; ++j) {...}
6052/// ...
6053/// }
6054/// \endcode
6055class OMPFuseDirective final
6057 friend class ASTStmtReader;
6059
6060 // Offsets of child members.
6061 enum {
6062 PreInitsOffset = 0,
6063 TransformedStmtOffset,
6064 };
6065
6066 explicit OMPFuseDirective(SourceLocation StartLoc, SourceLocation EndLoc)
6068 OMPFuseDirectiveClass, llvm::omp::OMPD_fuse, StartLoc, EndLoc) {}
6069
6070 void setPreInits(Stmt *PreInits) {
6071 Data->getChildren()[PreInitsOffset] = PreInits;
6072 }
6073
6074 void setTransformedStmt(Stmt *S) {
6075 Data->getChildren()[TransformedStmtOffset] = S;
6076 }
6077
6078public:
6079 /// Create a new AST node representation for #pragma omp fuse'
6080 ///
6081 /// \param C Context of the AST
6082 /// \param StartLoc Location of the introducer (e.g the 'omp' token)
6083 /// \param EndLoc Location of the directive's end (e.g the tok::eod)
6084 /// \param Clauses The directive's clauses
6085 /// \param NumLoops Total number of loops in the canonical loop sequence.
6086 /// \param NumGeneratedTopLevelLoops Number of top-level generated loops.
6087 // Typically 1 but looprange clause can
6088 // change this.
6089 /// \param AssociatedStmt The outermost associated loop
6090 /// \param TransformedStmt The loop nest after fusion, or nullptr in
6091 /// dependent
6092 /// \param PreInits Helper preinits statements for the loop nest
6093 static OMPFuseDirective *
6094 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
6095 ArrayRef<OMPClause *> Clauses, unsigned NumGeneratedTopLevelLoops,
6096 Stmt *AssociatedStmt, Stmt *TransformedStmt, Stmt *PreInits);
6097
6098 /// Build an empty '#pragma omp fuse' AST node for deserialization
6099 ///
6100 /// \param C Context of the AST
6101 /// \param NumClauses Number of clauses to allocate
6102 /// \param NumLoops Number of top level loops to allocate
6103 static OMPFuseDirective *CreateEmpty(const ASTContext &C,
6104 unsigned NumClauses);
6105
6106 /// Gets the associated loops after the transformation. This is the de-sugared
6107 /// replacement or nulltpr in dependent contexts.
6108 Stmt *getTransformedStmt() const {
6109 return Data->getChildren()[TransformedStmtOffset];
6110 }
6111
6112 /// Return preinits statement.
6113 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
6114
6115 static bool classof(const Stmt *T) {
6116 return T->getStmtClass() == OMPFuseDirectiveClass;
6117 }
6118};
6119
6120/// Represents the '#pragma omp split' loop transformation directive.
6121///
6122/// \code{.c}
6123/// #pragma omp split counts(3, omp_fill, 2)
6124/// for (int i = 0; i < n; ++i)
6125/// ...
6126/// \endcode
6127///
6128/// This directive transforms a single loop into multiple loops based on
6129/// index ranges. The transformation splits the iteration space of the loop
6130/// into multiple contiguous ranges. The \c counts clause is required and
6131/// exactly one list item must be \c omp_fill.
6132class OMPSplitDirective final
6134 friend class ASTStmtReader;
6136
6137 /// Offsets of child members.
6138 enum {
6139 PreInitsOffset = 0,
6140 TransformedStmtOffset,
6141 };
6142
6143 explicit OMPSplitDirective(SourceLocation StartLoc, SourceLocation EndLoc,
6144 unsigned NumLoops)
6146 OMPSplitDirectiveClass, llvm::omp::OMPD_split, StartLoc, EndLoc,
6147 NumLoops) {}
6148
6149 void setPreInits(Stmt *PreInits) {
6150 Data->getChildren()[PreInitsOffset] = PreInits;
6151 }
6152
6153 void setTransformedStmt(Stmt *S) {
6154 Data->getChildren()[TransformedStmtOffset] = S;
6155 }
6156
6157public:
6158 /// Create a new AST node representation for '#pragma omp split'.
6159 ///
6160 /// \param C Context of the AST.
6161 /// \param StartLoc Location of the introducer (e.g. the 'omp' token).
6162 /// \param EndLoc Location of the directive's end (e.g. the tok::eod).
6163 /// \param Clauses The directive's clauses (e.g. the required \c counts
6164 /// clause).
6165 /// \param NumLoops Number of affected loops (should be 1 for split).
6166 /// \param AssociatedStmt The outermost associated loop.
6167 /// \param TransformedStmt The loop nest after splitting, or nullptr in
6168 /// dependent contexts.
6169 /// \param PreInits Helper preinits statements for the loop nest.
6170 static OMPSplitDirective *Create(const ASTContext &C, SourceLocation StartLoc,
6171 SourceLocation EndLoc,
6172 ArrayRef<OMPClause *> Clauses,
6173 unsigned NumLoops, Stmt *AssociatedStmt,
6174 Stmt *TransformedStmt, Stmt *PreInits);
6175
6176 /// Build an empty '#pragma omp split' AST node for deserialization.
6177 ///
6178 /// \param C Context of the AST.
6179 /// \param NumClauses Number of clauses to allocate.
6180 /// \param NumLoops Number of associated loops to allocate.
6181 static OMPSplitDirective *CreateEmpty(const ASTContext &C,
6182 unsigned NumClauses, unsigned NumLoops);
6183
6184 /// Gets/sets the associated loops after the transformation, i.e. after
6185 /// de-sugaring.
6186 Stmt *getTransformedStmt() const {
6187 return Data->getChildren()[TransformedStmtOffset];
6188 }
6189
6190 /// Return preinits statement.
6191 Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; }
6192
6193 static bool classof(const Stmt *T) {
6194 return T->getStmtClass() == OMPSplitDirectiveClass;
6195 }
6196};
6197
6198/// This represents '#pragma omp scan' directive.
6199///
6200/// \code
6201/// #pragma omp scan inclusive(a)
6202/// \endcode
6203/// In this example directive '#pragma omp scan' has clause 'inclusive' with
6204/// list item 'a'.
6205class OMPScanDirective final : public OMPExecutableDirective {
6206 friend class ASTStmtReader;
6208 /// Build directive with the given start and end location.
6209 ///
6210 /// \param StartLoc Starting location of the directive kind.
6211 /// \param EndLoc Ending location of the directive.
6212 ///
6213 OMPScanDirective(SourceLocation StartLoc, SourceLocation EndLoc)
6214 : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan,
6215 StartLoc, EndLoc) {}
6216
6217 /// Build an empty directive.
6218 ///
6219 explicit OMPScanDirective()
6220 : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan,
6221 SourceLocation(), SourceLocation()) {}
6222
6223public:
6224 /// Creates directive with a list of \a Clauses.
6225 ///
6226 /// \param C AST context.
6227 /// \param StartLoc Starting location of the directive kind.
6228 /// \param EndLoc Ending Location of the directive.
6229 /// \param Clauses List of clauses (only single OMPFlushClause clause is
6230 /// allowed).
6231 ///
6232 static OMPScanDirective *Create(const ASTContext &C, SourceLocation StartLoc,
6233 SourceLocation EndLoc,
6234 ArrayRef<OMPClause *> Clauses);
6235
6236 /// Creates an empty directive with the place for \a NumClauses
6237 /// clauses.
6238 ///
6239 /// \param C AST context.
6240 /// \param NumClauses Number of clauses.
6241 ///
6242 static OMPScanDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
6243 EmptyShell);
6244
6245 static bool classof(const Stmt *T) {
6246 return T->getStmtClass() == OMPScanDirectiveClass;
6247 }
6248};
6249
6250/// This represents '#pragma omp interop' directive.
6251///
6252/// \code
6253/// #pragma omp interop init(target:obj) device(x) depend(inout:y) nowait
6254/// \endcode
6255/// In this example directive '#pragma omp interop' has
6256/// clauses 'init', 'device', 'depend' and 'nowait'.
6257///
6258class OMPInteropDirective final : public OMPExecutableDirective {
6259 friend class ASTStmtReader;
6261
6262 /// Build directive with the given start and end location.
6263 ///
6264 /// \param StartLoc Starting location of the directive.
6265 /// \param EndLoc Ending location of the directive.
6266 ///
6267 OMPInteropDirective(SourceLocation StartLoc, SourceLocation EndLoc)
6268 : OMPExecutableDirective(OMPInteropDirectiveClass,
6269 llvm::omp::OMPD_interop, StartLoc, EndLoc) {}
6270
6271 /// Build an empty directive.
6272 ///
6273 explicit OMPInteropDirective()
6274 : OMPExecutableDirective(OMPInteropDirectiveClass,
6275 llvm::omp::OMPD_interop, SourceLocation(),
6276 SourceLocation()) {}
6277
6278public:
6279 /// Creates directive.
6280 ///
6281 /// \param C AST context.
6282 /// \param StartLoc Starting location of the directive.
6283 /// \param EndLoc Ending Location of the directive.
6284 /// \param Clauses The directive's clauses.
6285 ///
6286 static OMPInteropDirective *Create(const ASTContext &C,
6287 SourceLocation StartLoc,
6288 SourceLocation EndLoc,
6289 ArrayRef<OMPClause *> Clauses);
6290
6291 /// Creates an empty directive.
6292 ///
6293 /// \param C AST context.
6294 ///
6295 static OMPInteropDirective *CreateEmpty(const ASTContext &C,
6296 unsigned NumClauses, EmptyShell);
6297
6298 static bool classof(const Stmt *T) {
6299 return T->getStmtClass() == OMPInteropDirectiveClass;
6300 }
6301};
6302
6303/// This represents '#pragma omp dispatch' directive.
6304///
6305/// \code
6306/// #pragma omp dispatch device(dnum)
6307/// \endcode
6308/// This example shows a directive '#pragma omp dispatch' with a
6309/// device clause with variable 'dnum'.
6310///
6311class OMPDispatchDirective final : public OMPExecutableDirective {
6312 friend class ASTStmtReader;
6314
6315 /// The location of the target-call.
6316 SourceLocation TargetCallLoc;
6317
6318 /// Set the location of the target-call.
6319 void setTargetCallLoc(SourceLocation Loc) { TargetCallLoc = Loc; }
6320
6321 /// Build directive with the given start and end location.
6322 ///
6323 /// \param StartLoc Starting location of the directive kind.
6324 /// \param EndLoc Ending location of the directive.
6325 ///
6326 OMPDispatchDirective(SourceLocation StartLoc, SourceLocation EndLoc)
6327 : OMPExecutableDirective(OMPDispatchDirectiveClass,
6328 llvm::omp::OMPD_dispatch, StartLoc, EndLoc) {}
6329
6330 /// Build an empty directive.
6331 ///
6332 explicit OMPDispatchDirective()
6333 : OMPExecutableDirective(OMPDispatchDirectiveClass,
6334 llvm::omp::OMPD_dispatch, SourceLocation(),
6335 SourceLocation()) {}
6336
6337public:
6338 /// Creates directive with a list of \a Clauses.
6339 ///
6340 /// \param C AST context.
6341 /// \param StartLoc Starting location of the directive kind.
6342 /// \param EndLoc Ending Location of the directive.
6343 /// \param Clauses List of clauses.
6344 /// \param AssociatedStmt Statement, associated with the directive.
6345 /// \param TargetCallLoc Location of the target-call.
6346 ///
6347 static OMPDispatchDirective *
6348 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
6349 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
6350 SourceLocation TargetCallLoc);
6351
6352 /// Creates an empty directive with the place for \a NumClauses
6353 /// clauses.
6354 ///
6355 /// \param C AST context.
6356 /// \param NumClauses Number of clauses.
6357 ///
6358 static OMPDispatchDirective *CreateEmpty(const ASTContext &C,
6359 unsigned NumClauses, EmptyShell);
6360
6361 /// Return location of target-call.
6362 SourceLocation getTargetCallLoc() const { return TargetCallLoc; }
6363
6364 static bool classof(const Stmt *T) {
6365 return T->getStmtClass() == OMPDispatchDirectiveClass;
6366 }
6367};
6368
6369/// This represents '#pragma omp masked' directive.
6370/// \code
6371/// #pragma omp masked filter(tid)
6372/// \endcode
6373/// This example shows a directive '#pragma omp masked' with a filter clause
6374/// with variable 'tid'.
6375///
6376class OMPMaskedDirective final : public OMPExecutableDirective {
6377 friend class ASTStmtReader;
6379
6380 /// Build directive with the given start and end location.
6381 ///
6382 /// \param StartLoc Starting location of the directive kind.
6383 /// \param EndLoc Ending location of the directive.
6384 ///
6385 OMPMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
6386 : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked,
6387 StartLoc, EndLoc) {}
6388
6389 /// Build an empty directive.
6390 ///
6391 explicit OMPMaskedDirective()
6392 : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked,
6393 SourceLocation(), SourceLocation()) {}
6394
6395public:
6396 /// Creates directive.
6397 ///
6398 /// \param C AST context.
6399 /// \param StartLoc Starting location of the directive kind.
6400 /// \param EndLoc Ending Location of the directive.
6401 /// \param AssociatedStmt Statement, associated with the directive.
6402 ///
6403 static OMPMaskedDirective *
6404 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
6405 ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
6406
6407 /// Creates an empty directive.
6408 ///
6409 /// \param C AST context.
6410 ///
6411 static OMPMaskedDirective *CreateEmpty(const ASTContext &C,
6412 unsigned NumClauses, EmptyShell);
6413
6414 static bool classof(const Stmt *T) {
6415 return T->getStmtClass() == OMPMaskedDirectiveClass;
6416 }
6417};
6418
6419/// This represents '#pragma omp metadirective' directive.
6420///
6421/// \code
6422/// #pragma omp metadirective when(user={condition(N>10)}: parallel for)
6423/// \endcode
6424/// In this example directive '#pragma omp metadirective' has clauses 'when'
6425/// with a dynamic user condition to check if a variable 'N > 10'
6426///
6427class OMPMetaDirective final : public OMPExecutableDirective {
6428 friend class ASTStmtReader;
6430 Stmt *IfStmt;
6431
6432 OMPMetaDirective(SourceLocation StartLoc, SourceLocation EndLoc)
6433 : OMPExecutableDirective(OMPMetaDirectiveClass,
6434 llvm::omp::OMPD_metadirective, StartLoc,
6435 EndLoc) {}
6436 explicit OMPMetaDirective()
6437 : OMPExecutableDirective(OMPMetaDirectiveClass,
6438 llvm::omp::OMPD_metadirective, SourceLocation(),
6439 SourceLocation()) {}
6440
6441 void setIfStmt(Stmt *S) { IfStmt = S; }
6442
6443public:
6444 static OMPMetaDirective *Create(const ASTContext &C, SourceLocation StartLoc,
6445 SourceLocation EndLoc,
6446 ArrayRef<OMPClause *> Clauses,
6447 Stmt *AssociatedStmt, Stmt *IfStmt);
6448 static OMPMetaDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
6449 EmptyShell);
6450 Stmt *getIfStmt() const { return IfStmt; }
6451
6452 static bool classof(const Stmt *T) {
6453 return T->getStmtClass() == OMPMetaDirectiveClass;
6454 }
6455};
6456
6457/// This represents '#pragma omp loop' directive.
6458///
6459/// \code
6460/// #pragma omp loop private(a,b) binding(parallel) order(concurrent)
6461/// \endcode
6462/// In this example directive '#pragma omp loop' has
6463/// clauses 'private' with the variables 'a' and 'b', 'binding' with
6464/// modifier 'parallel' and 'order(concurrent).
6465///
6466class OMPGenericLoopDirective final : public OMPLoopDirective {
6467 friend class ASTStmtReader;
6469 /// Build directive with the given start and end location.
6470 ///
6471 /// \param StartLoc Starting location of the directive kind.
6472 /// \param EndLoc Ending location of the directive.
6473 /// \param CollapsedNum Number of collapsed nested loops.
6474 ///
6475 OMPGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
6476 unsigned CollapsedNum)
6477 : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop,
6478 StartLoc, EndLoc, CollapsedNum) {}
6479
6480 /// Build an empty directive.
6481 ///
6482 /// \param CollapsedNum Number of collapsed nested loops.
6483 ///
6484 explicit OMPGenericLoopDirective(unsigned CollapsedNum)
6485 : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop,
6486 SourceLocation(), SourceLocation(), CollapsedNum) {}
6487
6488public:
6489 /// Creates directive with a list of \p Clauses.
6490 ///
6491 /// \param C AST context.
6492 /// \param StartLoc Starting location of the directive kind.
6493 /// \param EndLoc Ending Location of the directive.
6494 /// \param CollapsedNum Number of collapsed loops.
6495 /// \param Clauses List of clauses.
6496 /// \param AssociatedStmt Statement, associated with the directive.
6497 /// \param Exprs Helper expressions for CodeGen.
6498 ///
6499 static OMPGenericLoopDirective *
6500 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
6501 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
6502 Stmt *AssociatedStmt, const HelperExprs &Exprs);
6503
6504 /// Creates an empty directive with a place for \a NumClauses clauses.
6505 ///
6506 /// \param C AST context.
6507 /// \param NumClauses Number of clauses.
6508 /// \param CollapsedNum Number of collapsed nested loops.
6509 ///
6510 static OMPGenericLoopDirective *CreateEmpty(const ASTContext &C,
6511 unsigned NumClauses,
6512 unsigned CollapsedNum,
6513 EmptyShell);
6514
6515 static bool classof(const Stmt *T) {
6516 return T->getStmtClass() == OMPGenericLoopDirectiveClass;
6517 }
6518};
6519
6520/// This represents '#pragma omp teams loop' directive.
6521///
6522/// \code
6523/// #pragma omp teams loop private(a,b) order(concurrent)
6524/// \endcode
6525/// In this example directive '#pragma omp teams loop' has
6526/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
6527///
6528class OMPTeamsGenericLoopDirective final : public OMPLoopDirective {
6529 friend class ASTStmtReader;
6531 /// Build directive with the given start and end location.
6532 ///
6533 /// \param StartLoc Starting location of the directive kind.
6534 /// \param EndLoc Ending location of the directive.
6535 /// \param CollapsedNum Number of collapsed nested loops.
6536 ///
6537 OMPTeamsGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
6538 unsigned CollapsedNum)
6539 : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass,
6540 llvm::omp::OMPD_teams_loop, StartLoc, EndLoc,
6541 CollapsedNum) {}
6542
6543 /// Build an empty directive.
6544 ///
6545 /// \param CollapsedNum Number of collapsed nested loops.
6546 ///
6547 explicit OMPTeamsGenericLoopDirective(unsigned CollapsedNum)
6548 : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass,
6549 llvm::omp::OMPD_teams_loop, SourceLocation(),
6550 SourceLocation(), CollapsedNum) {}
6551
6552public:
6553 /// Creates directive with a list of \p Clauses.
6554 ///
6555 /// \param C AST context.
6556 /// \param StartLoc Starting location of the directive kind.
6557 /// \param EndLoc Ending Location of the directive.
6558 /// \param CollapsedNum Number of collapsed loops.
6559 /// \param Clauses List of clauses.
6560 /// \param AssociatedStmt Statement, associated with the directive.
6561 /// \param Exprs Helper expressions for CodeGen.
6562 ///
6563 static OMPTeamsGenericLoopDirective *
6564 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
6565 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
6566 Stmt *AssociatedStmt, const HelperExprs &Exprs);
6567
6568 /// Creates an empty directive with the place
6569 /// for \a NumClauses clauses.
6570 ///
6571 /// \param C AST context.
6572 /// \param CollapsedNum Number of collapsed nested loops.
6573 /// \param NumClauses Number of clauses.
6574 ///
6575 static OMPTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C,
6576 unsigned NumClauses,
6577 unsigned CollapsedNum,
6578 EmptyShell);
6579
6580 static bool classof(const Stmt *T) {
6581 return T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass;
6582 }
6583};
6584
6585/// This represents '#pragma omp target teams loop' directive.
6586///
6587/// \code
6588/// #pragma omp target teams loop private(a,b) order(concurrent)
6589/// \endcode
6590/// In this example directive '#pragma omp target teams loop' has
6591/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
6592///
6593class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective {
6594 friend class ASTStmtReader;
6596 /// true if loop directive's associated loop can be a parallel for.
6597 bool CanBeParallelFor = false;
6598 /// Build directive with the given start and end location.
6599 ///
6600 /// \param StartLoc Starting location of the directive kind.
6601 /// \param EndLoc Ending location of the directive.
6602 /// \param CollapsedNum Number of collapsed nested loops.
6603 ///
6604 OMPTargetTeamsGenericLoopDirective(SourceLocation StartLoc,
6605 SourceLocation EndLoc,
6606 unsigned CollapsedNum)
6607 : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass,
6608 llvm::omp::OMPD_target_teams_loop, StartLoc, EndLoc,
6609 CollapsedNum) {}
6610
6611 /// Build an empty directive.
6612 ///
6613 /// \param CollapsedNum Number of collapsed nested loops.
6614 ///
6615 explicit OMPTargetTeamsGenericLoopDirective(unsigned CollapsedNum)
6616 : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass,
6617 llvm::omp::OMPD_target_teams_loop, SourceLocation(),
6618 SourceLocation(), CollapsedNum) {}
6619
6620 /// Set whether associated loop can be a parallel for.
6621 void setCanBeParallelFor(bool ParFor) { CanBeParallelFor = ParFor; }
6622
6623public:
6624 /// Creates directive with a list of \p Clauses.
6625 ///
6626 /// \param C AST context.
6627 /// \param StartLoc Starting location of the directive kind.
6628 /// \param EndLoc Ending Location of the directive.
6629 /// \param CollapsedNum Number of collapsed loops.
6630 /// \param Clauses List of clauses.
6631 /// \param AssociatedStmt Statement, associated with the directive.
6632 /// \param Exprs Helper expressions for CodeGen.
6633 ///
6634 static OMPTargetTeamsGenericLoopDirective *
6635 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
6636 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
6637 Stmt *AssociatedStmt, const HelperExprs &Exprs, bool CanBeParallelFor);
6638
6639 /// Creates an empty directive with the place
6640 /// for \a NumClauses clauses.
6641 ///
6642 /// \param C AST context.
6643 /// \param CollapsedNum Number of collapsed nested loops.
6644 /// \param NumClauses Number of clauses.
6645 ///
6646 static OMPTargetTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C,
6647 unsigned NumClauses,
6648 unsigned CollapsedNum,
6649 EmptyShell);
6650
6651 /// Return true if current loop directive's associated loop can be a
6652 /// parallel for.
6653 bool canBeParallelFor() const { return CanBeParallelFor; }
6654
6655 static bool classof(const Stmt *T) {
6656 return T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass;
6657 }
6658};
6659
6660/// This represents '#pragma omp parallel loop' directive.
6661///
6662/// \code
6663/// #pragma omp parallel loop private(a,b) order(concurrent)
6664/// \endcode
6665/// In this example directive '#pragma omp parallel loop' has
6666/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
6667///
6668class OMPParallelGenericLoopDirective final : public OMPLoopDirective {
6669 friend class ASTStmtReader;
6671 /// Build directive with the given start and end location.
6672 ///
6673 /// \param StartLoc Starting location of the directive kind.
6674 /// \param EndLoc Ending location of the directive.
6675 /// \param CollapsedNum Number of collapsed nested loops.
6676 ///
6677 OMPParallelGenericLoopDirective(SourceLocation StartLoc,
6678 SourceLocation EndLoc, unsigned CollapsedNum)
6679 : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass,
6680 llvm::omp::OMPD_parallel_loop, StartLoc, EndLoc,
6681 CollapsedNum) {}
6682
6683 /// Build an empty directive.
6684 ///
6685 /// \param CollapsedNum Number of collapsed nested loops.
6686 ///
6687 explicit OMPParallelGenericLoopDirective(unsigned CollapsedNum)
6688 : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass,
6689 llvm::omp::OMPD_parallel_loop, SourceLocation(),
6690 SourceLocation(), CollapsedNum) {}
6691
6692public:
6693 /// Creates directive with a list of \p Clauses.
6694 ///
6695 /// \param C AST context.
6696 /// \param StartLoc Starting location of the directive kind.
6697 /// \param EndLoc Ending Location of the directive.
6698 /// \param CollapsedNum Number of collapsed loops.
6699 /// \param Clauses List of clauses.
6700 /// \param AssociatedStmt Statement, associated with the directive.
6701 /// \param Exprs Helper expressions for CodeGen.
6702 ///
6703 static OMPParallelGenericLoopDirective *
6704 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
6705 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
6706 Stmt *AssociatedStmt, const HelperExprs &Exprs);
6707
6708 /// Creates an empty directive with the place
6709 /// for \a NumClauses clauses.
6710 ///
6711 /// \param C AST context.
6712 /// \param CollapsedNum Number of collapsed nested loops.
6713 /// \param NumClauses Number of clauses.
6714 ///
6715 static OMPParallelGenericLoopDirective *CreateEmpty(const ASTContext &C,
6716 unsigned NumClauses,
6717 unsigned CollapsedNum,
6718 EmptyShell);
6719
6720 static bool classof(const Stmt *T) {
6721 return T->getStmtClass() == OMPParallelGenericLoopDirectiveClass;
6722 }
6723};
6724
6725/// This represents '#pragma omp target parallel loop' directive.
6726///
6727/// \code
6728/// #pragma omp target parallel loop private(a,b) order(concurrent)
6729/// \endcode
6730/// In this example directive '#pragma omp target parallel loop' has
6731/// clauses 'private' with the variables 'a' and 'b', and order(concurrent).
6732///
6733class OMPTargetParallelGenericLoopDirective final : public OMPLoopDirective {
6734 friend class ASTStmtReader;
6736 /// Build directive with the given start and end location.
6737 ///
6738 /// \param StartLoc Starting location of the directive kind.
6739 /// \param EndLoc Ending location of the directive.
6740 /// \param CollapsedNum Number of collapsed nested loops.
6741 ///
6742 OMPTargetParallelGenericLoopDirective(SourceLocation StartLoc,
6743 SourceLocation EndLoc,
6744 unsigned CollapsedNum)
6745 : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass,
6746 llvm::omp::OMPD_target_parallel_loop, StartLoc, EndLoc,
6747 CollapsedNum) {}
6748
6749 /// Build an empty directive.
6750 ///
6751 /// \param CollapsedNum Number of collapsed nested loops.
6752 ///
6753 explicit OMPTargetParallelGenericLoopDirective(unsigned CollapsedNum)
6754 : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass,
6755 llvm::omp::OMPD_target_parallel_loop, SourceLocation(),
6756 SourceLocation(), CollapsedNum) {}
6757
6758public:
6759 /// Creates directive with a list of \p Clauses.
6760 ///
6761 /// \param C AST context.
6762 /// \param StartLoc Starting location of the directive kind.
6763 /// \param EndLoc Ending Location of the directive.
6764 /// \param CollapsedNum Number of collapsed loops.
6765 /// \param Clauses List of clauses.
6766 /// \param AssociatedStmt Statement, associated with the directive.
6767 /// \param Exprs Helper expressions for CodeGen.
6768 ///
6769 static OMPTargetParallelGenericLoopDirective *
6770 Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
6771 unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
6772 Stmt *AssociatedStmt, const HelperExprs &Exprs);
6773
6774 /// Creates an empty directive with the place
6775 /// for \a NumClauses clauses.
6776 ///
6777 /// \param C AST context.
6778 /// \param CollapsedNum Number of collapsed nested loops.
6779 /// \param NumClauses Number of clauses.
6780 ///
6781 static OMPTargetParallelGenericLoopDirective *
6782 CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
6783 EmptyShell);
6784
6785 static bool classof(const Stmt *T) {
6786 return T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass;
6787 }
6788};
6789
6790/// This represents '#pragma omp error' directive.
6791///
6792/// \code
6793/// #pragma omp error
6794/// \endcode
6795class OMPErrorDirective final : public OMPExecutableDirective {
6796 friend class ASTStmtReader;
6798 /// Build directive with the given start and end location.
6799 ///
6800 /// \param StartLoc Starting location of the directive kind.
6801 /// \param EndLoc Ending location of the directive.
6802 ///
6803 OMPErrorDirective(SourceLocation StartLoc, SourceLocation EndLoc)
6804 : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error,
6805 StartLoc, EndLoc) {}
6806 /// Build an empty directive.
6807 ///
6808 explicit OMPErrorDirective()
6809 : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error,
6810 SourceLocation(), SourceLocation()) {}
6811
6812public:
6813 ///
6814 /// \param C AST context.
6815 /// \param StartLoc Starting location of the directive kind.
6816 /// \param EndLoc Ending Location of the directive.
6817 /// \param Clauses List of clauses.
6818 ///
6819 static OMPErrorDirective *Create(const ASTContext &C, SourceLocation StartLoc,
6820 SourceLocation EndLoc,
6821 ArrayRef<OMPClause *> Clauses);
6822
6823 /// Creates an empty directive.
6824 ///
6825 /// \param C AST context.
6826 ///
6827 static OMPErrorDirective *CreateEmpty(const ASTContext &C,
6828 unsigned NumClauses, EmptyShell);
6829
6830 static bool classof(const Stmt *T) {
6831 return T->getStmtClass() == OMPErrorDirectiveClass;
6832 }
6833};
6834
6835// It's not really an executable directive, but it seems convenient to use
6836// that as the parent class.
6837class OMPAssumeDirective final : public OMPExecutableDirective {
6838 friend class ASTStmtReader;
6840
6841private:
6842 OMPAssumeDirective(SourceLocation StartLoc, SourceLocation EndLoc)
6843 : OMPExecutableDirective(OMPAssumeDirectiveClass, llvm::omp::OMPD_assume,
6844 StartLoc, EndLoc) {}
6845
6846 explicit OMPAssumeDirective()
6847 : OMPExecutableDirective(OMPAssumeDirectiveClass, llvm::omp::OMPD_assume,
6848 SourceLocation(), SourceLocation()) {}
6849
6850public:
6851 static OMPAssumeDirective *Create(const ASTContext &Ctx,
6852 SourceLocation StartLoc,
6853 SourceLocation EndLoc,
6854 ArrayRef<OMPClause *> Clauses, Stmt *AStmt);
6855
6856 static OMPAssumeDirective *CreateEmpty(const ASTContext &C,
6857 unsigned NumClauses, EmptyShell);
6858
6859 static bool classof(const Stmt *T) {
6860 return T->getStmtClass() == OMPAssumeDirectiveClass;
6861 }
6862};
6863
6864} // end namespace clang
6865
6866namespace llvm {
6867// Allow a Stmt* be casted correctly to an OMPLoopTransformationDirective*.
6868// The default routines would just use a C-style cast which won't work well
6869// for the multiple inheritance here. We have to use a static cast from the
6870// corresponding subclass.
6871template <>
6873 : public NullableValueCastFailed<clang::OMPLoopTransformationDirective *>,
6875 clang::OMPLoopTransformationDirective *, clang::Stmt *,
6876 CastInfo<clang::OMPLoopTransformationDirective, clang::Stmt *>> {
6877 static bool isPossible(const clang::Stmt *T) {
6878 return clang::OMPLoopTransformationDirective::classof(T);
6879 }
6880
6881 static clang::OMPLoopTransformationDirective *doCast(clang::Stmt *T) {
6882 if (auto *D =
6883 dyn_cast<clang::OMPCanonicalLoopNestTransformationDirective>(T))
6884 return static_cast<clang::OMPLoopTransformationDirective *>(D);
6885 if (auto *D =
6886 dyn_cast<clang::OMPCanonicalLoopSequenceTransformationDirective>(T))
6887 return static_cast<clang::OMPLoopTransformationDirective *>(D);
6888 llvm_unreachable("unexpected type");
6889 }
6890};
6891template <>
6894 clang::OMPLoopTransformationDirective, const clang::Stmt *,
6895 CastInfo<clang::OMPLoopTransformationDirective, clang::Stmt *>> {};
6896
6897} // namespace llvm
6898
6899#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:223
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
Represents the 'pragma omp split' loop transformation directive.
Stmt * getPreInits() const
Return preinits statement.
Stmt * getTransformedStmt() const
Gets/sets the associated loops after the transformation, i.e.
static bool classof(const Stmt *T)
friend class OMPExecutableDirective
friend class ASTStmtReader
This represents the 'pragma omp stripe' loop transformation directive.
static bool classof(const Stmt *T)
Stmt * getPreInits() const
Return preinits statement.
Stmt * getTransformedStmt() const
Gets/sets the associated loops after striping.
friend class OMPExecutableDirective
friend class ASTStmtReader
This represents 'pragma omp target data' directive.
static bool classof(const Stmt *T)
friend class OMPExecutableDirective
friend class ASTStmtReader
This represents 'pragma omp target' directive.
static bool classof(const Stmt *T)
friend class OMPExecutableDirective
friend class ASTStmtReader
This represents 'pragma omp target enter data' directive.
friend class OMPExecutableDirective
static bool classof(const Stmt *T)
This represents 'pragma omp target exit data' directive.
friend class OMPExecutableDirective
static bool classof(const Stmt *T)
This represents 'pragma omp target parallel' directive.
static bool classof(const Stmt *T)
bool hasCancel() const
Return true if current directive has inner cancel directive.
const Expr * getTaskReductionRefExpr() const
Expr * getTaskReductionRefExpr()
Returns special task reduction reference expression.
friend class OMPExecutableDirective
This represents 'pragma omp target parallel for' directive.
const Expr * getTaskReductionRefExpr() const
static bool classof(const Stmt *T)
bool hasCancel() const
Return true if current directive has inner cancel directive.
Expr * getTaskReductionRefExpr()
Returns special task reduction reference expression.
This represents 'pragma omp target parallel for simd' directive.
static bool classof(const Stmt *T)
This represents 'pragma omp target parallel loop' directive.
static bool classof(const Stmt *T)
This represents 'pragma omp target simd' directive.
static bool classof(const Stmt *T)
friend class OMPExecutableDirective
friend class ASTStmtReader
This represents 'pragma omp target teams' directive.
static bool classof(const Stmt *T)
friend class OMPExecutableDirective
friend class ASTStmtReader
This represents 'pragma omp target teams distribute' combined directive.
static bool classof(const Stmt *T)
This represents 'pragma omp target teams distribute parallel for' combined directive.
Expr * getTaskReductionRefExpr()
Returns special task reduction reference expression.
bool hasCancel() const
Return true if current directive has inner cancel directive.
This represents 'pragma omp target teams distribute parallel for simd' combined directive.
This represents 'pragma omp target teams distribute simd' combined directive.
static bool classof(const Stmt *T)
This represents 'pragma omp target teams loop' directive.
static bool classof(const Stmt *T)
bool canBeParallelFor() const
Return true if current loop directive's associated loop can be a parallel for.
This represents 'pragma omp target update' directive.
static bool classof(const Stmt *T)
friend class OMPExecutableDirective
This represents 'pragma omp 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:2412
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:987
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions &DiagOpts, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
Top level wrappers for InstallAPI frontend operations.
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
bool isa(CodeGen::Address addr)
Definition Address.h:330
MutableArrayRef< Expr * > getFinals()
Sets the list of final update expressions for linear variables.
Stmt * getStructuredBlock()
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
void setUpdates(ArrayRef< Expr * > UL)
Sets the list of update expressions for linear variables.
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.
child_range used_children()
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 ...
void setInits(ArrayRef< Expr * > IL)
Sets the list of the initial values for linear variables.
inits_range inits()
llvm::omp::Directive OpenMPDirectiveKind
OpenMP directives.
Definition OpenMPKinds.h:25
MutableArrayRef< Expr * > getUpdates()
Sets the list of update expressions for linear variables.
updates_range updates()
void setFinals(ArrayRef< Expr * > FL)
Sets the list of final update expressions for linear variables.
finals_range finals()
void getOpenMPCaptureRegions(llvm::SmallVectorImpl< OpenMPDirectiveKind > &CaptureRegions, OpenMPDirectiveKind DKind)
Return the captured regions of an OpenMP directive.
MutableArrayRef< Expr * > getInits()
child_range children()
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
__packed_splat4 __packed_splat2 __packed_splat8 __packed_splat4 __packed_splat2 uint8_t
static clang::OMPLoopTransformationDirective * doCast(clang::Stmt *T)