clang  17.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 
17 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/Expr.h"
19 #include "clang/AST/OpenMPClause.h"
20 #include "clang/AST/Stmt.h"
21 #include "clang/AST/StmtCXX.h"
24 
25 namespace clang {
26 
27 //===----------------------------------------------------------------------===//
28 // AST classes for directives.
29 //===----------------------------------------------------------------------===//
30 
31 /// Representation of an OpenMP canonical loop.
32 ///
33 /// OpenMP 1.0 C/C++, section 2.4.1 for Construct; canonical-shape
34 /// OpenMP 2.0 C/C++, section 2.4.1 for Construct; canonical-shape
35 /// OpenMP 2.5, section 2.5.1 Loop Construct; canonical form
36 /// OpenMP 3.1, section 2.5.1 Loop Construct; canonical form
37 /// OpenMP 4.0, section 2.6 Canonical Loop Form
38 /// OpenMP 4.5, section 2.6 Canonical Loop Form
39 /// OpenMP 5.0, section 2.9.1 Canonical Loop Form
40 /// OpenMP 5.1, section 2.11.1 Canonical Loop Nest Form
41 ///
42 /// An OpenMP canonical loop is a for-statement or range-based for-statement
43 /// with additional requirements that ensure that the number of iterations is
44 /// known before entering the loop and allow skipping to an arbitrary iteration.
45 /// The OMPCanonicalLoop AST node wraps a ForStmt or CXXForRangeStmt that is
46 /// known to fulfill OpenMP's canonical loop requirements because of being
47 /// associated to an OMPLoopBasedDirective. That is, the general structure is:
48 ///
49 /// OMPLoopBasedDirective
50 /// [`- CapturedStmt ]
51 /// [ `- CapturedDecl]
52 /// ` OMPCanonicalLoop
53 /// `- ForStmt/CXXForRangeStmt
54 /// `- Stmt
55 ///
56 /// One or multiple CapturedStmt/CapturedDecl pairs may be inserted by some
57 /// directives such as OMPParallelForDirective, but others do not need them
58 /// (such as OMPTileDirective). In The OMPCanonicalLoop and
59 /// ForStmt/CXXForRangeStmt pair is repeated for loop associated with the
60 /// directive. A OMPCanonicalLoop must not appear in the AST unless associated
61 /// with a OMPLoopBasedDirective. In an imperfectly nested loop nest, the
62 /// OMPCanonicalLoop may also be wrapped in a CompoundStmt:
63 ///
64 /// [...]
65 /// ` OMPCanonicalLoop
66 /// `- ForStmt/CXXForRangeStmt
67 /// `- CompoundStmt
68 /// |- Leading in-between code (if any)
69 /// |- OMPCanonicalLoop
70 /// | `- ForStmt/CXXForRangeStmt
71 /// | `- ...
72 /// `- Trailing in-between code (if any)
73 ///
74 /// The leading/trailing in-between code must not itself be a OMPCanonicalLoop
75 /// to avoid confusion which loop belongs to the nesting.
76 ///
77 /// There are three different kinds of iteration variables for different
78 /// purposes:
79 /// * Loop user variable: The user-accessible variable with different value for
80 /// each iteration.
81 /// * Loop iteration variable: The variable used to identify a loop iteration;
82 /// for range-based for-statement, this is the hidden iterator '__begin'. For
83 /// other loops, it is identical to the loop user variable. Must be a
84 /// random-access iterator, pointer or integer type.
85 /// * Logical iteration counter: Normalized loop counter starting at 0 and
86 /// incrementing by one at each iteration. Allows abstracting over the type
87 /// of the loop iteration variable and is always an unsigned integer type
88 /// appropriate to represent the range of the loop iteration variable. Its
89 /// value corresponds to the logical iteration number in the OpenMP
90 /// specification.
91 ///
92 /// This AST node provides two captured statements:
93 /// * The distance function which computes the number of iterations.
94 /// * The loop user variable function that computes the loop user variable when
95 /// given a logical iteration number.
96 ///
97 /// These captured statements provide the link between C/C++ semantics and the
98 /// logical iteration counters used by the OpenMPIRBuilder which is
99 /// language-agnostic and therefore does not know e.g. how to advance a
100 /// random-access iterator. The OpenMPIRBuilder will use this information to
101 /// apply simd, workshare-loop, distribute, taskloop and loop directives to the
102 /// loop. For compatibility with the non-OpenMPIRBuilder codegen path, an
103 /// OMPCanonicalLoop can itself also be wrapped into the CapturedStmts of an
104 /// OMPLoopDirective and skipped when searching for the associated syntactical
105 /// loop.
106 ///
107 /// Example:
108 /// <code>
109 /// std::vector<std::string> Container{1,2,3};
110 /// for (std::string Str : Container)
111 /// Body(Str);
112 /// </code>
113 /// which is syntactic sugar for approximately:
114 /// <code>
115 /// auto &&__range = Container;
116 /// auto __begin = std::begin(__range);
117 /// auto __end = std::end(__range);
118 /// for (; __begin != __end; ++__begin) {
119 /// std::String Str = *__begin;
120 /// Body(Str);
121 /// }
122 /// </code>
123 /// In this example, the loop user variable is `Str`, the loop iteration
124 /// variable is `__begin` of type `std::vector<std::string>::iterator` and the
125 /// logical iteration number type is `size_t` (unsigned version of
126 /// `std::vector<std::string>::iterator::difference_type` aka `ptrdiff_t`).
127 /// Therefore, the distance function will be
128 /// <code>
129 /// [&](size_t &Result) { Result = __end - __begin; }
130 /// </code>
131 /// and the loop variable function is
132 /// <code>
133 /// [&,__begin](std::vector<std::string>::iterator &Result, size_t Logical) {
134 /// Result = __begin + Logical;
135 /// }
136 /// </code>
137 /// The variable `__begin`, aka the loop iteration variable, is captured by
138 /// value because it is modified in the loop body, but both functions require
139 /// the initial value. The OpenMP specification explicitly leaves unspecified
140 /// when the loop expressions are evaluated such that a capture by reference is
141 /// sufficient.
142 class OMPCanonicalLoop : public Stmt {
143  friend class ASTStmtReader;
144  friend class ASTStmtWriter;
145 
146  /// Children of this AST node.
147  enum {
148  LOOP_STMT,
149  DISTANCE_FUNC,
150  LOOPVAR_FUNC,
151  LOOPVAR_REF,
152  LastSubStmt = LOOPVAR_REF
153  };
154 
155 private:
156  /// This AST node's children.
157  Stmt *SubStmts[LastSubStmt + 1] = {};
158 
159  OMPCanonicalLoop() : Stmt(StmtClass::OMPCanonicalLoopClass) {}
160 
161 public:
162  /// Create a new OMPCanonicalLoop.
163  static OMPCanonicalLoop *create(const ASTContext &Ctx, Stmt *LoopStmt,
164  CapturedStmt *DistanceFunc,
165  CapturedStmt *LoopVarFunc,
166  DeclRefExpr *LoopVarRef) {
167  OMPCanonicalLoop *S = new (Ctx) OMPCanonicalLoop();
168  S->setLoopStmt(LoopStmt);
169  S->setDistanceFunc(DistanceFunc);
170  S->setLoopVarFunc(LoopVarFunc);
171  S->setLoopVarRef(LoopVarRef);
172  return S;
173  }
174 
175  /// Create an empty OMPCanonicalLoop for deserialization.
177  return new (Ctx) OMPCanonicalLoop();
178  }
179 
180  static bool classof(const Stmt *S) {
181  return S->getStmtClass() == StmtClass::OMPCanonicalLoopClass;
182  }
183 
186 
187  /// Return this AST node's children.
188  /// @{
190  return child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1);
191  }
193  return const_child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1);
194  }
195  /// @}
196 
197  /// The wrapped syntactic loop statement (ForStmt or CXXForRangeStmt).
198  /// @{
199  Stmt *getLoopStmt() { return SubStmts[LOOP_STMT]; }
200  const Stmt *getLoopStmt() const { return SubStmts[LOOP_STMT]; }
201  void setLoopStmt(Stmt *S) {
202  assert((isa<ForStmt>(S) || isa<CXXForRangeStmt>(S)) &&
203  "Canonical loop must be a for loop (range-based or otherwise)");
204  SubStmts[LOOP_STMT] = S;
205  }
206  /// @}
207 
208  /// The function that computes the number of loop iterations. Can be evaluated
209  /// before entering the loop but after the syntactical loop's init
210  /// statement(s).
211  ///
212  /// Function signature: void(LogicalTy &Result)
213  /// Any values necessary to compute the distance are captures of the closure.
214  /// @{
216  return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]);
217  }
218  const CapturedStmt *getDistanceFunc() const {
219  return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]);
220  }
222  assert(S && "Expected non-null captured statement");
223  SubStmts[DISTANCE_FUNC] = S;
224  }
225  /// @}
226 
227  /// The function that computes the loop user variable from a logical iteration
228  /// counter. Can be evaluated as first statement in the loop.
229  ///
230  /// Function signature: void(LoopVarTy &Result, LogicalTy Number)
231  /// Any other values required to compute the loop user variable (such as start
232  /// value, step size) are captured by the closure. In particular, the initial
233  /// value of loop iteration variable is captured by value to be unaffected by
234  /// previous iterations.
235  /// @{
237  return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]);
238  }
239  const CapturedStmt *getLoopVarFunc() const {
240  return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]);
241  }
243  assert(S && "Expected non-null captured statement");
244  SubStmts[LOOPVAR_FUNC] = S;
245  }
246  /// @}
247 
248  /// Reference to the loop user variable as accessed in the loop body.
249  /// @{
251  return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]);
252  }
253  const DeclRefExpr *getLoopVarRef() const {
254  return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]);
255  }
257  assert(E && "Expected non-null loop variable");
258  SubStmts[LOOPVAR_REF] = E;
259  }
260  /// @}
261 };
262 
263 /// This is a basic class for representing single OpenMP executable
264 /// directive.
265 ///
266 class OMPExecutableDirective : public Stmt {
267  friend class ASTStmtReader;
268  friend class ASTStmtWriter;
269 
270  /// Kind of the directive.
271  OpenMPDirectiveKind Kind = llvm::omp::OMPD_unknown;
272  /// Starting location of the directive (directive keyword).
273  SourceLocation StartLoc;
274  /// Ending location of the directive.
275  SourceLocation EndLoc;
276 
277  /// Get the clauses storage.
278  MutableArrayRef<OMPClause *> getClauses() {
279  if (!Data)
280  return std::nullopt;
281  return Data->getClauses();
282  }
283 
284 protected:
285  /// Data, associated with the directive.
286  OMPChildren *Data = nullptr;
287 
288  /// Build instance of directive of class \a K.
289  ///
290  /// \param SC Statement class.
291  /// \param K Kind of OpenMP directive.
292  /// \param StartLoc Starting location of the directive (directive keyword).
293  /// \param EndLoc Ending location of the directive.
294  ///
296  SourceLocation StartLoc, SourceLocation EndLoc)
297  : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
298  EndLoc(std::move(EndLoc)) {}
299 
300  template <typename T, typename... Params>
302  Stmt *AssociatedStmt, unsigned NumChildren,
303  Params &&... P) {
304  void *Mem =
305  C.Allocate(sizeof(T) + OMPChildren::size(Clauses.size(), AssociatedStmt,
306  NumChildren),
307  alignof(T));
308 
309  auto *Data = OMPChildren::Create(reinterpret_cast<T *>(Mem) + 1, Clauses,
310  AssociatedStmt, NumChildren);
311  auto *Inst = new (Mem) T(std::forward<Params>(P)...);
312  Inst->Data = Data;
313  return Inst;
314  }
315 
316  template <typename T, typename... Params>
317  static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses,
318  bool HasAssociatedStmt, unsigned NumChildren,
319  Params &&... P) {
320  void *Mem =
321  C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt,
322  NumChildren),
323  alignof(T));
324  auto *Data =
325  OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses,
326  HasAssociatedStmt, NumChildren);
327  auto *Inst = new (Mem) T(std::forward<Params>(P)...);
328  Inst->Data = Data;
329  return Inst;
330  }
331 
332  template <typename T>
333  static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses,
334  bool HasAssociatedStmt = false,
335  unsigned NumChildren = 0) {
336  void *Mem =
337  C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt,
338  NumChildren),
339  alignof(T));
340  auto *Data =
341  OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses,
342  HasAssociatedStmt, NumChildren);
343  auto *Inst = new (Mem) T;
344  Inst->Data = Data;
345  return Inst;
346  }
347 
348 public:
349  /// Iterates over expressions/statements used in the construct.
351  : public llvm::iterator_adaptor_base<
352  used_clauses_child_iterator, ArrayRef<OMPClause *>::iterator,
353  std::forward_iterator_tag, Stmt *, ptrdiff_t, Stmt *, Stmt *> {
355  OMPClause::child_iterator ChildI, ChildEnd;
356 
357  void MoveToNext() {
358  if (ChildI != ChildEnd)
359  return;
360  while (this->I != End) {
361  ++this->I;
362  if (this->I != End) {
363  ChildI = (*this->I)->used_children().begin();
364  ChildEnd = (*this->I)->used_children().end();
365  if (ChildI != ChildEnd)
366  return;
367  }
368  }
369  }
370 
371  public:
373  : used_clauses_child_iterator::iterator_adaptor_base(Clauses.begin()),
374  End(Clauses.end()) {
375  if (this->I != End) {
376  ChildI = (*this->I)->used_children().begin();
377  ChildEnd = (*this->I)->used_children().end();
378  MoveToNext();
379  }
380  }
381  Stmt *operator*() const { return *ChildI; }
382  Stmt *operator->() const { return **this; }
383 
385  ++ChildI;
386  if (ChildI != ChildEnd)
387  return *this;
388  if (this->I != End) {
389  ++this->I;
390  if (this->I != End) {
391  ChildI = (*this->I)->used_children().begin();
392  ChildEnd = (*this->I)->used_children().end();
393  }
394  }
395  MoveToNext();
396  return *this;
397  }
398  };
399 
400  static llvm::iterator_range<used_clauses_child_iterator>
402  return {
404  used_clauses_child_iterator(llvm::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>
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 *> {
419 
420  void SkipToNextClause() {
421  while (this->I != End && !isa<SpecificClause>(*this->I))
422  ++this->I;
423  }
424 
425  public:
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 
438  ++this->I;
439  SkipToNextClause();
440  return *this;
441  }
442  };
443 
444  template <typename SpecificClause>
445  static llvm::iterator_range<specific_clause_iterator<SpecificClause>>
449  llvm::ArrayRef(Clauses.end(), (size_t)0))};
450  }
451 
452  template <typename SpecificClause>
453  llvm::iterator_range<specific_clause_iterator<SpecificClause>>
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  }
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.
535  assert(hasAssociatedStmt() &&
536  "Expected directive with the associated statement.");
538  getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
539  return Data->getCapturedStmt(RegionKind, CaptureRegions);
540  }
541 
542  /// Get innermost captured statement for the construct.
544  assert(hasAssociatedStmt() &&
545  "Expected directive with the associated statement.");
547  getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
548  return Data->getInnermostCapturedStmt(CaptureRegions);
549  }
550 
552  return const_cast<OMPExecutableDirective *>(this)
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 
564  if (!Data)
566  return Data->getAssociatedStmtAsRange();
567  }
568 
570  return const_cast<OMPExecutableDirective *>(this)->children();
571  }
572 
574  if (!Data)
575  return std::nullopt;
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  }
592 
593  const Stmt *getRawStmt() const {
594  return const_cast<OMPExecutableDirective *>(this)->getRawStmt();
595  }
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 ///
613  friend class ASTStmtReader;
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  ///
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 
640 public:
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.
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 /// The base class for all loop-based directives, including loop transformation
682 /// directives.
684  friend class ASTStmtReader;
685 
686 protected:
687  /// Number of collapsed loops as specified by 'collapse' clause.
688  unsigned NumAssociatedLoops = 0;
689 
690  /// Build instance of loop directive of class \a Kind.
691  ///
692  /// \param SC Statement class.
693  /// \param Kind Kind of OpenMP directive.
694  /// \param StartLoc Starting location of the directive (directive keyword).
695  /// \param EndLoc Ending location of the directive.
696  /// \param NumAssociatedLoops Number of loops associated with the construct.
697  ///
699  SourceLocation StartLoc, SourceLocation EndLoc,
700  unsigned NumAssociatedLoops)
701  : OMPExecutableDirective(SC, Kind, StartLoc, EndLoc),
703 
704 public:
705  /// The expressions built to support OpenMP loops in combined/composite
706  /// pragmas (e.g. pragma omp distribute parallel for)
708  /// DistributeLowerBound - used when composing 'omp distribute' with
709  /// 'omp for' in a same construct.
711  /// DistributeUpperBound - used when composing 'omp distribute' with
712  /// 'omp for' in a same construct.
714  /// DistributeEnsureUpperBound - used when composing 'omp distribute'
715  /// with 'omp for' in a same construct, EUB depends on DistUB
717  /// Distribute loop iteration variable init used when composing 'omp
718  /// distribute'
719  /// with 'omp for' in a same construct
721  /// Distribute Loop condition used when composing 'omp distribute'
722  /// with 'omp for' in a same construct
724  /// Update of LowerBound for statically scheduled omp loops for
725  /// outer loop in combined constructs (e.g. 'distribute parallel for')
727  /// Update of UpperBound for statically scheduled omp loops for
728  /// outer loop in combined constructs (e.g. 'distribute parallel for')
730  /// Distribute Loop condition used when composing 'omp distribute'
731  /// with 'omp for' in a same construct when schedule is chunked.
733  /// 'omp parallel for' loop condition used when composed with
734  /// 'omp distribute' in the same construct and when schedule is
735  /// chunked and the chunk size is 1.
737  };
738 
739  /// The expressions built for the OpenMP loop CodeGen for the
740  /// whole collapsed loop nest.
741  struct HelperExprs {
742  /// Loop iteration variable.
744  /// Loop last iteration number.
746  /// Loop number of iterations.
748  /// Calculation of last iteration.
750  /// Loop pre-condition.
752  /// Loop condition.
754  /// Loop iteration variable init.
756  /// Loop increment.
758  /// IsLastIteration - local flag variable passed to runtime.
760  /// LowerBound - local variable passed to runtime.
762  /// UpperBound - local variable passed to runtime.
764  /// Stride - local variable passed to runtime.
766  /// EnsureUpperBound -- expression UB = min(UB, NumIterations).
768  /// Update of LowerBound for statically scheduled 'omp for' loops.
770  /// Update of UpperBound for statically scheduled 'omp for' loops.
772  /// PreviousLowerBound - local variable passed to runtime in the
773  /// enclosing schedule or null if that does not apply.
775  /// PreviousUpperBound - local variable passed to runtime in the
776  /// enclosing schedule or null if that does not apply.
778  /// DistInc - increment expression for distribute loop when found
779  /// combined with a further loop level (e.g. in 'distribute parallel for')
780  /// expression IV = IV + ST
782  /// PrevEUB - expression similar to EUB but to be used when loop
783  /// scheduling uses PrevLB and PrevUB (e.g. in 'distribute parallel for'
784  /// when ensuring that the UB is either the calculated UB by the runtime or
785  /// the end of the assigned distribute chunk)
786  /// expression UB = min (UB, PrevUB)
788  /// Counters Loop counters.
790  /// PrivateCounters Loop counters.
792  /// Expressions for loop counters inits for CodeGen.
794  /// Expressions for loop counters update for CodeGen.
796  /// Final loop counter values for GodeGen.
798  /// List of counters required for the generation of the non-rectangular
799  /// loops.
801  /// List of initializers required for the generation of the non-rectangular
802  /// loops.
804  /// List of final conditions required for the generation of the
805  /// non-rectangular loops.
807  /// Init statement for all captured expressions.
809 
810  /// Expressions used when combining OpenMP loop pragmas
812 
813  /// Check if all the expressions are built (does not check the
814  /// worksharing ones).
815  bool builtAll() {
816  return IterationVarRef != nullptr && LastIteration != nullptr &&
817  NumIterations != nullptr && PreCond != nullptr &&
818  Cond != nullptr && Init != nullptr && Inc != nullptr;
819  }
820 
821  /// Initialize all the fields to null.
822  /// \param Size Number of elements in the
823  /// counters/finals/updates/dependent_counters/dependent_inits/finals_conditions
824  /// arrays.
825  void clear(unsigned Size) {
826  IterationVarRef = nullptr;
827  LastIteration = nullptr;
828  CalcLastIteration = nullptr;
829  PreCond = nullptr;
830  Cond = nullptr;
831  Init = nullptr;
832  Inc = nullptr;
833  IL = nullptr;
834  LB = nullptr;
835  UB = nullptr;
836  ST = nullptr;
837  EUB = nullptr;
838  NLB = nullptr;
839  NUB = nullptr;
840  NumIterations = nullptr;
841  PrevLB = nullptr;
842  PrevUB = nullptr;
843  DistInc = nullptr;
844  PrevEUB = nullptr;
845  Counters.resize(Size);
846  PrivateCounters.resize(Size);
847  Inits.resize(Size);
848  Updates.resize(Size);
849  Finals.resize(Size);
850  DependentCounters.resize(Size);
851  DependentInits.resize(Size);
852  FinalsConditions.resize(Size);
853  for (unsigned I = 0; I < Size; ++I) {
854  Counters[I] = nullptr;
855  PrivateCounters[I] = nullptr;
856  Inits[I] = nullptr;
857  Updates[I] = nullptr;
858  Finals[I] = nullptr;
859  DependentCounters[I] = nullptr;
860  DependentInits[I] = nullptr;
861  FinalsConditions[I] = nullptr;
862  }
863  PreInits = nullptr;
864  DistCombinedFields.LB = nullptr;
865  DistCombinedFields.UB = nullptr;
866  DistCombinedFields.EUB = nullptr;
867  DistCombinedFields.Init = nullptr;
868  DistCombinedFields.Cond = nullptr;
869  DistCombinedFields.NLB = nullptr;
870  DistCombinedFields.NUB = nullptr;
871  DistCombinedFields.DistCond = nullptr;
873  }
874  };
875 
876  /// Get number of collapsed loops.
877  unsigned getLoopsNumber() const { return NumAssociatedLoops; }
878 
879  /// Try to find the next loop sub-statement in the specified statement \p
880  /// CurStmt.
881  /// \param TryImperfectlyNestedLoops true, if we need to try to look for the
882  /// imperfectly nested loop.
883  static Stmt *tryToFindNextInnerLoop(Stmt *CurStmt,
884  bool TryImperfectlyNestedLoops);
885  static const Stmt *tryToFindNextInnerLoop(const Stmt *CurStmt,
886  bool TryImperfectlyNestedLoops) {
887  return tryToFindNextInnerLoop(const_cast<Stmt *>(CurStmt),
888  TryImperfectlyNestedLoops);
889  }
890 
891  /// Calls the specified callback function for all the loops in \p CurStmt,
892  /// from the outermost to the innermost.
893  static bool
894  doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
895  unsigned NumLoops,
896  llvm::function_ref<bool(unsigned, Stmt *)> Callback,
897  llvm::function_ref<void(OMPLoopTransformationDirective *)>
898  OnTransformationCallback);
899  static bool
900  doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
901  unsigned NumLoops,
902  llvm::function_ref<bool(unsigned, const Stmt *)> Callback,
903  llvm::function_ref<void(const OMPLoopTransformationDirective *)>
904  OnTransformationCallback) {
905  auto &&NewCallback = [Callback](unsigned Cnt, Stmt *CurStmt) {
906  return Callback(Cnt, CurStmt);
907  };
908  auto &&NewTransformCb =
909  [OnTransformationCallback](OMPLoopTransformationDirective *A) {
910  OnTransformationCallback(A);
911  };
912  return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
913  NumLoops, NewCallback, NewTransformCb);
914  }
915 
916  /// Calls the specified callback function for all the loops in \p CurStmt,
917  /// from the outermost to the innermost.
918  static bool
919  doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
920  unsigned NumLoops,
921  llvm::function_ref<bool(unsigned, Stmt *)> Callback) {
922  auto &&TransformCb = [](OMPLoopTransformationDirective *) {};
923  return doForAllLoops(CurStmt, TryImperfectlyNestedLoops, NumLoops, Callback,
924  TransformCb);
925  }
926  static bool
927  doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
928  unsigned NumLoops,
929  llvm::function_ref<bool(unsigned, const Stmt *)> Callback) {
930  auto &&NewCallback = [Callback](unsigned Cnt, const Stmt *CurStmt) {
931  return Callback(Cnt, CurStmt);
932  };
933  return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
934  NumLoops, NewCallback);
935  }
936 
937  /// Calls the specified callback function for all the loop bodies in \p
938  /// CurStmt, from the outermost loop to the innermost.
939  static void doForAllLoopsBodies(
940  Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops,
941  llvm::function_ref<void(unsigned, Stmt *, Stmt *)> Callback);
942  static void doForAllLoopsBodies(
943  const Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops,
944  llvm::function_ref<void(unsigned, const Stmt *, const Stmt *)> Callback) {
945  auto &&NewCallback = [Callback](unsigned Cnt, Stmt *Loop, Stmt *Body) {
946  Callback(Cnt, Loop, Body);
947  };
948  doForAllLoopsBodies(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
949  NumLoops, NewCallback);
950  }
951 
952  static bool classof(const Stmt *T) {
953  if (auto *D = dyn_cast<OMPExecutableDirective>(T))
954  return isOpenMPLoopDirective(D->getDirectiveKind());
955  return false;
956  }
957 };
958 
959 /// The base class for all loop transformation directives.
961  friend class ASTStmtReader;
962 
963  /// Number of loops generated by this loop transformation.
964  unsigned NumGeneratedLoops = 0;
965 
966 protected:
969  SourceLocation StartLoc,
970  SourceLocation EndLoc,
971  unsigned NumAssociatedLoops)
972  : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, NumAssociatedLoops) {}
973 
974  /// Set the number of loops generated by this loop transformation.
975  void setNumGeneratedLoops(unsigned Num) { NumGeneratedLoops = Num; }
976 
977 public:
978  /// Return the number of associated (consumed) loops.
979  unsigned getNumAssociatedLoops() const { return getLoopsNumber(); }
980 
981  /// Return the number of loops generated by this loop transformation.
982  unsigned getNumGeneratedLoops() { return NumGeneratedLoops; }
983 
984  /// Get the de-sugared statements after the loop transformation.
985  ///
986  /// Might be nullptr if either the directive generates no loops and is handled
987  /// directly in CodeGen, or resolving a template-dependence context is
988  /// required.
989  Stmt *getTransformedStmt() const;
990 
991  /// Return preinits statement.
992  Stmt *getPreInits() const;
993 
994  static bool classof(const Stmt *T) {
995  return T->getStmtClass() == OMPTileDirectiveClass ||
996  T->getStmtClass() == OMPUnrollDirectiveClass;
997  }
998 };
999 
1000 /// This is a common base class for loop directives ('omp simd', 'omp
1001 /// for', 'omp for simd' etc.). It is responsible for the loop code generation.
1002 ///
1004  friend class ASTStmtReader;
1005 
1006  /// Offsets to the stored exprs.
1007  /// This enumeration contains offsets to all the pointers to children
1008  /// expressions stored in OMPLoopDirective.
1009  /// The first 9 children are necessary for all the loop directives,
1010  /// the next 8 are specific to the worksharing ones, and the next 11 are
1011  /// used for combined constructs containing two pragmas associated to loops.
1012  /// After the fixed children, three arrays of length NumAssociatedLoops are
1013  /// allocated: loop counters, their updates and final values.
1014  /// PrevLowerBound and PrevUpperBound are used to communicate blocking
1015  /// information in composite constructs which require loop blocking
1016  /// DistInc is used to generate the increment expression for the distribute
1017  /// loop when combined with a further nested loop
1018  /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the
1019  /// for loop when combined with a previous distribute loop in the same pragma
1020  /// (e.g. 'distribute parallel for')
1021  ///
1022  enum {
1023  IterationVariableOffset = 0,
1024  LastIterationOffset = 1,
1025  CalcLastIterationOffset = 2,
1026  PreConditionOffset = 3,
1027  CondOffset = 4,
1028  InitOffset = 5,
1029  IncOffset = 6,
1030  PreInitsOffset = 7,
1031  // The '...End' enumerators do not correspond to child expressions - they
1032  // specify the offset to the end (and start of the following counters/
1033  // updates/finals/dependent_counters/dependent_inits/finals_conditions
1034  // arrays).
1035  DefaultEnd = 8,
1036  // The following 8 exprs are used by worksharing and distribute loops only.
1037  IsLastIterVariableOffset = 8,
1038  LowerBoundVariableOffset = 9,
1039  UpperBoundVariableOffset = 10,
1040  StrideVariableOffset = 11,
1041  EnsureUpperBoundOffset = 12,
1042  NextLowerBoundOffset = 13,
1043  NextUpperBoundOffset = 14,
1044  NumIterationsOffset = 15,
1045  // Offset to the end for worksharing loop directives.
1046  WorksharingEnd = 16,
1047  PrevLowerBoundVariableOffset = 16,
1048  PrevUpperBoundVariableOffset = 17,
1049  DistIncOffset = 18,
1050  PrevEnsureUpperBoundOffset = 19,
1051  CombinedLowerBoundVariableOffset = 20,
1052  CombinedUpperBoundVariableOffset = 21,
1053  CombinedEnsureUpperBoundOffset = 22,
1054  CombinedInitOffset = 23,
1055  CombinedConditionOffset = 24,
1056  CombinedNextLowerBoundOffset = 25,
1057  CombinedNextUpperBoundOffset = 26,
1058  CombinedDistConditionOffset = 27,
1059  CombinedParForInDistConditionOffset = 28,
1060  // Offset to the end (and start of the following
1061  // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions
1062  // arrays) for combined distribute loop directives.
1063  CombinedDistributeEnd = 29,
1064  };
1065 
1066  /// Get the counters storage.
1067  MutableArrayRef<Expr *> getCounters() {
1068  auto **Storage = reinterpret_cast<Expr **>(
1070  return llvm::MutableArrayRef(Storage, getLoopsNumber());
1071  }
1072 
1073  /// Get the private counters storage.
1074  MutableArrayRef<Expr *> getPrivateCounters() {
1075  auto **Storage = reinterpret_cast<Expr **>(
1077  getLoopsNumber()]);
1078  return llvm::MutableArrayRef(Storage, getLoopsNumber());
1079  }
1080 
1081  /// Get the updates storage.
1082  MutableArrayRef<Expr *> getInits() {
1083  auto **Storage = reinterpret_cast<Expr **>(
1085  2 * getLoopsNumber()]);
1086  return llvm::MutableArrayRef(Storage, getLoopsNumber());
1087  }
1088 
1089  /// Get the updates storage.
1090  MutableArrayRef<Expr *> getUpdates() {
1091  auto **Storage = reinterpret_cast<Expr **>(
1093  3 * getLoopsNumber()]);
1094  return llvm::MutableArrayRef(Storage, getLoopsNumber());
1095  }
1096 
1097  /// Get the final counter updates storage.
1098  MutableArrayRef<Expr *> getFinals() {
1099  auto **Storage = reinterpret_cast<Expr **>(
1101  4 * getLoopsNumber()]);
1102  return llvm::MutableArrayRef(Storage, getLoopsNumber());
1103  }
1104 
1105  /// Get the dependent counters storage.
1106  MutableArrayRef<Expr *> getDependentCounters() {
1107  auto **Storage = reinterpret_cast<Expr **>(
1109  5 * getLoopsNumber()]);
1110  return llvm::MutableArrayRef(Storage, getLoopsNumber());
1111  }
1112 
1113  /// Get the dependent inits storage.
1114  MutableArrayRef<Expr *> getDependentInits() {
1115  auto **Storage = reinterpret_cast<Expr **>(
1117  6 * getLoopsNumber()]);
1118  return llvm::MutableArrayRef(Storage, getLoopsNumber());
1119  }
1120 
1121  /// Get the finals conditions storage.
1122  MutableArrayRef<Expr *> getFinalsConditions() {
1123  auto **Storage = reinterpret_cast<Expr **>(
1125  7 * getLoopsNumber()]);
1126  return llvm::MutableArrayRef(Storage, getLoopsNumber());
1127  }
1128 
1129 protected:
1130  /// Build instance of loop directive of class \a Kind.
1131  ///
1132  /// \param SC Statement class.
1133  /// \param Kind Kind of OpenMP directive.
1134  /// \param StartLoc Starting location of the directive (directive keyword).
1135  /// \param EndLoc Ending location of the directive.
1136  /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
1137  ///
1139  SourceLocation StartLoc, SourceLocation EndLoc,
1140  unsigned CollapsedNum)
1141  : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, CollapsedNum) {}
1142 
1143  /// Offset to the start of children expression arrays.
1146  return CombinedDistributeEnd;
1149  return WorksharingEnd;
1150  return DefaultEnd;
1151  }
1152 
1153  /// Children number.
1154  static unsigned numLoopChildren(unsigned CollapsedNum,
1156  return getArraysOffset(Kind) +
1157  8 * CollapsedNum; // Counters, PrivateCounters, Inits,
1158  // Updates, Finals, DependentCounters,
1159  // DependentInits, FinalsConditions.
1160  }
1161 
1163  Data->getChildren()[IterationVariableOffset] = IV;
1164  }
1166  Data->getChildren()[LastIterationOffset] = LI;
1167  }
1169  Data->getChildren()[CalcLastIterationOffset] = CLI;
1170  }
1171  void setPreCond(Expr *PC) { Data->getChildren()[PreConditionOffset] = PC; }
1172  void setCond(Expr *Cond) { Data->getChildren()[CondOffset] = Cond; }
1173  void setInit(Expr *Init) { Data->getChildren()[InitOffset] = Init; }
1174  void setInc(Expr *Inc) { Data->getChildren()[IncOffset] = Inc; }
1175  void setPreInits(Stmt *PreInits) {
1176  Data->getChildren()[PreInitsOffset] = PreInits;
1177  }
1183  "expected worksharing loop directive");
1184  Data->getChildren()[IsLastIterVariableOffset] = IL;
1185  }
1191  "expected worksharing loop directive");
1192  Data->getChildren()[LowerBoundVariableOffset] = LB;
1193  }
1199  "expected worksharing loop directive");
1200  Data->getChildren()[UpperBoundVariableOffset] = UB;
1201  }
1207  "expected worksharing loop directive");
1208  Data->getChildren()[StrideVariableOffset] = ST;
1209  }
1215  "expected worksharing loop directive");
1216  Data->getChildren()[EnsureUpperBoundOffset] = EUB;
1217  }
1223  "expected worksharing loop directive");
1224  Data->getChildren()[NextLowerBoundOffset] = NLB;
1225  }
1231  "expected worksharing loop directive");
1232  Data->getChildren()[NextUpperBoundOffset] = NUB;
1233  }
1239  "expected worksharing loop directive");
1240  Data->getChildren()[NumIterationsOffset] = NI;
1241  }
1244  "expected loop bound sharing directive");
1245  Data->getChildren()[PrevLowerBoundVariableOffset] = PrevLB;
1246  }
1249  "expected loop bound sharing directive");
1250  Data->getChildren()[PrevUpperBoundVariableOffset] = PrevUB;
1251  }
1252  void setDistInc(Expr *DistInc) {
1254  "expected loop bound sharing directive");
1255  Data->getChildren()[DistIncOffset] = DistInc;
1256  }
1259  "expected loop bound sharing directive");
1260  Data->getChildren()[PrevEnsureUpperBoundOffset] = PrevEUB;
1261  }
1264  "expected loop bound sharing directive");
1265  Data->getChildren()[CombinedLowerBoundVariableOffset] = CombLB;
1266  }
1269  "expected loop bound sharing directive");
1270  Data->getChildren()[CombinedUpperBoundVariableOffset] = CombUB;
1271  }
1274  "expected loop bound sharing directive");
1275  Data->getChildren()[CombinedEnsureUpperBoundOffset] = CombEUB;
1276  }
1277  void setCombinedInit(Expr *CombInit) {
1279  "expected loop bound sharing directive");
1280  Data->getChildren()[CombinedInitOffset] = CombInit;
1281  }
1282  void setCombinedCond(Expr *CombCond) {
1284  "expected loop bound sharing directive");
1285  Data->getChildren()[CombinedConditionOffset] = CombCond;
1286  }
1289  "expected loop bound sharing directive");
1290  Data->getChildren()[CombinedNextLowerBoundOffset] = CombNLB;
1291  }
1294  "expected loop bound sharing directive");
1295  Data->getChildren()[CombinedNextUpperBoundOffset] = CombNUB;
1296  }
1297  void setCombinedDistCond(Expr *CombDistCond) {
1299  "expected loop bound distribute sharing directive");
1300  Data->getChildren()[CombinedDistConditionOffset] = CombDistCond;
1301  }
1302  void setCombinedParForInDistCond(Expr *CombParForInDistCond) {
1304  "expected loop bound distribute sharing directive");
1305  Data->getChildren()[CombinedParForInDistConditionOffset] =
1306  CombParForInDistCond;
1307  }
1308  void setCounters(ArrayRef<Expr *> A);
1310  void setInits(ArrayRef<Expr *> A);
1311  void setUpdates(ArrayRef<Expr *> A);
1312  void setFinals(ArrayRef<Expr *> A);
1316 
1317 public:
1319  return cast<Expr>(Data->getChildren()[IterationVariableOffset]);
1320  }
1322  return cast<Expr>(Data->getChildren()[LastIterationOffset]);
1323  }
1325  return cast<Expr>(Data->getChildren()[CalcLastIterationOffset]);
1326  }
1327  Expr *getPreCond() const {
1328  return cast<Expr>(Data->getChildren()[PreConditionOffset]);
1329  }
1330  Expr *getCond() const { return cast<Expr>(Data->getChildren()[CondOffset]); }
1331  Expr *getInit() const { return cast<Expr>(Data->getChildren()[InitOffset]); }
1332  Expr *getInc() const { return cast<Expr>(Data->getChildren()[IncOffset]); }
1333  const Stmt *getPreInits() const {
1334  return Data->getChildren()[PreInitsOffset];
1335  }
1336  Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; }
1342  "expected worksharing loop directive");
1343  return cast<Expr>(Data->getChildren()[IsLastIterVariableOffset]);
1344  }
1350  "expected worksharing loop directive");
1351  return cast<Expr>(Data->getChildren()[LowerBoundVariableOffset]);
1352  }
1358  "expected worksharing loop directive");
1359  return cast<Expr>(Data->getChildren()[UpperBoundVariableOffset]);
1360  }
1366  "expected worksharing loop directive");
1367  return cast<Expr>(Data->getChildren()[StrideVariableOffset]);
1368  }
1374  "expected worksharing loop directive");
1375  return cast<Expr>(Data->getChildren()[EnsureUpperBoundOffset]);
1376  }
1382  "expected worksharing loop directive");
1383  return cast<Expr>(Data->getChildren()[NextLowerBoundOffset]);
1384  }
1390  "expected worksharing loop directive");
1391  return cast<Expr>(Data->getChildren()[NextUpperBoundOffset]);
1392  }
1398  "expected worksharing loop directive");
1399  return cast<Expr>(Data->getChildren()[NumIterationsOffset]);
1400  }
1403  "expected loop bound sharing directive");
1404  return cast<Expr>(Data->getChildren()[PrevLowerBoundVariableOffset]);
1405  }
1408  "expected loop bound sharing directive");
1409  return cast<Expr>(Data->getChildren()[PrevUpperBoundVariableOffset]);
1410  }
1411  Expr *getDistInc() const {
1413  "expected loop bound sharing directive");
1414  return cast<Expr>(Data->getChildren()[DistIncOffset]);
1415  }
1418  "expected loop bound sharing directive");
1419  return cast<Expr>(Data->getChildren()[PrevEnsureUpperBoundOffset]);
1420  }
1423  "expected loop bound sharing directive");
1424  return cast<Expr>(Data->getChildren()[CombinedLowerBoundVariableOffset]);
1425  }
1428  "expected loop bound sharing directive");
1429  return cast<Expr>(Data->getChildren()[CombinedUpperBoundVariableOffset]);
1430  }
1433  "expected loop bound sharing directive");
1434  return cast<Expr>(Data->getChildren()[CombinedEnsureUpperBoundOffset]);
1435  }
1438  "expected loop bound sharing directive");
1439  return cast<Expr>(Data->getChildren()[CombinedInitOffset]);
1440  }
1443  "expected loop bound sharing directive");
1444  return cast<Expr>(Data->getChildren()[CombinedConditionOffset]);
1445  }
1448  "expected loop bound sharing directive");
1449  return cast<Expr>(Data->getChildren()[CombinedNextLowerBoundOffset]);
1450  }
1453  "expected loop bound sharing directive");
1454  return cast<Expr>(Data->getChildren()[CombinedNextUpperBoundOffset]);
1455  }
1458  "expected loop bound distribute sharing directive");
1459  return cast<Expr>(Data->getChildren()[CombinedDistConditionOffset]);
1460  }
1463  "expected loop bound distribute sharing directive");
1464  return cast<Expr>(Data->getChildren()[CombinedParForInDistConditionOffset]);
1465  }
1466  Stmt *getBody();
1467  const Stmt *getBody() const {
1468  return const_cast<OMPLoopDirective *>(this)->getBody();
1469  }
1470 
1471  ArrayRef<Expr *> counters() { return getCounters(); }
1472 
1474  return const_cast<OMPLoopDirective *>(this)->getCounters();
1475  }
1476 
1477  ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
1478 
1480  return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
1481  }
1482 
1483  ArrayRef<Expr *> inits() { return getInits(); }
1484 
1486  return const_cast<OMPLoopDirective *>(this)->getInits();
1487  }
1488 
1489  ArrayRef<Expr *> updates() { return getUpdates(); }
1490 
1492  return const_cast<OMPLoopDirective *>(this)->getUpdates();
1493  }
1494 
1495  ArrayRef<Expr *> finals() { return getFinals(); }
1496 
1498  return const_cast<OMPLoopDirective *>(this)->getFinals();
1499  }
1500 
1501  ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); }
1502 
1504  return const_cast<OMPLoopDirective *>(this)->getDependentCounters();
1505  }
1506 
1507  ArrayRef<Expr *> dependent_inits() { return getDependentInits(); }
1508 
1510  return const_cast<OMPLoopDirective *>(this)->getDependentInits();
1511  }
1512 
1513  ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); }
1514 
1516  return const_cast<OMPLoopDirective *>(this)->getFinalsConditions();
1517  }
1518 
1519  static bool classof(const Stmt *T) {
1520  return T->getStmtClass() == OMPSimdDirectiveClass ||
1521  T->getStmtClass() == OMPForDirectiveClass ||
1522  T->getStmtClass() == OMPForSimdDirectiveClass ||
1523  T->getStmtClass() == OMPParallelForDirectiveClass ||
1524  T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
1525  T->getStmtClass() == OMPTaskLoopDirectiveClass ||
1526  T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
1527  T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass ||
1528  T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass ||
1529  T->getStmtClass() == OMPMasterTaskLoopDirectiveClass ||
1530  T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass ||
1531  T->getStmtClass() == OMPGenericLoopDirectiveClass ||
1532  T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass ||
1533  T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass ||
1534  T->getStmtClass() == OMPParallelGenericLoopDirectiveClass ||
1535  T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass ||
1536  T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass ||
1537  T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass ||
1538  T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass ||
1539  T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass ||
1540  T->getStmtClass() == OMPDistributeDirectiveClass ||
1541  T->getStmtClass() == OMPTargetParallelForDirectiveClass ||
1542  T->getStmtClass() == OMPDistributeParallelForDirectiveClass ||
1543  T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass ||
1544  T->getStmtClass() == OMPDistributeSimdDirectiveClass ||
1545  T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass ||
1546  T->getStmtClass() == OMPTargetSimdDirectiveClass ||
1547  T->getStmtClass() == OMPTeamsDistributeDirectiveClass ||
1548  T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass ||
1549  T->getStmtClass() ==
1550  OMPTeamsDistributeParallelForSimdDirectiveClass ||
1551  T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass ||
1552  T->getStmtClass() ==
1553  OMPTargetTeamsDistributeParallelForDirectiveClass ||
1554  T->getStmtClass() ==
1555  OMPTargetTeamsDistributeParallelForSimdDirectiveClass ||
1556  T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass ||
1557  T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
1558  }
1559 };
1560 
1561 /// This represents '#pragma omp simd' directive.
1562 ///
1563 /// \code
1564 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
1565 /// \endcode
1566 /// In this example directive '#pragma omp simd' has clauses 'private'
1567 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
1568 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
1569 ///
1571  friend class ASTStmtReader;
1573  /// Build directive with the given start and end location.
1574  ///
1575  /// \param StartLoc Starting location of the directive kind.
1576  /// \param EndLoc Ending location of the directive.
1577  /// \param CollapsedNum Number of collapsed nested loops.
1578  ///
1580  unsigned CollapsedNum)
1581  : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, StartLoc,
1582  EndLoc, CollapsedNum) {}
1583 
1584  /// Build an empty directive.
1585  ///
1586  /// \param CollapsedNum Number of collapsed nested loops.
1587  ///
1588  explicit OMPSimdDirective(unsigned CollapsedNum)
1589  : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd,
1590  SourceLocation(), SourceLocation(), CollapsedNum) {}
1591 
1592 public:
1593  /// Creates directive with a list of \a Clauses.
1594  ///
1595  /// \param C AST context.
1596  /// \param StartLoc Starting location of the directive kind.
1597  /// \param EndLoc Ending Location of the directive.
1598  /// \param CollapsedNum Number of collapsed loops.
1599  /// \param Clauses List of clauses.
1600  /// \param AssociatedStmt Statement, associated with the directive.
1601  /// \param Exprs Helper expressions for CodeGen.
1602  ///
1603  static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1604  SourceLocation EndLoc, unsigned CollapsedNum,
1605  ArrayRef<OMPClause *> Clauses,
1606  Stmt *AssociatedStmt,
1607  const HelperExprs &Exprs);
1608 
1609  /// Creates an empty directive with the place
1610  /// for \a NumClauses clauses.
1611  ///
1612  /// \param C AST context.
1613  /// \param CollapsedNum Number of collapsed nested loops.
1614  /// \param NumClauses Number of clauses.
1615  ///
1616  static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1617  unsigned CollapsedNum, EmptyShell);
1618 
1619  static bool classof(const Stmt *T) {
1620  return T->getStmtClass() == OMPSimdDirectiveClass;
1621  }
1622 };
1623 
1624 /// This represents '#pragma omp for' directive.
1625 ///
1626 /// \code
1627 /// #pragma omp for private(a,b) reduction(+:c,d)
1628 /// \endcode
1629 /// In this example directive '#pragma omp for' has clauses 'private' with the
1630 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
1631 /// and 'd'.
1632 ///
1634  friend class ASTStmtReader;
1636  /// true if current directive has inner cancel directive.
1637  bool HasCancel = false;
1638 
1639  /// Build directive with the given start and end location.
1640  ///
1641  /// \param StartLoc Starting location of the directive kind.
1642  /// \param EndLoc Ending location of the directive.
1643  /// \param CollapsedNum Number of collapsed nested loops.
1644  ///
1646  unsigned CollapsedNum)
1647  : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, StartLoc,
1648  EndLoc, CollapsedNum) {}
1649 
1650  /// Build an empty directive.
1651  ///
1652  /// \param CollapsedNum Number of collapsed nested loops.
1653  ///
1654  explicit OMPForDirective(unsigned CollapsedNum)
1655  : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for,
1656  SourceLocation(), SourceLocation(), CollapsedNum) {}
1657 
1658  /// Sets special task reduction descriptor.
1659  void setTaskReductionRefExpr(Expr *E) {
1661  llvm::omp::OMPD_for)] = E;
1662  }
1663 
1664  /// Set cancel state.
1665  void setHasCancel(bool Has) { HasCancel = Has; }
1666 
1667 public:
1668  /// Creates directive with a list of \a Clauses.
1669  ///
1670  /// \param C AST context.
1671  /// \param StartLoc Starting location of the directive kind.
1672  /// \param EndLoc Ending Location of the directive.
1673  /// \param CollapsedNum Number of collapsed loops.
1674  /// \param Clauses List of clauses.
1675  /// \param AssociatedStmt Statement, associated with the directive.
1676  /// \param Exprs Helper expressions for CodeGen.
1677  /// \param TaskRedRef Task reduction special reference expression to handle
1678  /// taskgroup descriptor.
1679  /// \param HasCancel true if current directive has inner cancel directive.
1680  ///
1681  static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1682  SourceLocation EndLoc, unsigned CollapsedNum,
1683  ArrayRef<OMPClause *> Clauses,
1684  Stmt *AssociatedStmt, const HelperExprs &Exprs,
1685  Expr *TaskRedRef, bool HasCancel);
1686 
1687  /// Creates an empty directive with the place
1688  /// for \a NumClauses clauses.
1689  ///
1690  /// \param C AST context.
1691  /// \param CollapsedNum Number of collapsed nested loops.
1692  /// \param NumClauses Number of clauses.
1693  ///
1694  static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1695  unsigned CollapsedNum, EmptyShell);
1696 
1697  /// Returns special task reduction reference expression.
1699  return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
1700  getLoopsNumber(), llvm::omp::OMPD_for)]);
1701  }
1703  return const_cast<OMPForDirective *>(this)->getTaskReductionRefExpr();
1704  }
1705 
1706  /// Return true if current directive has inner cancel directive.
1707  bool hasCancel() const { return HasCancel; }
1708 
1709  static bool classof(const Stmt *T) {
1710  return T->getStmtClass() == OMPForDirectiveClass;
1711  }
1712 };
1713 
1714 /// This represents '#pragma omp for simd' directive.
1715 ///
1716 /// \code
1717 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
1718 /// \endcode
1719 /// In this example directive '#pragma omp for simd' has clauses 'private'
1720 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
1721 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
1722 ///
1724  friend class ASTStmtReader;
1726  /// Build directive with the given start and end location.
1727  ///
1728  /// \param StartLoc Starting location of the directive kind.
1729  /// \param EndLoc Ending location of the directive.
1730  /// \param CollapsedNum Number of collapsed nested loops.
1731  ///
1733  unsigned CollapsedNum)
1734  : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
1735  StartLoc, EndLoc, CollapsedNum) {}
1736 
1737  /// Build an empty directive.
1738  ///
1739  /// \param CollapsedNum Number of collapsed nested loops.
1740  ///
1741  explicit OMPForSimdDirective(unsigned CollapsedNum)
1742  : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
1743  SourceLocation(), SourceLocation(), CollapsedNum) {}
1744 
1745 public:
1746  /// Creates directive with a list of \a Clauses.
1747  ///
1748  /// \param C AST context.
1749  /// \param StartLoc Starting location of the directive kind.
1750  /// \param EndLoc Ending Location of the directive.
1751  /// \param CollapsedNum Number of collapsed loops.
1752  /// \param Clauses List of clauses.
1753  /// \param AssociatedStmt Statement, associated with the directive.
1754  /// \param Exprs Helper expressions for CodeGen.
1755  ///
1756  static OMPForSimdDirective *
1757  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1758  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1759  Stmt *AssociatedStmt, const HelperExprs &Exprs);
1760 
1761  /// Creates an empty directive with the place
1762  /// for \a NumClauses clauses.
1763  ///
1764  /// \param C AST context.
1765  /// \param CollapsedNum Number of collapsed nested loops.
1766  /// \param NumClauses Number of clauses.
1767  ///
1768  static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
1769  unsigned NumClauses,
1770  unsigned CollapsedNum, EmptyShell);
1771 
1772  static bool classof(const Stmt *T) {
1773  return T->getStmtClass() == OMPForSimdDirectiveClass;
1774  }
1775 };
1776 
1777 /// This represents '#pragma omp sections' directive.
1778 ///
1779 /// \code
1780 /// #pragma omp sections private(a,b) reduction(+:c,d)
1781 /// \endcode
1782 /// In this example directive '#pragma omp sections' has clauses 'private' with
1783 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
1784 /// 'c' and 'd'.
1785 ///
1787  friend class ASTStmtReader;
1789 
1790  /// true if current directive has inner cancel directive.
1791  bool HasCancel = false;
1792 
1793  /// Build directive with the given start and end location.
1794  ///
1795  /// \param StartLoc Starting location of the directive kind.
1796  /// \param EndLoc Ending location of the directive.
1797  ///
1799  : OMPExecutableDirective(OMPSectionsDirectiveClass,
1800  llvm::omp::OMPD_sections, StartLoc, EndLoc) {}
1801 
1802  /// Build an empty directive.
1803  ///
1804  explicit OMPSectionsDirective()
1805  : OMPExecutableDirective(OMPSectionsDirectiveClass,
1806  llvm::omp::OMPD_sections, SourceLocation(),
1807  SourceLocation()) {}
1808 
1809  /// Sets special task reduction descriptor.
1810  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
1811 
1812  /// Set cancel state.
1813  void setHasCancel(bool Has) { HasCancel = Has; }
1814 
1815 public:
1816  /// Creates directive with a list of \a Clauses.
1817  ///
1818  /// \param C AST context.
1819  /// \param StartLoc Starting location of the directive kind.
1820  /// \param EndLoc Ending Location of the directive.
1821  /// \param Clauses List of clauses.
1822  /// \param AssociatedStmt Statement, associated with the directive.
1823  /// \param TaskRedRef Task reduction special reference expression to handle
1824  /// taskgroup descriptor.
1825  /// \param HasCancel true if current directive has inner directive.
1826  ///
1827  static OMPSectionsDirective *
1828  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1829  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
1830  bool HasCancel);
1831 
1832  /// Creates an empty directive with the place for \a NumClauses
1833  /// clauses.
1834  ///
1835  /// \param C AST context.
1836  /// \param NumClauses Number of clauses.
1837  ///
1838  static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
1839  unsigned NumClauses, EmptyShell);
1840 
1841  /// Returns special task reduction reference expression.
1843  return cast_or_null<Expr>(Data->getChildren()[0]);
1844  }
1846  return const_cast<OMPSectionsDirective *>(this)->getTaskReductionRefExpr();
1847  }
1848 
1849  /// Return true if current directive has inner cancel directive.
1850  bool hasCancel() const { return HasCancel; }
1851 
1852  static bool classof(const Stmt *T) {
1853  return T->getStmtClass() == OMPSectionsDirectiveClass;
1854  }
1855 };
1856 
1857 /// This represents '#pragma omp section' directive.
1858 ///
1859 /// \code
1860 /// #pragma omp section
1861 /// \endcode
1862 ///
1864  friend class ASTStmtReader;
1866 
1867  /// true if current directive has inner cancel directive.
1868  bool HasCancel = false;
1869 
1870  /// Build directive with the given start and end location.
1871  ///
1872  /// \param StartLoc Starting location of the directive kind.
1873  /// \param EndLoc Ending location of the directive.
1874  ///
1876  : OMPExecutableDirective(OMPSectionDirectiveClass,
1877  llvm::omp::OMPD_section, StartLoc, EndLoc) {}
1878 
1879  /// Build an empty directive.
1880  ///
1881  explicit OMPSectionDirective()
1882  : OMPExecutableDirective(OMPSectionDirectiveClass,
1883  llvm::omp::OMPD_section, SourceLocation(),
1884  SourceLocation()) {}
1885 
1886 public:
1887  /// Creates directive.
1888  ///
1889  /// \param C AST context.
1890  /// \param StartLoc Starting location of the directive kind.
1891  /// \param EndLoc Ending Location of the directive.
1892  /// \param AssociatedStmt Statement, associated with the directive.
1893  /// \param HasCancel true if current directive has inner directive.
1894  ///
1895  static OMPSectionDirective *Create(const ASTContext &C,
1896  SourceLocation StartLoc,
1897  SourceLocation EndLoc,
1898  Stmt *AssociatedStmt, bool HasCancel);
1899 
1900  /// Creates an empty directive.
1901  ///
1902  /// \param C AST context.
1903  ///
1904  static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1905 
1906  /// Set cancel state.
1907  void setHasCancel(bool Has) { HasCancel = Has; }
1908 
1909  /// Return true if current directive has inner cancel directive.
1910  bool hasCancel() const { return HasCancel; }
1911 
1912  static bool classof(const Stmt *T) {
1913  return T->getStmtClass() == OMPSectionDirectiveClass;
1914  }
1915 };
1916 
1917 /// This represents '#pragma omp single' directive.
1918 ///
1919 /// \code
1920 /// #pragma omp single private(a,b) copyprivate(c,d)
1921 /// \endcode
1922 /// In this example directive '#pragma omp single' has clauses 'private' with
1923 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
1924 ///
1926  friend class ASTStmtReader;
1928  /// Build directive with the given start and end location.
1929  ///
1930  /// \param StartLoc Starting location of the directive kind.
1931  /// \param EndLoc Ending location of the directive.
1932  ///
1934  : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
1935  StartLoc, EndLoc) {}
1936 
1937  /// Build an empty directive.
1938  ///
1939  explicit OMPSingleDirective()
1940  : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
1942 
1943 public:
1944  /// Creates directive with a list of \a Clauses.
1945  ///
1946  /// \param C AST context.
1947  /// \param StartLoc Starting location of the directive kind.
1948  /// \param EndLoc Ending Location of the directive.
1949  /// \param Clauses List of clauses.
1950  /// \param AssociatedStmt Statement, associated with the directive.
1951  ///
1952  static OMPSingleDirective *
1953  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1954  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1955 
1956  /// Creates an empty directive with the place for \a NumClauses
1957  /// clauses.
1958  ///
1959  /// \param C AST context.
1960  /// \param NumClauses Number of clauses.
1961  ///
1962  static OMPSingleDirective *CreateEmpty(const ASTContext &C,
1963  unsigned NumClauses, EmptyShell);
1964 
1965  static bool classof(const Stmt *T) {
1966  return T->getStmtClass() == OMPSingleDirectiveClass;
1967  }
1968 };
1969 
1970 /// This represents '#pragma omp master' directive.
1971 ///
1972 /// \code
1973 /// #pragma omp master
1974 /// \endcode
1975 ///
1977  friend class ASTStmtReader;
1979  /// Build directive with the given start and end location.
1980  ///
1981  /// \param StartLoc Starting location of the directive kind.
1982  /// \param EndLoc Ending location of the directive.
1983  ///
1985  : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
1986  StartLoc, EndLoc) {}
1987 
1988  /// Build an empty directive.
1989  ///
1990  explicit OMPMasterDirective()
1991  : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
1993 
1994 public:
1995  /// Creates directive.
1996  ///
1997  /// \param C AST context.
1998  /// \param StartLoc Starting location of the directive kind.
1999  /// \param EndLoc Ending Location of the directive.
2000  /// \param AssociatedStmt Statement, associated with the directive.
2001  ///
2002  static OMPMasterDirective *Create(const ASTContext &C,
2003  SourceLocation StartLoc,
2004  SourceLocation EndLoc,
2005  Stmt *AssociatedStmt);
2006 
2007  /// Creates an empty directive.
2008  ///
2009  /// \param C AST context.
2010  ///
2011  static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2012 
2013  static bool classof(const Stmt *T) {
2014  return T->getStmtClass() == OMPMasterDirectiveClass;
2015  }
2016 };
2017 
2018 /// This represents '#pragma omp critical' directive.
2019 ///
2020 /// \code
2021 /// #pragma omp critical
2022 /// \endcode
2023 ///
2025  friend class ASTStmtReader;
2027  /// Name of the directive.
2028  DeclarationNameInfo DirName;
2029  /// Build directive with the given start and end location.
2030  ///
2031  /// \param Name Name of the directive.
2032  /// \param StartLoc Starting location of the directive kind.
2033  /// \param EndLoc Ending location of the directive.
2034  ///
2036  SourceLocation EndLoc)
2037  : OMPExecutableDirective(OMPCriticalDirectiveClass,
2038  llvm::omp::OMPD_critical, StartLoc, EndLoc),
2039  DirName(Name) {}
2040 
2041  /// Build an empty directive.
2042  ///
2043  explicit OMPCriticalDirective()
2044  : OMPExecutableDirective(OMPCriticalDirectiveClass,
2045  llvm::omp::OMPD_critical, SourceLocation(),
2046  SourceLocation()) {}
2047 
2048  /// Set name of the directive.
2049  ///
2050  /// \param Name Name of the directive.
2051  ///
2052  void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
2053 
2054 public:
2055  /// Creates directive.
2056  ///
2057  /// \param C AST context.
2058  /// \param Name Name of the directive.
2059  /// \param StartLoc Starting location of the directive kind.
2060  /// \param EndLoc Ending Location of the directive.
2061  /// \param Clauses List of clauses.
2062  /// \param AssociatedStmt Statement, associated with the directive.
2063  ///
2064  static OMPCriticalDirective *
2065  Create(const ASTContext &C, const DeclarationNameInfo &Name,
2066  SourceLocation StartLoc, SourceLocation EndLoc,
2067  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2068 
2069  /// Creates an empty directive.
2070  ///
2071  /// \param C AST context.
2072  /// \param NumClauses Number of clauses.
2073  ///
2074  static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
2075  unsigned NumClauses, EmptyShell);
2076 
2077  /// Return name of the directive.
2078  ///
2079  DeclarationNameInfo getDirectiveName() const { return DirName; }
2080 
2081  static bool classof(const Stmt *T) {
2082  return T->getStmtClass() == OMPCriticalDirectiveClass;
2083  }
2084 };
2085 
2086 /// This represents '#pragma omp parallel for' directive.
2087 ///
2088 /// \code
2089 /// #pragma omp parallel for private(a,b) reduction(+:c,d)
2090 /// \endcode
2091 /// In this example directive '#pragma omp parallel for' has clauses 'private'
2092 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
2093 /// variables 'c' and 'd'.
2094 ///
2096  friend class ASTStmtReader;
2098 
2099  /// true if current region has inner cancel directive.
2100  bool HasCancel = false;
2101 
2102  /// Build directive with the given start and end location.
2103  ///
2104  /// \param StartLoc Starting location of the directive kind.
2105  /// \param EndLoc Ending location of the directive.
2106  /// \param CollapsedNum Number of collapsed nested loops.
2107  ///
2109  unsigned CollapsedNum)
2110  : OMPLoopDirective(OMPParallelForDirectiveClass,
2111  llvm::omp::OMPD_parallel_for, StartLoc, EndLoc,
2112  CollapsedNum) {}
2113 
2114  /// Build an empty directive.
2115  ///
2116  /// \param CollapsedNum Number of collapsed nested loops.
2117  ///
2118  explicit OMPParallelForDirective(unsigned CollapsedNum)
2119  : OMPLoopDirective(OMPParallelForDirectiveClass,
2120  llvm::omp::OMPD_parallel_for, SourceLocation(),
2121  SourceLocation(), CollapsedNum) {}
2122 
2123  /// Sets special task reduction descriptor.
2124  void setTaskReductionRefExpr(Expr *E) {
2126  llvm::omp::OMPD_parallel_for)] = E;
2127  }
2128 
2129  /// Set cancel state.
2130  void setHasCancel(bool Has) { HasCancel = Has; }
2131 
2132 public:
2133  /// Creates directive with a list of \a Clauses.
2134  ///
2135  /// \param C AST context.
2136  /// \param StartLoc Starting location of the directive kind.
2137  /// \param EndLoc Ending Location of the directive.
2138  /// \param CollapsedNum Number of collapsed loops.
2139  /// \param Clauses List of clauses.
2140  /// \param AssociatedStmt Statement, associated with the directive.
2141  /// \param Exprs Helper expressions for CodeGen.
2142  /// \param TaskRedRef Task reduction special reference expression to handle
2143  /// taskgroup descriptor.
2144  /// \param HasCancel true if current directive has inner cancel directive.
2145  ///
2146  static OMPParallelForDirective *
2147  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2148  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2149  Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
2150  bool HasCancel);
2151 
2152  /// Creates an empty directive with the place
2153  /// for \a NumClauses clauses.
2154  ///
2155  /// \param C AST context.
2156  /// \param CollapsedNum Number of collapsed nested loops.
2157  /// \param NumClauses Number of clauses.
2158  ///
2159  static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
2160  unsigned NumClauses,
2161  unsigned CollapsedNum,
2162  EmptyShell);
2163 
2164  /// Returns special task reduction reference expression.
2166  return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
2167  getLoopsNumber(), llvm::omp::OMPD_parallel_for)]);
2168  }
2170  return const_cast<OMPParallelForDirective *>(this)
2172  }
2173 
2174  /// Return true if current directive has inner cancel directive.
2175  bool hasCancel() const { return HasCancel; }
2176 
2177  static bool classof(const Stmt *T) {
2178  return T->getStmtClass() == OMPParallelForDirectiveClass;
2179  }
2180 };
2181 
2182 /// This represents '#pragma omp parallel for simd' directive.
2183 ///
2184 /// \code
2185 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
2186 /// \endcode
2187 /// In this example directive '#pragma omp parallel for simd' has clauses
2188 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
2189 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and
2190 /// 'd'.
2191 ///
2193  friend class ASTStmtReader;
2195  /// Build directive with the given start and end location.
2196  ///
2197  /// \param StartLoc Starting location of the directive kind.
2198  /// \param EndLoc Ending location of the directive.
2199  /// \param CollapsedNum Number of collapsed nested loops.
2200  ///
2202  unsigned CollapsedNum)
2203  : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
2204  llvm::omp::OMPD_parallel_for_simd, StartLoc, EndLoc,
2205  CollapsedNum) {}
2206 
2207  /// Build an empty directive.
2208  ///
2209  /// \param CollapsedNum Number of collapsed nested loops.
2210  ///
2211  explicit OMPParallelForSimdDirective(unsigned CollapsedNum)
2212  : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
2213  llvm::omp::OMPD_parallel_for_simd, SourceLocation(),
2214  SourceLocation(), CollapsedNum) {}
2215 
2216 public:
2217  /// Creates directive with a list of \a Clauses.
2218  ///
2219  /// \param C AST context.
2220  /// \param StartLoc Starting location of the directive kind.
2221  /// \param EndLoc Ending Location of the directive.
2222  /// \param CollapsedNum Number of collapsed loops.
2223  /// \param Clauses List of clauses.
2224  /// \param AssociatedStmt Statement, associated with the directive.
2225  /// \param Exprs Helper expressions for CodeGen.
2226  ///
2227  static OMPParallelForSimdDirective *
2228  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2229  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2230  Stmt *AssociatedStmt, const HelperExprs &Exprs);
2231 
2232  /// Creates an empty directive with the place
2233  /// for \a NumClauses clauses.
2234  ///
2235  /// \param C AST context.
2236  /// \param CollapsedNum Number of collapsed nested loops.
2237  /// \param NumClauses Number of clauses.
2238  ///
2239  static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
2240  unsigned NumClauses,
2241  unsigned CollapsedNum,
2242  EmptyShell);
2243 
2244  static bool classof(const Stmt *T) {
2245  return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
2246  }
2247 };
2248 
2249 /// This represents '#pragma omp parallel master' directive.
2250 ///
2251 /// \code
2252 /// #pragma omp parallel master private(a,b)
2253 /// \endcode
2254 /// In this example directive '#pragma omp parallel master' has clauses
2255 /// 'private' with the variables 'a' and 'b'
2256 ///
2258  friend class ASTStmtReader;
2260 
2262  : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
2263  llvm::omp::OMPD_parallel_master, StartLoc,
2264  EndLoc) {}
2265 
2266  explicit OMPParallelMasterDirective()
2267  : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
2268  llvm::omp::OMPD_parallel_master,
2270 
2271  /// Sets special task reduction descriptor.
2272  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2273 
2274 public:
2275  /// Creates directive with a list of \a Clauses.
2276  ///
2277  /// \param C AST context.
2278  /// \param StartLoc Starting location of the directive kind.
2279  /// \param EndLoc Ending Location of the directive.
2280  /// \param Clauses List of clauses.
2281  /// \param AssociatedStmt Statement, associated with the directive.
2282  /// \param TaskRedRef Task reduction special reference expression to handle
2283  /// taskgroup descriptor.
2284  ///
2285  static OMPParallelMasterDirective *
2286  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2287  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
2288 
2289  /// Creates an empty directive with the place for \a NumClauses
2290  /// clauses.
2291  ///
2292  /// \param C AST context.
2293  /// \param NumClauses Number of clauses.
2294  ///
2295  static OMPParallelMasterDirective *
2296  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2297 
2298  /// Returns special task reduction reference expression.
2300  return cast_or_null<Expr>(Data->getChildren()[0]);
2301  }
2303  return const_cast<OMPParallelMasterDirective *>(this)
2305  }
2306 
2307  static bool classof(const Stmt *T) {
2308  return T->getStmtClass() == OMPParallelMasterDirectiveClass;
2309  }
2310 };
2311 
2312 /// This represents '#pragma omp parallel masked' directive.
2313 ///
2314 /// \code
2315 /// #pragma omp parallel masked filter(tid)
2316 /// \endcode
2317 /// In this example directive '#pragma omp parallel masked' has a clause
2318 /// 'filter' with the variable tid
2319 ///
2321  friend class ASTStmtReader;
2323 
2325  : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
2326  llvm::omp::OMPD_parallel_masked, StartLoc,
2327  EndLoc) {}
2328 
2329  explicit OMPParallelMaskedDirective()
2330  : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
2331  llvm::omp::OMPD_parallel_masked,
2333 
2334  /// Sets special task reduction descriptor.
2335  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2336 
2337 public:
2338  /// Creates directive with a list of \a Clauses.
2339  ///
2340  /// \param C AST context.
2341  /// \param StartLoc Starting location of the directive kind.
2342  /// \param EndLoc Ending Location of the directive.
2343  /// \param Clauses List of clauses.
2344  /// \param AssociatedStmt Statement, associated with the directive.
2345  /// \param TaskRedRef Task reduction special reference expression to handle
2346  /// taskgroup descriptor.
2347  ///
2348  static OMPParallelMaskedDirective *
2349  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2350  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
2351 
2352  /// Creates an empty directive with the place for \a NumClauses
2353  /// clauses.
2354  ///
2355  /// \param C AST context.
2356  /// \param NumClauses Number of clauses.
2357  ///
2358  static OMPParallelMaskedDirective *
2359  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2360 
2361  /// Returns special task reduction reference expression.
2363  return cast_or_null<Expr>(Data->getChildren()[0]);
2364  }
2366  return const_cast<OMPParallelMaskedDirective *>(this)
2368  }
2369 
2370  static bool classof(const Stmt *T) {
2371  return T->getStmtClass() == OMPParallelMaskedDirectiveClass;
2372  }
2373 };
2374 
2375 /// This represents '#pragma omp parallel sections' directive.
2376 ///
2377 /// \code
2378 /// #pragma omp parallel sections private(a,b) reduction(+:c,d)
2379 /// \endcode
2380 /// In this example directive '#pragma omp parallel sections' has clauses
2381 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
2382 /// and variables 'c' and 'd'.
2383 ///
2385  friend class ASTStmtReader;
2387 
2388  /// true if current directive has inner cancel directive.
2389  bool HasCancel = false;
2390 
2391  /// Build directive with the given start and end location.
2392  ///
2393  /// \param StartLoc Starting location of the directive kind.
2394  /// \param EndLoc Ending location of the directive.
2395  ///
2397  : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
2398  llvm::omp::OMPD_parallel_sections, StartLoc,
2399  EndLoc) {}
2400 
2401  /// Build an empty directive.
2402  ///
2403  explicit OMPParallelSectionsDirective()
2404  : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
2405  llvm::omp::OMPD_parallel_sections,
2407 
2408  /// Sets special task reduction descriptor.
2409  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2410 
2411  /// Set cancel state.
2412  void setHasCancel(bool Has) { HasCancel = Has; }
2413 
2414 public:
2415  /// Creates directive with a list of \a Clauses.
2416  ///
2417  /// \param C AST context.
2418  /// \param StartLoc Starting location of the directive kind.
2419  /// \param EndLoc Ending Location of the directive.
2420  /// \param Clauses List of clauses.
2421  /// \param AssociatedStmt Statement, associated with the directive.
2422  /// \param TaskRedRef Task reduction special reference expression to handle
2423  /// taskgroup descriptor.
2424  /// \param HasCancel true if current directive has inner cancel directive.
2425  ///
2426  static OMPParallelSectionsDirective *
2427  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2428  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
2429  bool HasCancel);
2430 
2431  /// Creates an empty directive with the place for \a NumClauses
2432  /// clauses.
2433  ///
2434  /// \param C AST context.
2435  /// \param NumClauses Number of clauses.
2436  ///
2437  static OMPParallelSectionsDirective *
2438  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2439 
2440  /// Returns special task reduction reference expression.
2442  return cast_or_null<Expr>(Data->getChildren()[0]);
2443  }
2445  return const_cast<OMPParallelSectionsDirective *>(this)
2447  }
2448 
2449  /// Return true if current directive has inner cancel directive.
2450  bool hasCancel() const { return HasCancel; }
2451 
2452  static bool classof(const Stmt *T) {
2453  return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
2454  }
2455 };
2456 
2457 /// This represents '#pragma omp task' directive.
2458 ///
2459 /// \code
2460 /// #pragma omp task private(a,b) final(d)
2461 /// \endcode
2462 /// In this example directive '#pragma omp task' has clauses 'private' with the
2463 /// variables 'a' and 'b' and 'final' with condition 'd'.
2464 ///
2466  friend class ASTStmtReader;
2468  /// true if this directive has inner cancel directive.
2469  bool HasCancel = false;
2470 
2471  /// Build directive with the given start and end location.
2472  ///
2473  /// \param StartLoc Starting location of the directive kind.
2474  /// \param EndLoc Ending location of the directive.
2475  ///
2477  : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
2478  StartLoc, EndLoc) {}
2479 
2480  /// Build an empty directive.
2481  ///
2482  explicit OMPTaskDirective()
2483  : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
2485 
2486  /// Set cancel state.
2487  void setHasCancel(bool Has) { HasCancel = Has; }
2488 
2489 public:
2490  /// Creates directive with a list of \a Clauses.
2491  ///
2492  /// \param C AST context.
2493  /// \param StartLoc Starting location of the directive kind.
2494  /// \param EndLoc Ending Location of the directive.
2495  /// \param Clauses List of clauses.
2496  /// \param AssociatedStmt Statement, associated with the directive.
2497  /// \param HasCancel true, if current directive has inner cancel directive.
2498  ///
2499  static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2500  SourceLocation EndLoc,
2501  ArrayRef<OMPClause *> Clauses,
2502  Stmt *AssociatedStmt, bool HasCancel);
2503 
2504  /// Creates an empty directive with the place for \a NumClauses
2505  /// clauses.
2506  ///
2507  /// \param C AST context.
2508  /// \param NumClauses Number of clauses.
2509  ///
2510  static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
2511  EmptyShell);
2512 
2513  /// Return true if current directive has inner cancel directive.
2514  bool hasCancel() const { return HasCancel; }
2515 
2516  static bool classof(const Stmt *T) {
2517  return T->getStmtClass() == OMPTaskDirectiveClass;
2518  }
2519 };
2520 
2521 /// This represents '#pragma omp taskyield' directive.
2522 ///
2523 /// \code
2524 /// #pragma omp taskyield
2525 /// \endcode
2526 ///
2528  friend class ASTStmtReader;
2530  /// Build directive with the given start and end location.
2531  ///
2532  /// \param StartLoc Starting location of the directive kind.
2533  /// \param EndLoc Ending location of the directive.
2534  ///
2536  : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
2537  llvm::omp::OMPD_taskyield, StartLoc, EndLoc) {}
2538 
2539  /// Build an empty directive.
2540  ///
2541  explicit OMPTaskyieldDirective()
2542  : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
2543  llvm::omp::OMPD_taskyield, SourceLocation(),
2544  SourceLocation()) {}
2545 
2546 public:
2547  /// Creates directive.
2548  ///
2549  /// \param C AST context.
2550  /// \param StartLoc Starting location of the directive kind.
2551  /// \param EndLoc Ending Location of the directive.
2552  ///
2553  static OMPTaskyieldDirective *
2554  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
2555 
2556  /// Creates an empty directive.
2557  ///
2558  /// \param C AST context.
2559  ///
2560  static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2561 
2562  static bool classof(const Stmt *T) {
2563  return T->getStmtClass() == OMPTaskyieldDirectiveClass;
2564  }
2565 };
2566 
2567 /// This represents '#pragma omp barrier' directive.
2568 ///
2569 /// \code
2570 /// #pragma omp barrier
2571 /// \endcode
2572 ///
2574  friend class ASTStmtReader;
2576  /// Build directive with the given start and end location.
2577  ///
2578  /// \param StartLoc Starting location of the directive kind.
2579  /// \param EndLoc Ending location of the directive.
2580  ///
2582  : OMPExecutableDirective(OMPBarrierDirectiveClass,
2583  llvm::omp::OMPD_barrier, StartLoc, EndLoc) {}
2584 
2585  /// Build an empty directive.
2586  ///
2587  explicit OMPBarrierDirective()
2588  : OMPExecutableDirective(OMPBarrierDirectiveClass,
2589  llvm::omp::OMPD_barrier, SourceLocation(),
2590  SourceLocation()) {}
2591 
2592 public:
2593  /// Creates directive.
2594  ///
2595  /// \param C AST context.
2596  /// \param StartLoc Starting location of the directive kind.
2597  /// \param EndLoc Ending Location of the directive.
2598  ///
2599  static OMPBarrierDirective *
2600  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
2601 
2602  /// Creates an empty directive.
2603  ///
2604  /// \param C AST context.
2605  ///
2606  static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2607 
2608  static bool classof(const Stmt *T) {
2609  return T->getStmtClass() == OMPBarrierDirectiveClass;
2610  }
2611 };
2612 
2613 /// This represents '#pragma omp taskwait' directive.
2614 ///
2615 /// \code
2616 /// #pragma omp taskwait
2617 /// \endcode
2618 ///
2620  friend class ASTStmtReader;
2622  /// Build directive with the given start and end location.
2623  ///
2624  /// \param StartLoc Starting location of the directive kind.
2625  /// \param EndLoc Ending location of the directive.
2626  ///
2628  : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
2629  llvm::omp::OMPD_taskwait, StartLoc, EndLoc) {}
2630 
2631  /// Build an empty directive.
2632  ///
2633  explicit OMPTaskwaitDirective()
2634  : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
2635  llvm::omp::OMPD_taskwait, SourceLocation(),
2636  SourceLocation()) {}
2637 
2638 public:
2639  /// Creates directive.
2640  ///
2641  /// \param C AST context.
2642  /// \param StartLoc Starting location of the directive kind.
2643  /// \param EndLoc Ending Location of the directive.
2644  /// \param Clauses List of clauses.
2645  ///
2646  static OMPTaskwaitDirective *Create(const ASTContext &C,
2647  SourceLocation StartLoc,
2648  SourceLocation EndLoc,
2649  ArrayRef<OMPClause *> Clauses);
2650 
2651  /// Creates an empty directive.
2652  ///
2653  /// \param C AST context.
2654  /// \param NumClauses Number of clauses.
2655  ///
2656  static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C,
2657  unsigned NumClauses, EmptyShell);
2658 
2659  static bool classof(const Stmt *T) {
2660  return T->getStmtClass() == OMPTaskwaitDirectiveClass;
2661  }
2662 };
2663 
2664 /// This represents '#pragma omp taskgroup' directive.
2665 ///
2666 /// \code
2667 /// #pragma omp taskgroup
2668 /// \endcode
2669 ///
2671  friend class ASTStmtReader;
2673  /// Build directive with the given start and end location.
2674  ///
2675  /// \param StartLoc Starting location of the directive kind.
2676  /// \param EndLoc Ending location of the directive.
2677  ///
2679  : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
2680  llvm::omp::OMPD_taskgroup, StartLoc, EndLoc) {}
2681 
2682  /// Build an empty directive.
2683  ///
2684  explicit OMPTaskgroupDirective()
2685  : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
2686  llvm::omp::OMPD_taskgroup, SourceLocation(),
2687  SourceLocation()) {}
2688 
2689  /// Sets the task_reduction return variable.
2690  void setReductionRef(Expr *RR) { Data->getChildren()[0] = RR; }
2691 
2692 public:
2693  /// Creates directive.
2694  ///
2695  /// \param C AST context.
2696  /// \param StartLoc Starting location of the directive kind.
2697  /// \param EndLoc Ending Location of the directive.
2698  /// \param Clauses List of clauses.
2699  /// \param AssociatedStmt Statement, associated with the directive.
2700  /// \param ReductionRef Reference to the task_reduction return variable.
2701  ///
2702  static OMPTaskgroupDirective *
2703  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2704  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
2705  Expr *ReductionRef);
2706 
2707  /// Creates an empty directive.
2708  ///
2709  /// \param C AST context.
2710  /// \param NumClauses Number of clauses.
2711  ///
2712  static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C,
2713  unsigned NumClauses, EmptyShell);
2714 
2715 
2716  /// Returns reference to the task_reduction return variable.
2717  const Expr *getReductionRef() const {
2718  return const_cast<OMPTaskgroupDirective *>(this)->getReductionRef();
2719  }
2720  Expr *getReductionRef() { return cast_or_null<Expr>(Data->getChildren()[0]); }
2721 
2722  static bool classof(const Stmt *T) {
2723  return T->getStmtClass() == OMPTaskgroupDirectiveClass;
2724  }
2725 };
2726 
2727 /// This represents '#pragma omp flush' directive.
2728 ///
2729 /// \code
2730 /// #pragma omp flush(a,b)
2731 /// \endcode
2732 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
2733 /// and 'b'.
2734 /// 'omp flush' directive does not have clauses but have an optional list of
2735 /// variables to flush. This list of variables is stored within some fake clause
2736 /// FlushClause.
2738  friend class ASTStmtReader;
2740  /// Build directive with the given start and end location.
2741  ///
2742  /// \param StartLoc Starting location of the directive kind.
2743  /// \param EndLoc Ending location of the directive.
2744  ///
2746  : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
2747  StartLoc, EndLoc) {}
2748 
2749  /// Build an empty directive.
2750  ///
2751  explicit OMPFlushDirective()
2752  : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
2754 
2755 public:
2756  /// Creates directive with a list of \a Clauses.
2757  ///
2758  /// \param C AST context.
2759  /// \param StartLoc Starting location of the directive kind.
2760  /// \param EndLoc Ending Location of the directive.
2761  /// \param Clauses List of clauses (only single OMPFlushClause clause is
2762  /// allowed).
2763  ///
2764  static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2765  SourceLocation EndLoc,
2766  ArrayRef<OMPClause *> Clauses);
2767 
2768  /// Creates an empty directive with the place for \a NumClauses
2769  /// clauses.
2770  ///
2771  /// \param C AST context.
2772  /// \param NumClauses Number of clauses.
2773  ///
2774  static OMPFlushDirective *CreateEmpty(const ASTContext &C,
2775  unsigned NumClauses, EmptyShell);
2776 
2777  static bool classof(const Stmt *T) {
2778  return T->getStmtClass() == OMPFlushDirectiveClass;
2779  }
2780 };
2781 
2782 /// This represents '#pragma omp depobj' directive.
2783 ///
2784 /// \code
2785 /// #pragma omp depobj(a) depend(in:x,y)
2786 /// \endcode
2787 /// In this example directive '#pragma omp depobj' initializes a depobj object
2788 /// 'a' with dependence type 'in' and a list with 'x' and 'y' locators.
2790  friend class ASTStmtReader;
2792 
2793  /// Build directive with the given start and end location.
2794  ///
2795  /// \param StartLoc Starting location of the directive kind.
2796  /// \param EndLoc Ending location of the directive.
2797  ///
2799  : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
2800  StartLoc, EndLoc) {}
2801 
2802  /// Build an empty directive.
2803  ///
2804  explicit OMPDepobjDirective()
2805  : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
2807 
2808 public:
2809  /// Creates directive with a list of \a Clauses.
2810  ///
2811  /// \param C AST context.
2812  /// \param StartLoc Starting location of the directive kind.
2813  /// \param EndLoc Ending Location of the directive.
2814  /// \param Clauses List of clauses.
2815  ///
2816  static OMPDepobjDirective *Create(const ASTContext &C,
2817  SourceLocation StartLoc,
2818  SourceLocation EndLoc,
2819  ArrayRef<OMPClause *> Clauses);
2820 
2821  /// Creates an empty directive with the place for \a NumClauses
2822  /// clauses.
2823  ///
2824  /// \param C AST context.
2825  /// \param NumClauses Number of clauses.
2826  ///
2827  static OMPDepobjDirective *CreateEmpty(const ASTContext &C,
2828  unsigned NumClauses, EmptyShell);
2829 
2830  static bool classof(const Stmt *T) {
2831  return T->getStmtClass() == OMPDepobjDirectiveClass;
2832  }
2833 };
2834 
2835 /// This represents '#pragma omp ordered' directive.
2836 ///
2837 /// \code
2838 /// #pragma omp ordered
2839 /// \endcode
2840 ///
2842  friend class ASTStmtReader;
2844  /// Build directive with the given start and end location.
2845  ///
2846  /// \param StartLoc Starting location of the directive kind.
2847  /// \param EndLoc Ending location of the directive.
2848  ///
2850  : OMPExecutableDirective(OMPOrderedDirectiveClass,
2851  llvm::omp::OMPD_ordered, StartLoc, EndLoc) {}
2852 
2853  /// Build an empty directive.
2854  ///
2855  explicit OMPOrderedDirective()
2856  : OMPExecutableDirective(OMPOrderedDirectiveClass,
2857  llvm::omp::OMPD_ordered, SourceLocation(),
2858  SourceLocation()) {}
2859 
2860 public:
2861  /// Creates directive.
2862  ///
2863  /// \param C AST context.
2864  /// \param StartLoc Starting location of the directive kind.
2865  /// \param EndLoc Ending Location of the directive.
2866  /// \param Clauses List of clauses.
2867  /// \param AssociatedStmt Statement, associated with the directive.
2868  ///
2869  static OMPOrderedDirective *
2870  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2871  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2872 
2873  /// Creates an empty directive.
2874  ///
2875  /// \param C AST context.
2876  /// \param NumClauses Number of clauses.
2877  /// \param IsStandalone true, if the standalone directive is created.
2878  ///
2879  static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
2880  unsigned NumClauses,
2881  bool IsStandalone, EmptyShell);
2882 
2883  static bool classof(const Stmt *T) {
2884  return T->getStmtClass() == OMPOrderedDirectiveClass;
2885  }
2886 };
2887 
2888 /// This represents '#pragma omp atomic' directive.
2889 ///
2890 /// \code
2891 /// #pragma omp atomic capture
2892 /// \endcode
2893 /// In this example directive '#pragma omp atomic' has clause 'capture'.
2894 ///
2896  friend class ASTStmtReader;
2898 
2899  struct FlagTy {
2900  /// Used for 'atomic update' or 'atomic capture' constructs. They may
2901  /// have atomic expressions of forms:
2902  /// \code
2903  /// x = x binop expr;
2904  /// x = expr binop x;
2905  /// \endcode
2906  /// This field is 1 for the first form of the expression and 0 for the
2907  /// second. Required for correct codegen of non-associative operations (like
2908  /// << or >>).
2909  uint8_t IsXLHSInRHSPart : 1;
2910  /// Used for 'atomic update' or 'atomic capture' constructs. They may
2911  /// have atomic expressions of forms:
2912  /// \code
2913  /// v = x; <update x>;
2914  /// <update x>; v = x;
2915  /// \endcode
2916  /// This field is 1 for the first(postfix) form of the expression and 0
2917  /// otherwise.
2918  uint8_t IsPostfixUpdate : 1;
2919  /// 1 if 'v' is updated only when the condition is false (compare capture
2920  /// only).
2921  uint8_t IsFailOnly : 1;
2922  } Flags;
2923 
2924  /// Build directive with the given start and end location.
2925  ///
2926  /// \param StartLoc Starting location of the directive kind.
2927  /// \param EndLoc Ending location of the directive.
2928  ///
2930  : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
2931  StartLoc, EndLoc) {}
2932 
2933  /// Build an empty directive.
2934  ///
2935  explicit OMPAtomicDirective()
2936  : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
2937  SourceLocation(), SourceLocation()) {}
2938 
2939  enum DataPositionTy : size_t {
2940  POS_X = 0,
2941  POS_V,
2942  POS_E,
2943  POS_UpdateExpr,
2944  POS_D,
2945  POS_Cond,
2946  POS_R,
2947  };
2948 
2949  /// Set 'x' part of the associated expression/statement.
2950  void setX(Expr *X) { Data->getChildren()[DataPositionTy::POS_X] = X; }
2951  /// Set helper expression of the form
2952  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
2953  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2954  void setUpdateExpr(Expr *UE) {
2955  Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE;
2956  }
2957  /// Set 'v' part of the associated expression/statement.
2958  void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; }
2959  /// Set 'r' part of the associated expression/statement.
2960  void setR(Expr *R) { Data->getChildren()[DataPositionTy::POS_R] = R; }
2961  /// Set 'expr' part of the associated expression/statement.
2962  void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; }
2963  /// Set 'd' part of the associated expression/statement.
2964  void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; }
2965  /// Set conditional expression in `atomic compare`.
2966  void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; }
2967 
2968 public:
2969  struct Expressions {
2970  /// 'x' part of the associated expression/statement.
2971  Expr *X = nullptr;
2972  /// 'v' part of the associated expression/statement.
2973  Expr *V = nullptr;
2974  // 'r' part of the associated expression/statement.
2975  Expr *R = nullptr;
2976  /// 'expr' part of the associated expression/statement.
2977  Expr *E = nullptr;
2978  /// UE Helper expression of the form:
2979  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
2980  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2981  Expr *UE = nullptr;
2982  /// 'd' part of the associated expression/statement.
2983  Expr *D = nullptr;
2984  /// Conditional expression in `atomic compare` construct.
2985  Expr *Cond = nullptr;
2986  /// True if UE has the first form and false if the second.
2988  /// True if original value of 'x' must be stored in 'v', not an updated one.
2990  /// True if 'v' is updated only when the condition is false (compare capture
2991  /// only).
2993  };
2994 
2995  /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
2996  /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
2997  /// detailed description of 'x', 'v' and 'expr').
2998  ///
2999  /// \param C AST context.
3000  /// \param StartLoc Starting location of the directive kind.
3001  /// \param EndLoc Ending Location of the directive.
3002  /// \param Clauses List of clauses.
3003  /// \param AssociatedStmt Statement, associated with the directive.
3004  /// \param Exprs Associated expressions or statements.
3005  static OMPAtomicDirective *Create(const ASTContext &C,
3006  SourceLocation StartLoc,
3007  SourceLocation EndLoc,
3008  ArrayRef<OMPClause *> Clauses,
3009  Stmt *AssociatedStmt, Expressions Exprs);
3010 
3011  /// Creates an empty directive with the place for \a NumClauses
3012  /// clauses.
3013  ///
3014  /// \param C AST context.
3015  /// \param NumClauses Number of clauses.
3016  ///
3017  static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
3018  unsigned NumClauses, EmptyShell);
3019 
3020  /// Get 'x' part of the associated expression/statement.
3021  Expr *getX() {
3022  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
3023  }
3024  const Expr *getX() const {
3025  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
3026  }
3027  /// Get helper expression of the form
3028  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
3029  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3031  return cast_or_null<Expr>(
3032  Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
3033  }
3034  const Expr *getUpdateExpr() const {
3035  return cast_or_null<Expr>(
3036  Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
3037  }
3038  /// Return true if helper update expression has form
3039  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
3040  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3041  bool isXLHSInRHSPart() const { return Flags.IsXLHSInRHSPart; }
3042  /// Return true if 'v' expression must be updated to original value of
3043  /// 'x', false if 'v' must be updated to the new value of 'x'.
3044  bool isPostfixUpdate() const { return Flags.IsPostfixUpdate; }
3045  /// Return true if 'v' is updated only when the condition is evaluated false
3046  /// (compare capture only).
3047  bool isFailOnly() const { return Flags.IsFailOnly; }
3048  /// Get 'v' part of the associated expression/statement.
3049  Expr *getV() {
3050  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
3051  }
3052  const Expr *getV() const {
3053  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
3054  }
3055  /// Get 'r' part of the associated expression/statement.
3056  Expr *getR() {
3057  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
3058  }
3059  const Expr *getR() const {
3060  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
3061  }
3062  /// Get 'expr' part of the associated expression/statement.
3064  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
3065  }
3066  const Expr *getExpr() const {
3067  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
3068  }
3069  /// Get 'd' part of the associated expression/statement.
3070  Expr *getD() {
3071  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
3072  }
3073  Expr *getD() const {
3074  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
3075  }
3076  /// Get the 'cond' part of the source atomic expression.
3078  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
3079  }
3080  Expr *getCondExpr() const {
3081  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
3082  }
3083 
3084  static bool classof(const Stmt *T) {
3085  return T->getStmtClass() == OMPAtomicDirectiveClass;
3086  }
3087 };
3088 
3089 /// This represents '#pragma omp target' directive.
3090 ///
3091 /// \code
3092 /// #pragma omp target if(a)
3093 /// \endcode
3094 /// In this example directive '#pragma omp target' has clause 'if' with
3095 /// condition 'a'.
3096 ///
3098  friend class ASTStmtReader;
3100  /// Build directive with the given start and end location.
3101  ///
3102  /// \param StartLoc Starting location of the directive kind.
3103  /// \param EndLoc Ending location of the directive.
3104  ///
3106  : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
3107  StartLoc, EndLoc) {}
3108 
3109  /// Build an empty directive.
3110  ///
3111  explicit OMPTargetDirective()
3112  : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
3114 
3115 public:
3116  /// Creates directive with a list of \a Clauses.
3117  ///
3118  /// \param C AST context.
3119  /// \param StartLoc Starting location of the directive kind.
3120  /// \param EndLoc Ending Location of the directive.
3121  /// \param Clauses List of clauses.
3122  /// \param AssociatedStmt Statement, associated with the directive.
3123  ///
3124  static OMPTargetDirective *
3125  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3126  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3127 
3128  /// Creates an empty directive with the place for \a NumClauses
3129  /// clauses.
3130  ///
3131  /// \param C AST context.
3132  /// \param NumClauses Number of clauses.
3133  ///
3134  static OMPTargetDirective *CreateEmpty(const ASTContext &C,
3135  unsigned NumClauses, EmptyShell);
3136 
3137  static bool classof(const Stmt *T) {
3138  return T->getStmtClass() == OMPTargetDirectiveClass;
3139  }
3140 };
3141 
3142 /// This represents '#pragma omp target data' directive.
3143 ///
3144 /// \code
3145 /// #pragma omp target data device(0) if(a) map(b[:])
3146 /// \endcode
3147 /// In this example directive '#pragma omp target data' has clauses 'device'
3148 /// with the value '0', 'if' with condition 'a' and 'map' with array
3149 /// section 'b[:]'.
3150 ///
3152  friend class ASTStmtReader;
3154  /// Build directive with the given start and end location.
3155  ///
3156  /// \param StartLoc Starting location of the directive kind.
3157  /// \param EndLoc Ending Location of the directive.
3158  ///
3160  : OMPExecutableDirective(OMPTargetDataDirectiveClass,
3161  llvm::omp::OMPD_target_data, StartLoc, EndLoc) {}
3162 
3163  /// Build an empty directive.
3164  ///
3165  explicit OMPTargetDataDirective()
3166  : OMPExecutableDirective(OMPTargetDataDirectiveClass,
3167  llvm::omp::OMPD_target_data, SourceLocation(),
3168  SourceLocation()) {}
3169 
3170 public:
3171  /// Creates directive with a list of \a Clauses.
3172  ///
3173  /// \param C AST context.
3174  /// \param StartLoc Starting location of the directive kind.
3175  /// \param EndLoc Ending Location of the directive.
3176  /// \param Clauses List of clauses.
3177  /// \param AssociatedStmt Statement, associated with the directive.
3178  ///
3179  static OMPTargetDataDirective *
3180  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3181  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3182 
3183  /// Creates an empty directive with the place for \a N clauses.
3184  ///
3185  /// \param C AST context.
3186  /// \param N The number of clauses.
3187  ///
3188  static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
3189  EmptyShell);
3190 
3191  static bool classof(const Stmt *T) {
3192  return T->getStmtClass() == OMPTargetDataDirectiveClass;
3193  }
3194 };
3195 
3196 /// This represents '#pragma omp target enter data' directive.
3197 ///
3198 /// \code
3199 /// #pragma omp target enter data device(0) if(a) map(b[:])
3200 /// \endcode
3201 /// In this example directive '#pragma omp target enter data' has clauses
3202 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
3203 /// section 'b[:]'.
3204 ///
3206  friend class ASTStmtReader;
3208  /// Build directive with the given start and end location.
3209  ///
3210  /// \param StartLoc Starting location of the directive kind.
3211  /// \param EndLoc Ending Location of the directive.
3212  ///
3214  : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3215  llvm::omp::OMPD_target_enter_data, StartLoc,
3216  EndLoc) {}
3217 
3218  /// Build an empty directive.
3219  ///
3220  explicit OMPTargetEnterDataDirective()
3221  : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3222  llvm::omp::OMPD_target_enter_data,
3224 
3225 public:
3226  /// Creates directive with a list of \a Clauses.
3227  ///
3228  /// \param C AST context.
3229  /// \param StartLoc Starting location of the directive kind.
3230  /// \param EndLoc Ending Location of the directive.
3231  /// \param Clauses List of clauses.
3232  /// \param AssociatedStmt Statement, associated with the directive.
3233  ///
3234  static OMPTargetEnterDataDirective *
3235  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3236  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3237 
3238  /// Creates an empty directive with the place for \a N clauses.
3239  ///
3240  /// \param C AST context.
3241  /// \param N The number of clauses.
3242  ///
3243  static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C,
3244  unsigned N, EmptyShell);
3245 
3246  static bool classof(const Stmt *T) {
3247  return T->getStmtClass() == OMPTargetEnterDataDirectiveClass;
3248  }
3249 };
3250 
3251 /// This represents '#pragma omp target exit data' directive.
3252 ///
3253 /// \code
3254 /// #pragma omp target exit data device(0) if(a) map(b[:])
3255 /// \endcode
3256 /// In this example directive '#pragma omp target exit data' has clauses
3257 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
3258 /// section 'b[:]'.
3259 ///
3261  friend class ASTStmtReader;
3263  /// Build directive with the given start and end location.
3264  ///
3265  /// \param StartLoc Starting location of the directive kind.
3266  /// \param EndLoc Ending Location of the directive.
3267  ///
3269  : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3270  llvm::omp::OMPD_target_exit_data, StartLoc,
3271  EndLoc) {}
3272 
3273  /// Build an empty directive.
3274  ///
3275  explicit OMPTargetExitDataDirective()
3276  : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3277  llvm::omp::OMPD_target_exit_data,
3279 
3280 public:
3281  /// Creates directive with a list of \a Clauses.
3282  ///
3283  /// \param C AST context.
3284  /// \param StartLoc Starting location of the directive kind.
3285  /// \param EndLoc Ending Location of the directive.
3286  /// \param Clauses List of clauses.
3287  /// \param AssociatedStmt Statement, associated with the directive.
3288  ///
3289  static OMPTargetExitDataDirective *
3290  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3291  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3292 
3293  /// Creates an empty directive with the place for \a N clauses.
3294  ///
3295  /// \param C AST context.
3296  /// \param N The number of clauses.
3297  ///
3298  static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
3299  unsigned N, EmptyShell);
3300 
3301  static bool classof(const Stmt *T) {
3302  return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
3303  }
3304 };
3305 
3306 /// This represents '#pragma omp target parallel' directive.
3307 ///
3308 /// \code
3309 /// #pragma omp target parallel if(a)
3310 /// \endcode
3311 /// In this example directive '#pragma omp target parallel' has clause 'if' with
3312 /// condition 'a'.
3313 ///
3315  friend class ASTStmtReader;
3317  /// true if the construct has inner cancel directive.
3318  bool HasCancel = false;
3319 
3320  /// Build directive with the given start and end location.
3321  ///
3322  /// \param StartLoc Starting location of the directive kind.
3323  /// \param EndLoc Ending location of the directive.
3324  ///
3326  : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3327  llvm::omp::OMPD_target_parallel, StartLoc,
3328  EndLoc) {}
3329 
3330  /// Build an empty directive.
3331  ///
3332  explicit OMPTargetParallelDirective()
3333  : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3334  llvm::omp::OMPD_target_parallel,
3336 
3337  /// Sets special task reduction descriptor.
3338  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
3339  /// Set cancel state.
3340  void setHasCancel(bool Has) { HasCancel = Has; }
3341 
3342 public:
3343  /// Creates directive with a list of \a Clauses.
3344  ///
3345  /// \param C AST context.
3346  /// \param StartLoc Starting location of the directive kind.
3347  /// \param EndLoc Ending Location of the directive.
3348  /// \param Clauses List of clauses.
3349  /// \param AssociatedStmt Statement, associated with the directive.
3350  /// \param TaskRedRef Task reduction special reference expression to handle
3351  /// taskgroup descriptor.
3352  /// \param HasCancel true if this directive has inner cancel directive.
3353  ///
3354  static OMPTargetParallelDirective *
3355  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3356  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
3357  bool HasCancel);
3358 
3359  /// Creates an empty directive with the place for \a NumClauses
3360  /// clauses.
3361  ///
3362  /// \param C AST context.
3363  /// \param NumClauses Number of clauses.
3364  ///
3365  static OMPTargetParallelDirective *
3366  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
3367 
3368  /// Returns special task reduction reference expression.
3370  return cast_or_null<Expr>(Data->getChildren()[0]);
3371  }
3373  return const_cast<OMPTargetParallelDirective *>(this)
3375  }
3376 
3377  /// Return true if current directive has inner cancel directive.
3378  bool hasCancel() const { return HasCancel; }
3379 
3380  static bool classof(const Stmt *T) {
3381  return T->getStmtClass() == OMPTargetParallelDirectiveClass;
3382  }
3383 };
3384 
3385 /// This represents '#pragma omp target parallel for' directive.
3386 ///
3387 /// \code
3388 /// #pragma omp target parallel for private(a,b) reduction(+:c,d)
3389 /// \endcode
3390 /// In this example directive '#pragma omp target parallel for' has clauses
3391 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
3392 /// and variables 'c' and 'd'.
3393 ///
3395  friend class ASTStmtReader;
3397 
3398  /// true if current region has inner cancel directive.
3399  bool HasCancel = false;
3400 
3401  /// Build directive with the given start and end location.
3402  ///
3403  /// \param StartLoc Starting location of the directive kind.
3404  /// \param EndLoc Ending location of the directive.
3405  /// \param CollapsedNum Number of collapsed nested loops.
3406  ///
3408  unsigned CollapsedNum)
3409  : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3410  llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc,
3411  CollapsedNum) {}
3412 
3413  /// Build an empty directive.
3414  ///
3415  /// \param CollapsedNum Number of collapsed nested loops.
3416  ///
3417  explicit OMPTargetParallelForDirective(unsigned CollapsedNum)
3418  : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3419  llvm::omp::OMPD_target_parallel_for, SourceLocation(),
3420  SourceLocation(), CollapsedNum) {}
3421 
3422  /// Sets special task reduction descriptor.
3423  void setTaskReductionRefExpr(Expr *E) {
3425  getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E;
3426  }
3427 
3428  /// Set cancel state.
3429  void setHasCancel(bool Has) { HasCancel = Has; }
3430 
3431 public:
3432  /// Creates directive with a list of \a Clauses.
3433  ///
3434  /// \param C AST context.
3435  /// \param StartLoc Starting location of the directive kind.
3436  /// \param EndLoc Ending Location of the directive.
3437  /// \param CollapsedNum Number of collapsed loops.
3438  /// \param Clauses List of clauses.
3439  /// \param AssociatedStmt Statement, associated with the directive.
3440  /// \param Exprs Helper expressions for CodeGen.
3441  /// \param TaskRedRef Task reduction special reference expression to handle
3442  /// taskgroup descriptor.
3443  /// \param HasCancel true if current directive has inner cancel directive.
3444  ///
3445  static OMPTargetParallelForDirective *
3446  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3447  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3448  Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
3449  bool HasCancel);
3450 
3451  /// Creates an empty directive with the place
3452  /// for \a NumClauses clauses.
3453  ///
3454  /// \param C AST context.
3455  /// \param CollapsedNum Number of collapsed nested loops.
3456  /// \param NumClauses Number of clauses.
3457  ///
3458  static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C,
3459  unsigned NumClauses,
3460  unsigned CollapsedNum,
3461  EmptyShell);
3462 
3463  /// Returns special task reduction reference expression.
3465  return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
3466  getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]);
3467  }
3469  return const_cast<OMPTargetParallelForDirective *>(this)
3471  }
3472 
3473  /// Return true if current directive has inner cancel directive.
3474  bool hasCancel() const { return HasCancel; }
3475 
3476  static bool classof(const Stmt *T) {
3477  return T->getStmtClass() == OMPTargetParallelForDirectiveClass;
3478  }
3479 };
3480 
3481 /// This represents '#pragma omp teams' directive.
3482 ///
3483 /// \code
3484 /// #pragma omp teams if(a)
3485 /// \endcode
3486 /// In this example directive '#pragma omp teams' has clause 'if' with
3487 /// condition 'a'.
3488 ///
3490  friend class ASTStmtReader;
3492  /// Build directive with the given start and end location.
3493  ///
3494  /// \param StartLoc Starting location of the directive kind.
3495  /// \param EndLoc Ending location of the directive.
3496  ///
3498  : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3499  StartLoc, EndLoc) {}
3500 
3501  /// Build an empty directive.
3502  ///
3503  explicit OMPTeamsDirective()
3504  : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3506 
3507 public:
3508  /// Creates directive with a list of \a Clauses.
3509  ///
3510  /// \param C AST context.
3511  /// \param StartLoc Starting location of the directive kind.
3512  /// \param EndLoc Ending Location of the directive.
3513  /// \param Clauses List of clauses.
3514  /// \param AssociatedStmt Statement, associated with the directive.
3515  ///
3516  static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
3517  SourceLocation EndLoc,
3518  ArrayRef<OMPClause *> Clauses,
3519  Stmt *AssociatedStmt);
3520 
3521  /// Creates an empty directive with the place for \a NumClauses
3522  /// clauses.
3523  ///
3524  /// \param C AST context.
3525  /// \param NumClauses Number of clauses.
3526  ///
3527  static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
3528  unsigned NumClauses, EmptyShell);
3529 
3530  static bool classof(const Stmt *T) {
3531  return T->getStmtClass() == OMPTeamsDirectiveClass;
3532  }
3533 };
3534 
3535 /// This represents '#pragma omp cancellation point' directive.
3536 ///
3537 /// \code
3538 /// #pragma omp cancellation point for
3539 /// \endcode
3540 ///
3541 /// In this example a cancellation point is created for innermost 'for' region.
3543  friend class ASTStmtReader;
3545  OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
3546  /// Build directive with the given start and end location.
3547  ///
3548  /// \param StartLoc Starting location of the directive kind.
3549  /// \param EndLoc Ending location of the directive.
3550  /// statements and child expressions.
3551  ///
3553  : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3554  llvm::omp::OMPD_cancellation_point, StartLoc,
3555  EndLoc) {}
3556 
3557  /// Build an empty directive.
3559  : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3560  llvm::omp::OMPD_cancellation_point,
3562 
3563  /// Set cancel region for current cancellation point.
3564  /// \param CR Cancellation region.
3565  void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
3566 
3567 public:
3568  /// Creates directive.
3569  ///
3570  /// \param C AST context.
3571  /// \param StartLoc Starting location of the directive kind.
3572  /// \param EndLoc Ending Location of the directive.
3573  ///
3574  static OMPCancellationPointDirective *
3575  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3576  OpenMPDirectiveKind CancelRegion);
3577 
3578  /// Creates an empty directive.
3579  ///
3580  /// \param C AST context.
3581  ///
3582  static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
3583  EmptyShell);
3584 
3585  /// Get cancellation region for the current cancellation point.
3586  OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
3587 
3588  static bool classof(const Stmt *T) {
3589  return T->getStmtClass() == OMPCancellationPointDirectiveClass;
3590  }
3591 };
3592 
3593 /// This represents '#pragma omp cancel' directive.
3594 ///
3595 /// \code
3596 /// #pragma omp cancel for
3597 /// \endcode
3598 ///
3599 /// In this example a cancel is created for innermost 'for' region.
3601  friend class ASTStmtReader;
3603  OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
3604  /// Build directive with the given start and end location.
3605  ///
3606  /// \param StartLoc Starting location of the directive kind.
3607  /// \param EndLoc Ending location of the directive.
3608  ///
3610  : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3611  StartLoc, EndLoc) {}
3612 
3613  /// Build an empty directive.
3614  ///
3615  explicit OMPCancelDirective()
3616  : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3618 
3619  /// Set cancel region for current cancellation point.
3620  /// \param CR Cancellation region.
3621  void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
3622 
3623 public:
3624  /// Creates directive.
3625  ///
3626  /// \param C AST context.
3627  /// \param StartLoc Starting location of the directive kind.
3628  /// \param EndLoc Ending Location of the directive.
3629  /// \param Clauses List of clauses.
3630  ///
3631  static OMPCancelDirective *
3632  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3633  ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
3634 
3635  /// Creates an empty directive.
3636  ///
3637  /// \param C AST context.
3638  /// \param NumClauses Number of clauses.
3639  ///
3640  static OMPCancelDirective *CreateEmpty(const ASTContext &C,
3641  unsigned NumClauses, EmptyShell);
3642 
3643  /// Get cancellation region for the current cancellation point.
3644  OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
3645 
3646  static bool classof(const Stmt *T) {
3647  return T->getStmtClass() == OMPCancelDirectiveClass;
3648  }
3649 };
3650 
3651 /// This represents '#pragma omp taskloop' directive.
3652 ///
3653 /// \code
3654 /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
3655 /// \endcode
3656 /// In this example directive '#pragma omp taskloop' has clauses 'private'
3657 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
3658 /// 'num_tasks' with expression 'num'.
3659 ///
3661  friend class ASTStmtReader;
3663  /// true if the construct has inner cancel directive.
3664  bool HasCancel = false;
3665 
3666  /// Build directive with the given start and end location.
3667  ///
3668  /// \param StartLoc Starting location of the directive kind.
3669  /// \param EndLoc Ending location of the directive.
3670  /// \param CollapsedNum Number of collapsed nested loops.
3671  ///
3673  unsigned CollapsedNum)
3674  : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3675  StartLoc, EndLoc, CollapsedNum) {}
3676 
3677  /// Build an empty directive.
3678  ///
3679  /// \param CollapsedNum Number of collapsed nested loops.
3680  ///
3681  explicit OMPTaskLoopDirective(unsigned CollapsedNum)
3682  : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3683  SourceLocation(), SourceLocation(), CollapsedNum) {}
3684 
3685  /// Set cancel state.
3686  void setHasCancel(bool Has) { HasCancel = Has; }
3687 
3688 public:
3689  /// Creates directive with a list of \a Clauses.
3690  ///
3691  /// \param C AST context.
3692  /// \param StartLoc Starting location of the directive kind.
3693  /// \param EndLoc Ending Location of the directive.
3694  /// \param CollapsedNum Number of collapsed loops.
3695  /// \param Clauses List of clauses.
3696  /// \param AssociatedStmt Statement, associated with the directive.
3697  /// \param Exprs Helper expressions for CodeGen.
3698  /// \param HasCancel true if this directive has inner cancel directive.
3699  ///
3700  static OMPTaskLoopDirective *
3701  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3702  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3703  Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3704 
3705  /// Creates an empty directive with the place
3706  /// for \a NumClauses clauses.
3707  ///
3708  /// \param C AST context.
3709  /// \param CollapsedNum Number of collapsed nested loops.
3710  /// \param NumClauses Number of clauses.
3711  ///
3712  static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
3713  unsigned NumClauses,
3714  unsigned CollapsedNum, EmptyShell);
3715 
3716  /// Return true if current directive has inner cancel directive.
3717  bool hasCancel() const { return HasCancel; }
3718 
3719  static bool classof(const Stmt *T) {
3720  return T->getStmtClass() == OMPTaskLoopDirectiveClass;
3721  }
3722 };
3723 
3724 /// This represents '#pragma omp taskloop simd' directive.
3725 ///
3726 /// \code
3727 /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
3728 /// \endcode
3729 /// In this example directive '#pragma omp taskloop simd' has clauses 'private'
3730 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
3731 /// 'num_tasks' with expression 'num'.
3732 ///
3734  friend class ASTStmtReader;
3736  /// Build directive with the given start and end location.
3737  ///
3738  /// \param StartLoc Starting location of the directive kind.
3739  /// \param EndLoc Ending location of the directive.
3740  /// \param CollapsedNum Number of collapsed nested loops.
3741  ///
3743  unsigned CollapsedNum)
3744  : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3745  llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc,
3746  CollapsedNum) {}
3747 
3748  /// Build an empty directive.
3749  ///
3750  /// \param CollapsedNum Number of collapsed nested loops.
3751  ///
3752  explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum)
3753  : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3754  llvm::omp::OMPD_taskloop_simd, SourceLocation(),
3755  SourceLocation(), CollapsedNum) {}
3756 
3757 public:
3758  /// Creates directive with a list of \a Clauses.
3759  ///
3760  /// \param C AST context.
3761  /// \param StartLoc Starting location of the directive kind.
3762  /// \param EndLoc Ending Location of the directive.
3763  /// \param CollapsedNum Number of collapsed loops.
3764  /// \param Clauses List of clauses.
3765  /// \param AssociatedStmt Statement, associated with the directive.
3766  /// \param Exprs Helper expressions for CodeGen.
3767  ///
3768  static OMPTaskLoopSimdDirective *
3769  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3770  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3771  Stmt *AssociatedStmt, const HelperExprs &Exprs);
3772 
3773  /// Creates an empty directive with the place
3774  /// for \a NumClauses clauses.
3775  ///
3776  /// \param C AST context.
3777  /// \param CollapsedNum Number of collapsed nested loops.
3778  /// \param NumClauses Number of clauses.
3779  ///
3780  static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
3781  unsigned NumClauses,
3782  unsigned CollapsedNum,
3783  EmptyShell);
3784 
3785  static bool classof(const Stmt *T) {
3786  return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
3787  }
3788 };
3789 
3790 /// This represents '#pragma omp master taskloop' directive.
3791 ///
3792 /// \code
3793 /// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num)
3794 /// \endcode
3795 /// In this example directive '#pragma omp master taskloop' has clauses
3796 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3797 /// and 'num_tasks' with expression 'num'.
3798 ///
3800  friend class ASTStmtReader;
3802  /// true if the construct has inner cancel directive.
3803  bool HasCancel = false;
3804 
3805  /// Build directive with the given start and end location.
3806  ///
3807  /// \param StartLoc Starting location of the directive kind.
3808  /// \param EndLoc Ending location of the directive.
3809  /// \param CollapsedNum Number of collapsed nested loops.
3810  ///
3812  unsigned CollapsedNum)
3813  : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3814  llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc,
3815  CollapsedNum) {}
3816 
3817  /// Build an empty directive.
3818  ///
3819  /// \param CollapsedNum Number of collapsed nested loops.
3820  ///
3821  explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum)
3822  : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3823  llvm::omp::OMPD_master_taskloop, SourceLocation(),
3824  SourceLocation(), CollapsedNum) {}
3825 
3826  /// Set cancel state.
3827  void setHasCancel(bool Has) { HasCancel = Has; }
3828 
3829 public:
3830  /// Creates directive with a list of \a Clauses.
3831  ///
3832  /// \param C AST context.
3833  /// \param StartLoc Starting location of the directive kind.
3834  /// \param EndLoc Ending Location of the directive.
3835  /// \param CollapsedNum Number of collapsed loops.
3836  /// \param Clauses List of clauses.
3837  /// \param AssociatedStmt Statement, associated with the directive.
3838  /// \param Exprs Helper expressions for CodeGen.
3839  /// \param HasCancel true if this directive has inner cancel directive.
3840  ///
3841  static OMPMasterTaskLoopDirective *
3842  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3843  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3844  Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3845 
3846  /// Creates an empty directive with the place
3847  /// for \a NumClauses clauses.
3848  ///
3849  /// \param C AST context.
3850  /// \param CollapsedNum Number of collapsed nested loops.
3851  /// \param NumClauses Number of clauses.
3852  ///
3853  static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
3854  unsigned NumClauses,
3855  unsigned CollapsedNum,
3856  EmptyShell);
3857 
3858  /// Return true if current directive has inner cancel directive.
3859  bool hasCancel() const { return HasCancel; }
3860 
3861  static bool classof(const Stmt *T) {
3862  return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass;
3863  }
3864 };
3865 
3866 /// This represents '#pragma omp masked taskloop' directive.
3867 ///
3868 /// \code
3869 /// #pragma omp masked taskloop private(a,b) grainsize(val) num_tasks(num)
3870 /// \endcode
3871 /// In this example directive '#pragma omp masked taskloop' has clauses
3872 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3873 /// and 'num_tasks' with expression 'num'.
3874 ///
3876  friend class ASTStmtReader;
3878  /// true if the construct has inner cancel directive.
3879  bool HasCancel = false;
3880 
3881  /// Build directive with the given start and end location.
3882  ///
3883  /// \param StartLoc Starting location of the directive kind.
3884  /// \param EndLoc Ending location of the directive.
3885  /// \param CollapsedNum Number of collapsed nested loops.
3886  ///
3888  unsigned CollapsedNum)
3889  : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
3890  llvm::omp::OMPD_masked_taskloop, StartLoc, EndLoc,
3891  CollapsedNum) {}
3892 
3893  /// Build an empty directive.
3894  ///
3895  /// \param CollapsedNum Number of collapsed nested loops.
3896  ///
3897  explicit OMPMaskedTaskLoopDirective(unsigned CollapsedNum)
3898  : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
3899  llvm::omp::OMPD_masked_taskloop, SourceLocation(),
3900  SourceLocation(), CollapsedNum) {}
3901 
3902  /// Set cancel state.
3903  void setHasCancel(bool Has) { HasCancel = Has; }
3904 
3905 public:
3906  /// Creates directive with a list of \a Clauses.
3907  ///
3908  /// \param C AST context.
3909  /// \param StartLoc Starting location of the directive kind.
3910  /// \param EndLoc Ending Location of the directive.
3911  /// \param CollapsedNum Number of collapsed loops.
3912  /// \param Clauses List of clauses.
3913  /// \param AssociatedStmt Statement, associated with the directive.
3914  /// \param Exprs Helper expressions for CodeGen.
3915  /// \param HasCancel true if this directive has inner cancel directive.
3916  ///
3917  static OMPMaskedTaskLoopDirective *
3918  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3919  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3920  Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3921 
3922  /// Creates an empty directive with the place
3923  /// for \a NumClauses clauses.
3924  ///
3925  /// \param C AST context.
3926  /// \param CollapsedNum Number of collapsed nested loops.
3927  /// \param NumClauses Number of clauses.
3928  ///
3929  static OMPMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
3930  unsigned NumClauses,
3931  unsigned CollapsedNum,
3932  EmptyShell);
3933 
3934  /// Return true if current directive has inner cancel directive.
3935  bool hasCancel() const { return HasCancel; }
3936 
3937  static bool classof(const Stmt *T) {
3938  return T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass;
3939  }
3940 };
3941 
3942 /// This represents '#pragma omp master taskloop simd' directive.
3943 ///
3944 /// \code
3945 /// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num)
3946 /// \endcode
3947 /// In this example directive '#pragma omp master taskloop simd' has clauses
3948 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3949 /// and 'num_tasks' with expression 'num'.
3950 ///
3952  friend class ASTStmtReader;
3954  /// Build directive with the given start and end location.
3955  ///
3956  /// \param StartLoc Starting location of the directive kind.
3957  /// \param EndLoc Ending location of the directive.
3958  /// \param CollapsedNum Number of collapsed nested loops.
3959  ///
3961  unsigned CollapsedNum)
3962  : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
3963  llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc,
3964  CollapsedNum) {}
3965 
3966  /// Build an empty directive.
3967  ///
3968  /// \param CollapsedNum Number of collapsed nested loops.
3969  ///
3970  explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum)
3971  : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
3972  llvm::omp::OMPD_master_taskloop_simd, SourceLocation(),
3973  SourceLocation(), CollapsedNum) {}
3974 
3975 public:
3976  /// Creates directive with a list of \p Clauses.
3977  ///
3978  /// \param C AST context.
3979  /// \param StartLoc Starting location of the directive kind.
3980  /// \param EndLoc Ending Location of the directive.
3981  /// \param CollapsedNum Number of collapsed loops.
3982  /// \param Clauses List of clauses.
3983  /// \param AssociatedStmt Statement, associated with the directive.
3984  /// \param Exprs Helper expressions for CodeGen.
3985  ///
3986  static OMPMasterTaskLoopSimdDirective *
3987  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3988  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3989  Stmt *AssociatedStmt, const HelperExprs &Exprs);
3990 
3991  /// Creates an empty directive with the place for \p NumClauses clauses.
3992  ///
3993  /// \param C AST context.
3994  /// \param CollapsedNum Number of collapsed nested loops.
3995  /// \param NumClauses Number of clauses.
3996  ///
3997  static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
3998  unsigned NumClauses,
3999  unsigned CollapsedNum,
4000  EmptyShell);
4001 
4002  static bool classof(const Stmt *T) {
4003  return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass;
4004  }
4005 };
4006 
4007 /// This represents '#pragma omp masked taskloop simd' directive.
4008 ///
4009 /// \code
4010 /// #pragma omp masked taskloop simd private(a,b) grainsize(val) num_tasks(num)
4011 /// \endcode
4012 /// In this example directive '#pragma omp masked taskloop simd' has clauses
4013 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4014 /// and 'num_tasks' with expression 'num'.
4015 ///
4017  friend class ASTStmtReader;
4019  /// Build directive with the given start and end location.
4020  ///
4021  /// \param StartLoc Starting location of the directive kind.
4022  /// \param EndLoc Ending location of the directive.
4023  /// \param CollapsedNum Number of collapsed nested loops.
4024  ///
4026  unsigned CollapsedNum)
4027  : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
4028  llvm::omp::OMPD_masked_taskloop_simd, StartLoc, EndLoc,
4029  CollapsedNum) {}
4030 
4031  /// Build an empty directive.
4032  ///
4033  /// \param CollapsedNum Number of collapsed nested loops.
4034  ///
4035  explicit OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
4036  : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
4037  llvm::omp::OMPD_masked_taskloop_simd, SourceLocation(),
4038  SourceLocation(), CollapsedNum) {}
4039 
4040 public:
4041  /// Creates directive with a list of \p Clauses.
4042  ///
4043  /// \param C AST context.
4044  /// \param StartLoc Starting location of the directive kind.
4045  /// \param EndLoc Ending Location of the directive.
4046  /// \param CollapsedNum Number of collapsed loops.
4047  /// \param Clauses List of clauses.
4048  /// \param AssociatedStmt Statement, associated with the directive.
4049  /// \param Exprs Helper expressions for CodeGen.
4050  ///
4051  static OMPMaskedTaskLoopSimdDirective *
4052  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4053  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4054  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4055 
4056  /// Creates an empty directive with the place for \p NumClauses clauses.
4057  ///
4058  /// \param C AST context.
4059  /// \param CollapsedNum Number of collapsed nested loops.
4060  /// \param NumClauses Number of clauses.
4061  ///
4062  static OMPMaskedTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
4063  unsigned NumClauses,
4064  unsigned CollapsedNum,
4065  EmptyShell);
4066 
4067  static bool classof(const Stmt *T) {
4068  return T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass;
4069  }
4070 };
4071 
4072 /// This represents '#pragma omp parallel master taskloop' directive.
4073 ///
4074 /// \code
4075 /// #pragma omp parallel master taskloop private(a,b) grainsize(val)
4076 /// num_tasks(num)
4077 /// \endcode
4078 /// In this example directive '#pragma omp parallel master taskloop' has clauses
4079 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4080 /// and 'num_tasks' with expression 'num'.
4081 ///
4083  friend class ASTStmtReader;
4085  /// true if the construct has inner cancel directive.
4086  bool HasCancel = false;
4087 
4088  /// Build directive with the given start and end location.
4089  ///
4090  /// \param StartLoc Starting location of the directive kind.
4091  /// \param EndLoc Ending location of the directive.
4092  /// \param CollapsedNum Number of collapsed nested loops.
4093  ///
4095  SourceLocation EndLoc,
4096  unsigned CollapsedNum)
4097  : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
4098  llvm::omp::OMPD_parallel_master_taskloop, StartLoc,
4099  EndLoc, CollapsedNum) {}
4100 
4101  /// Build an empty directive.
4102  ///
4103  /// \param CollapsedNum Number of collapsed nested loops.
4104  ///
4105  explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum)
4106  : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
4107  llvm::omp::OMPD_parallel_master_taskloop,
4108  SourceLocation(), SourceLocation(), CollapsedNum) {}
4109 
4110  /// Set cancel state.
4111  void setHasCancel(bool Has) { HasCancel = Has; }
4112 
4113 public:
4114  /// Creates directive with a list of \a Clauses.
4115  ///
4116  /// \param C AST context.
4117  /// \param StartLoc Starting location of the directive kind.
4118  /// \param EndLoc Ending Location of the directive.
4119  /// \param CollapsedNum Number of collapsed loops.
4120  /// \param Clauses List of clauses.
4121  /// \param AssociatedStmt Statement, associated with the directive.
4122  /// \param Exprs Helper expressions for CodeGen.
4123  /// \param HasCancel true if this directive has inner cancel directive.
4124  ///
4125  static OMPParallelMasterTaskLoopDirective *
4126  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4127  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4128  Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
4129 
4130  /// Creates an empty directive with the place
4131  /// for \a NumClauses clauses.
4132  ///
4133  /// \param C AST context.
4134  /// \param CollapsedNum Number of collapsed nested loops.
4135  /// \param NumClauses Number of clauses.
4136  ///
4137  static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
4138  unsigned NumClauses,
4139  unsigned CollapsedNum,
4140  EmptyShell);
4141 
4142  /// Return true if current directive has inner cancel directive.
4143  bool hasCancel() const { return HasCancel; }
4144 
4145  static bool classof(const Stmt *T) {
4146  return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass;
4147  }
4148 };
4149 
4150 /// This represents '#pragma omp parallel masked taskloop' directive.
4151 ///
4152 /// \code
4153 /// #pragma omp parallel masked taskloop private(a,b) grainsize(val)
4154 /// num_tasks(num)
4155 /// \endcode
4156 /// In this example directive '#pragma omp parallel masked taskloop' has clauses
4157 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4158 /// and 'num_tasks' with expression 'num'.
4159 ///
4161  friend class ASTStmtReader;
4163  /// true if the construct has inner cancel directive.
4164  bool HasCancel = false;
4165 
4166  /// Build directive with the given start and end location.
4167  ///
4168  /// \param StartLoc Starting location of the directive kind.
4169  /// \param EndLoc Ending location of the directive.
4170  /// \param CollapsedNum Number of collapsed nested loops.
4171  ///
4173  SourceLocation EndLoc,
4174  unsigned CollapsedNum)
4175  : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
4176  llvm::omp::OMPD_parallel_masked_taskloop, StartLoc,
4177  EndLoc, CollapsedNum) {}
4178 
4179  /// Build an empty directive.
4180  ///
4181  /// \param CollapsedNum Number of collapsed nested loops.
4182  ///
4183  explicit OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum)
4184  : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
4185  llvm::omp::OMPD_parallel_masked_taskloop,
4186  SourceLocation(), SourceLocation(), CollapsedNum) {}
4187 
4188  /// Set cancel state.
4189  void setHasCancel(bool Has) { HasCancel = Has; }
4190 
4191 public:
4192  /// Creates directive with a list of \a Clauses.
4193  ///
4194  /// \param C AST context.
4195  /// \param StartLoc Starting location of the directive kind.
4196  /// \param EndLoc Ending Location of the directive.
4197  /// \param CollapsedNum Number of collapsed loops.
4198  /// \param Clauses List of clauses.
4199  /// \param AssociatedStmt Statement, associated with the directive.
4200  /// \param Exprs Helper expressions for CodeGen.
4201  /// \param HasCancel true if this directive has inner cancel directive.
4202  ///
4203  static OMPParallelMaskedTaskLoopDirective *
4204  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4205  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4206  Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
4207 
4208  /// Creates an empty directive with the place
4209  /// for \a NumClauses clauses.
4210  ///
4211  /// \param C AST context.
4212  /// \param CollapsedNum Number of collapsed nested loops.
4213  /// \param NumClauses Number of clauses.
4214  ///
4215  static OMPParallelMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
4216  unsigned NumClauses,
4217  unsigned CollapsedNum,
4218  EmptyShell);
4219 
4220  /// Return true if current directive has inner cancel directive.
4221  bool hasCancel() const { return HasCancel; }
4222 
4223  static bool classof(const Stmt *T) {
4224  return T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass;
4225  }
4226 };
4227 
4228 /// This represents '#pragma omp parallel master taskloop simd' directive.
4229 ///
4230 /// \code
4231 /// #pragma omp parallel master taskloop simd private(a,b) grainsize(val)
4232 /// num_tasks(num)
4233 /// \endcode
4234 /// In this example directive '#pragma omp parallel master taskloop simd' has
4235 /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
4236 /// expression 'val' and 'num_tasks' with expression 'num'.
4237 ///
4239  friend class ASTStmtReader;
4241  /// Build directive with the given start and end location.
4242  ///
4243  /// \param StartLoc Starting location of the directive kind.
4244  /// \param EndLoc Ending location of the directive.
4245  /// \param CollapsedNum Number of collapsed nested loops.
4246  ///
4248  SourceLocation EndLoc,
4249  unsigned CollapsedNum)
4250  : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
4251  llvm::omp::OMPD_parallel_master_taskloop_simd,
4252  StartLoc, EndLoc, CollapsedNum) {}
4253 
4254  /// Build an empty directive.
4255  ///
4256  /// \param CollapsedNum Number of collapsed nested loops.
4257  ///
4258  explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum)
4259  : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
4260  llvm::omp::OMPD_parallel_master_taskloop_simd,
4261  SourceLocation(), SourceLocation(), CollapsedNum) {}
4262 
4263 public:
4264  /// Creates directive with a list of \p Clauses.
4265  ///
4266  /// \param C AST context.
4267  /// \param StartLoc Starting location of the directive kind.
4268  /// \param EndLoc Ending Location of the directive.
4269  /// \param CollapsedNum Number of collapsed loops.
4270  /// \param Clauses List of clauses.
4271  /// \param AssociatedStmt Statement, associated with the directive.
4272  /// \param Exprs Helper expressions for CodeGen.
4273  ///
4274  static OMPParallelMasterTaskLoopSimdDirective *
4275  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4276  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4277  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4278 
4279  /// Creates an empty directive with the place
4280  /// for \a NumClauses clauses.
4281  ///
4282  /// \param C AST context.
4283  /// \param CollapsedNum Number of collapsed nested loops.
4284  /// \param NumClauses Number of clauses.
4285  ///
4286  static OMPParallelMasterTaskLoopSimdDirective *
4287  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4288  EmptyShell);
4289 
4290  static bool classof(const Stmt *T) {
4291  return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass;
4292  }
4293 };
4294 
4295 /// This represents '#pragma omp parallel masked taskloop simd' directive.
4296 ///
4297 /// \code
4298 /// #pragma omp parallel masked taskloop simd private(a,b) grainsize(val)
4299 /// num_tasks(num)
4300 /// \endcode
4301 /// In this example directive '#pragma omp parallel masked taskloop simd' has
4302 /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
4303 /// expression 'val' and 'num_tasks' with expression 'num'.
4304 ///
4306  friend class ASTStmtReader;
4308  /// Build directive with the given start and end location.
4309  ///
4310  /// \param StartLoc Starting location of the directive kind.
4311  /// \param EndLoc Ending location of the directive.
4312  /// \param CollapsedNum Number of collapsed nested loops.
4313  ///
4315  SourceLocation EndLoc,
4316  unsigned CollapsedNum)
4317  : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
4318  llvm::omp::OMPD_parallel_masked_taskloop_simd,
4319  StartLoc, EndLoc, CollapsedNum) {}
4320 
4321  /// Build an empty directive.
4322  ///
4323  /// \param CollapsedNum Number of collapsed nested loops.
4324  ///
4325  explicit OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
4326  : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
4327  llvm::omp::OMPD_parallel_masked_taskloop_simd,
4328  SourceLocation(), SourceLocation(), CollapsedNum) {}
4329 
4330 public:
4331  /// Creates directive with a list of \p Clauses.
4332  ///
4333  /// \param C AST context.
4334  /// \param StartLoc Starting location of the directive kind.
4335  /// \param EndLoc Ending Location of the directive.
4336  /// \param CollapsedNum Number of collapsed loops.
4337  /// \param Clauses List of clauses.
4338  /// \param AssociatedStmt Statement, associated with the directive.
4339  /// \param Exprs Helper expressions for CodeGen.
4340  ///
4341  static OMPParallelMaskedTaskLoopSimdDirective *
4342  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4343  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4344  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4345 
4346  /// Creates an empty directive with the place
4347  /// for \a NumClauses clauses.
4348  ///
4349  /// \param C AST context.
4350  /// \param CollapsedNum Number of collapsed nested loops.
4351  /// \param NumClauses Number of clauses.
4352  ///
4353  static OMPParallelMaskedTaskLoopSimdDirective *
4354  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4355  EmptyShell);
4356 
4357  static bool classof(const Stmt *T) {
4358  return T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass;
4359  }
4360 };
4361 
4362 /// This represents '#pragma omp distribute' directive.
4363 ///
4364 /// \code
4365 /// #pragma omp distribute private(a,b)
4366 /// \endcode
4367 /// In this example directive '#pragma omp distribute' has clauses 'private'
4368 /// with the variables 'a' and 'b'
4369 ///
4371  friend class ASTStmtReader;
4373 
4374  /// Build directive with the given start and end location.
4375  ///
4376  /// \param StartLoc Starting location of the directive kind.
4377  /// \param EndLoc Ending location of the directive.
4378  /// \param CollapsedNum Number of collapsed nested loops.
4379  ///
4381  unsigned CollapsedNum)
4382  : OMPLoopDirective(OMPDistributeDirectiveClass,
4383  llvm::omp::OMPD_distribute, StartLoc, EndLoc,
4384  CollapsedNum) {}
4385 
4386  /// Build an empty directive.
4387  ///
4388  /// \param CollapsedNum Number of collapsed nested loops.
4389  ///
4390  explicit OMPDistributeDirective(unsigned CollapsedNum)
4391  : OMPLoopDirective(OMPDistributeDirectiveClass,
4392  llvm::omp::OMPD_distribute, SourceLocation(),
4393  SourceLocation(), CollapsedNum) {}
4394 
4395 public:
4396  /// Creates directive with a list of \a Clauses.
4397  ///
4398  /// \param C AST context.
4399  /// \param StartLoc Starting location of the directive kind.
4400  /// \param EndLoc Ending Location of the directive.
4401  /// \param CollapsedNum Number of collapsed loops.
4402  /// \param Clauses List of clauses.
4403  /// \param AssociatedStmt Statement, associated with the directive.
4404  /// \param Exprs Helper expressions for CodeGen.
4405  ///
4406  static OMPDistributeDirective *
4407  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4408  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4409  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4410 
4411  /// Creates an empty directive with the place
4412  /// for \a NumClauses clauses.
4413  ///
4414  /// \param C AST context.
4415  /// \param CollapsedNum Number of collapsed nested loops.
4416  /// \param NumClauses Number of clauses.
4417  ///
4418  static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
4419  unsigned NumClauses,
4420  unsigned CollapsedNum, EmptyShell);
4421 
4422  static bool classof(const Stmt *T) {
4423  return T->getStmtClass() == OMPDistributeDirectiveClass;
4424  }
4425 };
4426 
4427 /// This represents '#pragma omp target update' directive.
4428 ///
4429 /// \code
4430 /// #pragma omp target update to(a) from(b) device(1)
4431 /// \endcode
4432 /// In this example directive '#pragma omp target update' has clause 'to' with
4433 /// argument 'a', clause 'from' with argument 'b' and clause 'device' with
4434 /// argument '1'.
4435 ///
4437  friend class ASTStmtReader;
4439  /// Build directive with the given start and end location.
4440  ///
4441  /// \param StartLoc Starting location of the directive kind.
4442  /// \param EndLoc Ending Location of the directive.
4443  ///
4445  : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
4446  llvm::omp::OMPD_target_update, StartLoc,
4447  EndLoc) {}
4448 
4449  /// Build an empty directive.
4450  ///
4451  explicit OMPTargetUpdateDirective()
4452  : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
4453  llvm::omp::OMPD_target_update, SourceLocation(),
4454  SourceLocation()) {}
4455 
4456 public:
4457  /// Creates directive with a list of \a Clauses.
4458  ///
4459  /// \param C AST context.
4460  /// \param StartLoc Starting location of the directive kind.
4461  /// \param EndLoc Ending Location of the directive.
4462  /// \param Clauses List of clauses.
4463  /// \param AssociatedStmt Statement, associated with the directive.
4464  ///
4465  static OMPTargetUpdateDirective *
4466  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4467  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
4468 
4469  /// Creates an empty directive with the place for \a NumClauses
4470  /// clauses.
4471  ///
4472  /// \param C AST context.
4473  /// \param NumClauses The number of clauses.
4474  ///
4475  static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C,
4476  unsigned NumClauses, EmptyShell);
4477 
4478  static bool classof(const Stmt *T) {
4479  return T->getStmtClass() == OMPTargetUpdateDirectiveClass;
4480  }
4481 };
4482 
4483 /// This represents '#pragma omp distribute parallel for' composite
4484 /// directive.
4485 ///
4486 /// \code
4487 /// #pragma omp distribute parallel for private(a,b)
4488 /// \endcode
4489 /// In this example directive '#pragma omp distribute parallel for' has clause
4490 /// 'private' with the variables 'a' and 'b'
4491 ///
4493  friend class ASTStmtReader;
4495  /// true if the construct has inner cancel directive.
4496  bool HasCancel = false;
4497 
4498  /// Build directive with the given start and end location.
4499  ///
4500  /// \param StartLoc Starting location of the directive kind.
4501  /// \param EndLoc Ending location of the directive.
4502  /// \param CollapsedNum Number of collapsed nested loops.
4503  ///
4505  SourceLocation EndLoc,
4506  unsigned CollapsedNum)
4507  : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4508  llvm::omp::OMPD_distribute_parallel_for, StartLoc,
4509  EndLoc, CollapsedNum) {}
4510 
4511  /// Build an empty directive.
4512  ///
4513  /// \param CollapsedNum Number of collapsed nested loops.
4514  ///
4515  explicit OMPDistributeParallelForDirective(unsigned CollapsedNum)
4516  : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4517  llvm::omp::OMPD_distribute_parallel_for,
4518  SourceLocation(), SourceLocation(), CollapsedNum) {}
4519 
4520  /// Sets special task reduction descriptor.
4521  void setTaskReductionRefExpr(Expr *E) {
4523  getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E;
4524  }
4525 
4526  /// Set cancel state.
4527  void setHasCancel(bool Has) { HasCancel = Has; }
4528 
4529 public:
4530  /// Creates directive with a list of \a Clauses.
4531  ///
4532  /// \param C AST context.
4533  /// \param StartLoc Starting location of the directive kind.
4534  /// \param EndLoc Ending Location of the directive.
4535  /// \param CollapsedNum Number of collapsed loops.
4536  /// \param Clauses List of clauses.
4537  /// \param AssociatedStmt Statement, associated with the directive.
4538  /// \param Exprs Helper expressions for CodeGen.
4539  /// \param TaskRedRef Task reduction special reference expression to handle
4540  /// taskgroup descriptor.
4541  /// \param HasCancel true if this directive has inner cancel directive.
4542  ///
4543  static OMPDistributeParallelForDirective *
4544  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4545  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4546  Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
4547  bool HasCancel);
4548 
4549  /// Creates an empty directive with the place
4550  /// for \a NumClauses clauses.
4551  ///
4552  /// \param C AST context.
4553  /// \param CollapsedNum Number of collapsed nested loops.
4554  /// \param NumClauses Number of clauses.
4555  ///
4556  static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C,
4557  unsigned NumClauses,
4558  unsigned CollapsedNum,
4559  EmptyShell);
4560 
4561  /// Returns special task reduction reference expression.
4563  return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
4564  getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]);
4565  }
4567  return const_cast<OMPDistributeParallelForDirective *>(this)
4569  }
4570 
4571  /// Return true if current directive has inner cancel directive.
4572  bool hasCancel() const { return HasCancel; }
4573 
4574  static bool classof(const Stmt *T) {
4575  return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
4576  }
4577 };
4578 
4579 /// This represents '#pragma omp distribute parallel for simd' composite
4580 /// directive.
4581 ///
4582 /// \code
4583 /// #pragma omp distribute parallel for simd private(x)
4584 /// \endcode
4585 /// In this example directive '#pragma omp distribute parallel for simd' has
4586 /// clause 'private' with the variables 'x'
4587 ///
4589  friend class ASTStmtReader;
4591 
4592  /// Build directive with the given start and end location.
4593  ///
4594  /// \param StartLoc Starting location of the directive kind.
4595  /// \param EndLoc Ending location of the directive.
4596  /// \param CollapsedNum Number of collapsed nested loops.
4597  ///
4599  SourceLocation EndLoc,
4600  unsigned CollapsedNum)
4601  : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4602  llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc,
4603  EndLoc, CollapsedNum) {}
4604 
4605  /// Build an empty directive.
4606  ///
4607  /// \param CollapsedNum Number of collapsed nested loops.
4608  ///
4609  explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum)
4610  : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4611  llvm::omp::OMPD_distribute_parallel_for_simd,
4612  SourceLocation(), SourceLocation(), CollapsedNum) {}
4613 
4614 public:
4615  /// Creates directive with a list of \a Clauses.
4616  ///
4617  /// \param C AST context.
4618  /// \param StartLoc Starting location of the directive kind.
4619  /// \param EndLoc Ending Location of the directive.
4620  /// \param CollapsedNum Number of collapsed loops.
4621  /// \param Clauses List of clauses.
4622  /// \param AssociatedStmt Statement, associated with the directive.
4623  /// \param Exprs Helper expressions for CodeGen.
4624  ///
4625  static OMPDistributeParallelForSimdDirective *Create(
4626  const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4627  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4628  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4629 
4630  /// Creates an empty directive with the place for \a NumClauses clauses.
4631  ///
4632  /// \param C AST context.
4633  /// \param CollapsedNum Number of collapsed nested loops.
4634  /// \param NumClauses Number of clauses.
4635  ///
4636  static OMPDistributeParallelForSimdDirective *CreateEmpty(
4637  const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4638  EmptyShell);
4639 
4640  static bool classof(const Stmt *T) {
4641  return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass;
4642  }
4643 };
4644 
4645 /// This represents '#pragma omp distribute simd' composite directive.
4646 ///
4647 /// \code
4648 /// #pragma omp distribute simd private(x)
4649 /// \endcode
4650 /// In this example directive '#pragma omp distribute simd' has clause
4651 /// 'private' with the variables 'x'
4652 ///
4654  friend class ASTStmtReader;
4656 
4657  /// Build directive with the given start and end location.
4658  ///
4659  /// \param StartLoc Starting location of the directive kind.
4660  /// \param EndLoc Ending location of the directive.
4661  /// \param CollapsedNum Number of collapsed nested loops.
4662  ///
4664  unsigned CollapsedNum)
4665  : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4666  llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc,
4667  CollapsedNum) {}
4668 
4669  /// Build an empty directive.
4670  ///
4671  /// \param CollapsedNum Number of collapsed nested loops.
4672  ///
4673  explicit OMPDistributeSimdDirective(unsigned CollapsedNum)
4674  : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4675  llvm::omp::OMPD_distribute_simd, SourceLocation(),
4676  SourceLocation(), CollapsedNum) {}
4677 
4678 public:
4679  /// Creates directive with a list of \a Clauses.
4680  ///
4681  /// \param C AST context.
4682  /// \param StartLoc Starting location of the directive kind.
4683  /// \param EndLoc Ending Location of the directive.
4684  /// \param CollapsedNum Number of collapsed loops.
4685  /// \param Clauses List of clauses.
4686  /// \param AssociatedStmt Statement, associated with the directive.
4687  /// \param Exprs Helper expressions for CodeGen.
4688  ///
4689  static OMPDistributeSimdDirective *
4690  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4691  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4692  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4693 
4694  /// Creates an empty directive with the place for \a NumClauses clauses.
4695  ///
4696  /// \param C AST context.
4697  /// \param CollapsedNum Number of collapsed nested loops.
4698  /// \param NumClauses Number of clauses.
4699  ///
4700  static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C,
4701  unsigned NumClauses,
4702  unsigned CollapsedNum,
4703  EmptyShell);
4704 
4705  static bool classof(const Stmt *T) {
4706  return T->getStmtClass() == OMPDistributeSimdDirectiveClass;
4707  }
4708 };
4709 
4710 /// This represents '#pragma omp target parallel for simd' directive.
4711 ///
4712 /// \code
4713 /// #pragma omp target parallel for simd private(a) map(b) safelen(c)
4714 /// \endcode
4715 /// In this example directive '#pragma omp target parallel for simd' has clauses
4716 /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen'
4717 /// with the variable 'c'.
4718 ///
4720  friend class ASTStmtReader;
4722 
4723  /// Build directive with the given start and end location.
4724  ///
4725  /// \param StartLoc Starting location of the directive kind.
4726  /// \param EndLoc Ending location of the directive.
4727  /// \param CollapsedNum Number of collapsed nested loops.
4728  ///
4730  SourceLocation EndLoc,
4731  unsigned CollapsedNum)
4732  : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4733  llvm::omp::OMPD_target_parallel_for_simd, StartLoc,
4734  EndLoc, CollapsedNum) {}
4735 
4736  /// Build an empty directive.
4737  ///
4738  /// \param CollapsedNum Number of collapsed nested loops.
4739  ///
4740  explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum)
4741  : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4742  llvm::omp::OMPD_target_parallel_for_simd,
4743  SourceLocation(), SourceLocation(), CollapsedNum) {}
4744 
4745 public:
4746  /// Creates directive with a list of \a Clauses.
4747  ///
4748  /// \param C AST context.
4749  /// \param StartLoc Starting location of the directive kind.
4750  /// \param EndLoc Ending Location of the directive.
4751  /// \param CollapsedNum Number of collapsed loops.
4752  /// \param Clauses List of clauses.
4753  /// \param AssociatedStmt Statement, associated with the directive.
4754  /// \param Exprs Helper expressions for CodeGen.
4755  ///
4756  static OMPTargetParallelForSimdDirective *
4757  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4758  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4759  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4760 
4761  /// Creates an empty directive with the place for \a NumClauses clauses.
4762  ///
4763  /// \param C AST context.
4764  /// \param CollapsedNum Number of collapsed nested loops.
4765  /// \param NumClauses Number of clauses.
4766  ///
4767  static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C,
4768  unsigned NumClauses,
4769  unsigned CollapsedNum,
4770  EmptyShell);
4771 
4772  static bool classof(const Stmt *T) {
4773  return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
4774  }
4775 };
4776 
4777 /// This represents '#pragma omp target simd' directive.
4778 ///
4779 /// \code
4780 /// #pragma omp target simd private(a) map(b) safelen(c)
4781 /// \endcode
4782 /// In this example directive '#pragma omp target simd' has clauses 'private'
4783 /// with the variable 'a', 'map' with the variable 'b' and 'safelen' with
4784 /// the variable 'c'.
4785 ///
4787  friend class ASTStmtReader;
4789 
4790  /// Build directive with the given start and end location.
4791  ///
4792  /// \param StartLoc Starting location of the directive kind.
4793  /// \param EndLoc Ending location of the directive.
4794  /// \param CollapsedNum Number of collapsed nested loops.
4795  ///
4797  unsigned CollapsedNum)
4798  : OMPLoopDirective(OMPTargetSimdDirectiveClass,
4799  llvm::omp::OMPD_target_simd, StartLoc, EndLoc,
4800  CollapsedNum) {}
4801 
4802  /// Build an empty directive.
4803  ///
4804  /// \param CollapsedNum Number of collapsed nested loops.
4805  ///
4806  explicit OMPTargetSimdDirective(unsigned CollapsedNum)
4807  : OMPLoopDirective(OMPTargetSimdDirectiveClass,
4808  llvm::omp::OMPD_target_simd, SourceLocation(),
4809  SourceLocation(), CollapsedNum) {}
4810 
4811 public:
4812  /// Creates directive with a list of \a Clauses.
4813  ///
4814  /// \param C AST context.
4815  /// \param StartLoc Starting location of the directive kind.
4816  /// \param EndLoc Ending Location of the directive.
4817  /// \param CollapsedNum Number of collapsed loops.
4818  /// \param Clauses List of clauses.
4819  /// \param AssociatedStmt Statement, associated with the directive.
4820  /// \param Exprs Helper expressions for CodeGen.
4821  ///
4822  static OMPTargetSimdDirective *
4823  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4824  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4825  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4826 
4827  /// Creates an empty directive with the place for \a NumClauses clauses.
4828  ///
4829  /// \param C AST context.
4830  /// \param CollapsedNum Number of collapsed nested loops.
4831  /// \param NumClauses Number of clauses.
4832  ///
4833  static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C,
4834  unsigned NumClauses,
4835  unsigned CollapsedNum,
4836  EmptyShell);
4837 
4838  static bool classof(const Stmt *T) {
4839  return T->getStmtClass() == OMPTargetSimdDirectiveClass;
4840  }
4841 };
4842 
4843 /// This represents '#pragma omp teams distribute' directive.
4844 ///
4845 /// \code
4846 /// #pragma omp teams distribute private(a,b)
4847 /// \endcode
4848 /// In this example directive '#pragma omp teams distribute' has clauses
4849 /// 'private' with the variables 'a' and 'b'
4850 ///
4852  friend class ASTStmtReader;
4854 
4855  /// Build directive with the given start and end location.
4856  ///
4857  /// \param StartLoc Starting location of the directive kind.
4858  /// \param EndLoc Ending location of the directive.
4859  /// \param CollapsedNum Number of collapsed nested loops.
4860  ///
4862  unsigned CollapsedNum)
4863  : OMPLoopDirective(OMPTeamsDistributeDirectiveClass,
4864  llvm::omp::OMPD_teams_distribute, StartLoc, EndLoc,
4865  CollapsedNum) {}
4866 
4867  /// Build an empty directive.
4868  ///
4869  /// \param CollapsedNum Number of collapsed nested loops.
4870  ///
4871  explicit OMPTeamsDistributeDirective(unsigned CollapsedNum)
4872  : OMPLoopDirective(OMPTeamsDistributeDirectiveClass,
4873  llvm::omp::OMPD_teams_distribute, SourceLocation(),
4874  SourceLocation(), CollapsedNum) {}
4875 
4876 public:
4877  /// Creates directive with a list of \a Clauses.
4878  ///
4879  /// \param C AST context.
4880  /// \param StartLoc Starting location of the directive kind.
4881  /// \param EndLoc Ending Location of the directive.
4882  /// \param CollapsedNum Number of collapsed loops.
4883  /// \param Clauses List of clauses.
4884  /// \param AssociatedStmt Statement, associated with the directive.
4885  /// \param Exprs Helper expressions for CodeGen.
4886  ///
4887  static OMPTeamsDistributeDirective *
4888  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4889  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4890  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4891 
4892  /// Creates an empty directive with the place for \a NumClauses clauses.
4893  ///
4894  /// \param C AST context.
4895  /// \param CollapsedNum Number of collapsed nested loops.
4896  /// \param NumClauses Number of clauses.
4897  ///
4898  static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C,
4899  unsigned NumClauses,
4900  unsigned CollapsedNum,
4901  EmptyShell);
4902 
4903  static bool classof(const Stmt *T) {
4904  return T->getStmtClass() == OMPTeamsDistributeDirectiveClass;
4905  }
4906 };
4907 
4908 /// This represents '#pragma omp teams distribute simd'
4909 /// combined directive.
4910 ///
4911 /// \code
4912 /// #pragma omp teams distribute simd private(a,b)
4913 /// \endcode
4914 /// In this example directive '#pragma omp teams distribute simd'
4915 /// has clause 'private' with the variables 'a' and 'b'
4916 ///
4918  friend class ASTStmtReader;
4920 
4921  /// Build directive with the given start and end location.
4922  ///
4923  /// \param StartLoc Starting location of the directive kind.
4924  /// \param EndLoc Ending location of the directive.
4925  /// \param CollapsedNum Number of collapsed nested loops.
4926  ///
4928  SourceLocation EndLoc, unsigned CollapsedNum)
4929  : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass,
4930  llvm::omp::OMPD_teams_distribute_simd, StartLoc,
4931  EndLoc, CollapsedNum) {}
4932 
4933  /// Build an empty directive.
4934  ///
4935  /// \param CollapsedNum Number of collapsed nested loops.
4936  ///
4937  explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum)
4938  : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass,
4939  llvm::omp::OMPD_teams_distribute_simd,
4940  SourceLocation(), SourceLocation(), CollapsedNum) {}
4941 
4942 public:
4943  /// Creates directive with a list of \a Clauses.
4944  ///
4945  /// \param C AST context.
4946  /// \param StartLoc Starting location of the directive kind.
4947  /// \param EndLoc Ending Location of the directive.
4948  /// \param CollapsedNum Number of collapsed loops.
4949  /// \param Clauses List of clauses.
4950  /// \param AssociatedStmt Statement, associated with the directive.
4951  /// \param Exprs Helper expressions for CodeGen.
4952  ///
4953  static OMPTeamsDistributeSimdDirective *
4954  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4955  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4956  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4957 
4958  /// Creates an empty directive with the place
4959  /// for \a NumClauses clauses.
4960  ///
4961  /// \param C AST context.
4962  /// \param CollapsedNum Number of collapsed nested loops.
4963  /// \param NumClauses Number of clauses.
4964  ///
4965  static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C,
4966  unsigned NumClauses,
4967  unsigned CollapsedNum,
4968  EmptyShell);
4969 
4970  static bool classof(const Stmt *T) {
4971  return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass;
4972  }
4973 };
4974 
4975 /// This represents '#pragma omp teams distribute parallel for simd' composite
4976 /// directive.
4977 ///
4978 /// \code
4979 /// #pragma omp teams distribute parallel for simd private(x)
4980 /// \endcode
4981 /// In this example directive '#pragma omp teams distribute parallel for simd'
4982 /// has clause 'private' with the variables 'x'
4983 ///
4985  : public OMPLoopDirective {
4986  friend class ASTStmtReader;
4988 
4989  /// Build directive with the given start and end location.
4990  ///
4991  /// \param StartLoc Starting location of the directive kind.
4992  /// \param EndLoc Ending location of the directive.
4993  /// \param CollapsedNum Number of collapsed nested loops.
4994  ///
4996  SourceLocation EndLoc,
4997  unsigned CollapsedNum)
4998  : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass,
4999  llvm::omp::OMPD_teams_distribute_parallel_for_simd,
5000  StartLoc, EndLoc, CollapsedNum) {}
5001 
5002  /// Build an empty directive.
5003  ///
5004  /// \param CollapsedNum Number of collapsed nested loops.
5005  ///
5006  explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum)
5007  : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass,
5008  llvm::omp::OMPD_teams_distribute_parallel_for_simd,
5009  SourceLocation(), SourceLocation(), CollapsedNum) {}
5010 
5011 public:
5012  /// Creates directive with a list of \a Clauses.
5013  ///
5014  /// \param C AST context.
5015  /// \param StartLoc Starting location of the directive kind.
5016  /// \param EndLoc Ending Location of the directive.
5017  /// \param CollapsedNum Number of collapsed loops.
5018  /// \param Clauses List of clauses.
5019  /// \param AssociatedStmt Statement, associated with the directive.
5020  /// \param Exprs Helper expressions for CodeGen.
5021  ///
5022  static OMPTeamsDistributeParallelForSimdDirective *
5023  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5024  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5025  Stmt *AssociatedStmt, const HelperExprs &Exprs);
5026 
5027  /// Creates an empty directive with the place for \a NumClauses clauses.
5028  ///
5029  /// \param C AST context.
5030  /// \param CollapsedNum Number of collapsed nested loops.
5031  /// \param NumClauses Number of clauses.
5032  ///
5033  static OMPTeamsDistributeParallelForSimdDirective *
5034  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5035  EmptyShell);
5036 
5037  static bool classof(const Stmt *T) {
5038  return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass;
5039  }
5040 };
5041 
5042 /// This represents '#pragma omp teams distribute parallel for' composite
5043 /// directive.
5044 ///
5045 /// \code
5046 /// #pragma omp teams distribute parallel for private(x)
5047 /// \endcode
5048 /// In this example directive '#pragma omp teams distribute parallel for'
5049 /// has clause 'private' with the variables 'x'
5050 ///
5052  friend class ASTStmtReader;
5054  /// true if the construct has inner cancel directive.
5055  bool HasCancel = false;
5056 
5057  /// Build directive with the given start and end location.
5058  ///
5059  /// \param StartLoc Starting location of the directive kind.
5060  /// \param EndLoc Ending location of the directive.
5061  /// \param CollapsedNum Number of collapsed nested loops.
5062  ///
5064  SourceLocation EndLoc,
5065  unsigned CollapsedNum)
5066  : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass,
5067  llvm::omp::OMPD_teams_distribute_parallel_for,
5068  StartLoc, EndLoc, CollapsedNum) {}
5069 
5070  /// Build an empty directive.
5071  ///
5072  /// \param CollapsedNum Number of collapsed nested loops.
5073  ///
5074  explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum)
5075  : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass,
5076  llvm::omp::OMPD_teams_distribute_parallel_for,
5077  SourceLocation(), SourceLocation(), CollapsedNum) {}
5078 
5079  /// Sets special task reduction descriptor.
5080  void setTaskReductionRefExpr(Expr *E) {
5082  getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)] = E;
5083  }
5084 
5085  /// Set cancel state.
5086  void setHasCancel(bool Has) { HasCancel = Has; }
5087 
5088 public:
5089  /// Creates directive with a list of \a Clauses.
5090  ///
5091  /// \param C AST context.
5092  /// \param StartLoc Starting location of the directive kind.
5093  /// \param EndLoc Ending Location of the directive.
5094  /// \param CollapsedNum Number of collapsed loops.
5095  /// \param Clauses List of clauses.
5096  /// \param AssociatedStmt Statement, associated with the directive.
5097  /// \param Exprs Helper expressions for CodeGen.
5098  /// \param TaskRedRef Task reduction special reference expression to handle
5099  /// taskgroup descriptor.
5100  /// \param HasCancel true if this directive has inner cancel directive.
5101  ///
5102  static OMPTeamsDistributeParallelForDirective *
5103  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5104  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5105  Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
5106  bool HasCancel);
5107 
5108  /// Creates an empty directive with the place for \a NumClauses clauses.
5109  ///
5110  /// \param C AST context.
5111  /// \param CollapsedNum Number of collapsed nested loops.
5112  /// \param NumClauses Number of clauses.
5113  ///
5114  static OMPTeamsDistributeParallelForDirective *
5115  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5116  EmptyShell);
5117 
5118  /// Returns special task reduction reference expression.
5120  return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
5121  getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)]);
5122  }
5124  return const_cast<OMPTeamsDistributeParallelForDirective *>(this)
5125  ->