clang  16.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 llvm::None;
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 {used_clauses_child_iterator(Clauses),
403  used_clauses_child_iterator(llvm::makeArrayRef(Clauses.end(), 0))};
404  }
405 
406  /// Iterates over a filtered subrange of clauses applied to a
407  /// directive.
408  ///
409  /// This iterator visits only clauses of type SpecificClause.
410  template <typename SpecificClause>
412  : public llvm::iterator_adaptor_base<
413  specific_clause_iterator<SpecificClause>,
414  ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag,
415  const SpecificClause *, ptrdiff_t, const SpecificClause *,
416  const SpecificClause *> {
418 
419  void SkipToNextClause() {
420  while (this->I != End && !isa<SpecificClause>(*this->I))
421  ++this->I;
422  }
423 
424  public:
426  : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()),
427  End(Clauses.end()) {
428  SkipToNextClause();
429  }
430 
431  const SpecificClause *operator*() const {
432  return cast<SpecificClause>(*this->I);
433  }
434  const SpecificClause *operator->() const { return **this; }
435 
437  ++this->I;
438  SkipToNextClause();
439  return *this;
440  }
441  };
442 
443  template <typename SpecificClause>
444  static llvm::iterator_range<specific_clause_iterator<SpecificClause>>
448  llvm::makeArrayRef(Clauses.end(), 0))};
449  }
450 
451  template <typename SpecificClause>
452  llvm::iterator_range<specific_clause_iterator<SpecificClause>>
454  return getClausesOfKind<SpecificClause>(clauses());
455  }
456 
457  /// Gets a single clause of the specified kind associated with the
458  /// current directive iff there is only one clause of this kind (and assertion
459  /// is fired if there is more than one clause is associated with the
460  /// directive). Returns nullptr if no clause of this kind is associated with
461  /// the directive.
462  template <typename SpecificClause>
463  static const SpecificClause *getSingleClause(ArrayRef<OMPClause *> Clauses) {
464  auto ClausesOfKind = getClausesOfKind<SpecificClause>(Clauses);
465 
466  if (ClausesOfKind.begin() != ClausesOfKind.end()) {
467  assert(std::next(ClausesOfKind.begin()) == ClausesOfKind.end() &&
468  "There are at least 2 clauses of the specified kind");
469  return *ClausesOfKind.begin();
470  }
471  return nullptr;
472  }
473 
474  template <typename SpecificClause>
475  const SpecificClause *getSingleClause() const {
476  return getSingleClause<SpecificClause>(clauses());
477  }
478 
479  /// Returns true if the current directive has one or more clauses of a
480  /// specific kind.
481  template <typename SpecificClause>
482  bool hasClausesOfKind() const {
483  auto Clauses = getClausesOfKind<SpecificClause>();
484  return Clauses.begin() != Clauses.end();
485  }
486 
487  /// Returns starting location of directive kind.
488  SourceLocation getBeginLoc() const { return StartLoc; }
489  /// Returns ending location of directive.
490  SourceLocation getEndLoc() const { return EndLoc; }
491 
492  /// Set starting location of directive kind.
493  ///
494  /// \param Loc New starting location of directive.
495  ///
496  void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
497  /// Set ending location of directive.
498  ///
499  /// \param Loc New ending location of directive.
500  ///
501  void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
502 
503  /// Get number of clauses.
504  unsigned getNumClauses() const {
505  if (!Data)
506  return 0;
507  return Data->getNumClauses();
508  }
509 
510  /// Returns specified clause.
511  ///
512  /// \param I Number of clause.
513  ///
514  OMPClause *getClause(unsigned I) const { return clauses()[I]; }
515 
516  /// Returns true if directive has associated statement.
517  bool hasAssociatedStmt() const { return Data && Data->hasAssociatedStmt(); }
518 
519  /// Returns statement associated with the directive.
520  const Stmt *getAssociatedStmt() const {
521  return const_cast<OMPExecutableDirective *>(this)->getAssociatedStmt();
522  }
524  assert(hasAssociatedStmt() &&
525  "Expected directive with the associated statement.");
526  return Data->getAssociatedStmt();
527  }
528 
529  /// Returns the captured statement associated with the
530  /// component region within the (combined) directive.
531  ///
532  /// \param RegionKind Component region kind.
534  assert(hasAssociatedStmt() &&
535  "Expected directive with the associated statement.");
537  getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
538  return Data->getCapturedStmt(RegionKind, CaptureRegions);
539  }
540 
541  /// Get innermost captured statement for the construct.
543  assert(hasAssociatedStmt() &&
544  "Expected directive with the associated statement.");
546  getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
547  return Data->getInnermostCapturedStmt(CaptureRegions);
548  }
549 
551  return const_cast<OMPExecutableDirective *>(this)
553  }
554 
555  OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
556 
557  static bool classof(const Stmt *S) {
558  return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
559  S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
560  }
561 
563  if (!Data)
565  return Data->getAssociatedStmtAsRange();
566  }
567 
569  return const_cast<OMPExecutableDirective *>(this)->children();
570  }
571 
573  if (!Data)
574  return llvm::None;
575  return Data->getClauses();
576  }
577 
578  /// Returns whether or not this is a Standalone directive.
579  ///
580  /// Stand-alone directives are executable directives
581  /// that have no associated user code.
582  bool isStandaloneDirective() const;
583 
584  /// Returns the AST node representing OpenMP structured-block of this
585  /// OpenMP executable directive,
586  /// Prerequisite: Executable Directive must not be Standalone directive.
587  const Stmt *getStructuredBlock() const {
588  return const_cast<OMPExecutableDirective *>(this)->getStructuredBlock();
589  }
591 
592  const Stmt *getRawStmt() const {
593  return const_cast<OMPExecutableDirective *>(this)->getRawStmt();
594  }
596  assert(hasAssociatedStmt() &&
597  "Expected directive with the associated statement.");
598  return Data->getRawStmt();
599  }
600 };
601 
602 /// This represents '#pragma omp parallel' directive.
603 ///
604 /// \code
605 /// #pragma omp parallel private(a,b) reduction(+: c,d)
606 /// \endcode
607 /// In this example directive '#pragma omp parallel' has clauses 'private'
608 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
609 /// variables 'c' and 'd'.
610 ///
612  friend class ASTStmtReader;
614  /// true if the construct has inner cancel directive.
615  bool HasCancel = false;
616 
617  /// Build directive with the given start and end location.
618  ///
619  /// \param StartLoc Starting location of the directive (directive keyword).
620  /// \param EndLoc Ending Location of the directive.
621  ///
623  : OMPExecutableDirective(OMPParallelDirectiveClass,
624  llvm::omp::OMPD_parallel, StartLoc, EndLoc) {}
625 
626  /// Build an empty directive.
627  ///
628  explicit OMPParallelDirective()
629  : OMPExecutableDirective(OMPParallelDirectiveClass,
630  llvm::omp::OMPD_parallel, SourceLocation(),
631  SourceLocation()) {}
632 
633  /// Sets special task reduction descriptor.
634  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
635 
636  /// Set cancel state.
637  void setHasCancel(bool Has) { HasCancel = Has; }
638 
639 public:
640  /// Creates directive with a list of \a Clauses.
641  ///
642  /// \param C AST context.
643  /// \param StartLoc Starting location of the directive kind.
644  /// \param EndLoc Ending Location of the directive.
645  /// \param Clauses List of clauses.
646  /// \param AssociatedStmt Statement associated with the directive.
647  /// \param TaskRedRef Task reduction special reference expression to handle
648  /// taskgroup descriptor.
649  /// \param HasCancel true if this directive has inner cancel directive.
650  ///
651  static OMPParallelDirective *
652  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
653  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
654  bool HasCancel);
655 
656  /// Creates an empty directive with the place for \a N clauses.
657  ///
658  /// \param C AST context.
659  /// \param NumClauses Number of clauses.
660  ///
661  static OMPParallelDirective *CreateEmpty(const ASTContext &C,
662  unsigned NumClauses, EmptyShell);
663 
664  /// Returns special task reduction reference expression.
666  return cast_or_null<Expr>(Data->getChildren()[0]);
667  }
668  const Expr *getTaskReductionRefExpr() const {
669  return const_cast<OMPParallelDirective *>(this)->getTaskReductionRefExpr();
670  }
671 
672  /// Return true if current directive has inner cancel directive.
673  bool hasCancel() const { return HasCancel; }
674 
675  static bool classof(const Stmt *T) {
676  return T->getStmtClass() == OMPParallelDirectiveClass;
677  }
678 };
679 
680 /// The base class for all loop-based directives, including loop transformation
681 /// directives.
683  friend class ASTStmtReader;
684 
685 protected:
686  /// Number of collapsed loops as specified by 'collapse' clause.
687  unsigned NumAssociatedLoops = 0;
688 
689  /// Build instance of loop directive of class \a Kind.
690  ///
691  /// \param SC Statement class.
692  /// \param Kind Kind of OpenMP directive.
693  /// \param StartLoc Starting location of the directive (directive keyword).
694  /// \param EndLoc Ending location of the directive.
695  /// \param NumAssociatedLoops Number of loops associated with the construct.
696  ///
698  SourceLocation StartLoc, SourceLocation EndLoc,
699  unsigned NumAssociatedLoops)
700  : OMPExecutableDirective(SC, Kind, StartLoc, EndLoc),
702 
703 public:
704  /// The expressions built to support OpenMP loops in combined/composite
705  /// pragmas (e.g. pragma omp distribute parallel for)
707  /// DistributeLowerBound - used when composing 'omp distribute' with
708  /// 'omp for' in a same construct.
710  /// DistributeUpperBound - used when composing 'omp distribute' with
711  /// 'omp for' in a same construct.
713  /// DistributeEnsureUpperBound - used when composing 'omp distribute'
714  /// with 'omp for' in a same construct, EUB depends on DistUB
716  /// Distribute loop iteration variable init used when composing 'omp
717  /// distribute'
718  /// with 'omp for' in a same construct
720  /// Distribute Loop condition used when composing 'omp distribute'
721  /// with 'omp for' in a same construct
723  /// Update of LowerBound for statically scheduled omp loops for
724  /// outer loop in combined constructs (e.g. 'distribute parallel for')
726  /// Update of UpperBound for statically scheduled omp loops for
727  /// outer loop in combined constructs (e.g. 'distribute parallel for')
729  /// Distribute Loop condition used when composing 'omp distribute'
730  /// with 'omp for' in a same construct when schedule is chunked.
732  /// 'omp parallel for' loop condition used when composed with
733  /// 'omp distribute' in the same construct and when schedule is
734  /// chunked and the chunk size is 1.
736  };
737 
738  /// The expressions built for the OpenMP loop CodeGen for the
739  /// whole collapsed loop nest.
740  struct HelperExprs {
741  /// Loop iteration variable.
743  /// Loop last iteration number.
745  /// Loop number of iterations.
747  /// Calculation of last iteration.
749  /// Loop pre-condition.
751  /// Loop condition.
753  /// Loop iteration variable init.
755  /// Loop increment.
757  /// IsLastIteration - local flag variable passed to runtime.
759  /// LowerBound - local variable passed to runtime.
761  /// UpperBound - local variable passed to runtime.
763  /// Stride - local variable passed to runtime.
765  /// EnsureUpperBound -- expression UB = min(UB, NumIterations).
767  /// Update of LowerBound for statically scheduled 'omp for' loops.
769  /// Update of UpperBound for statically scheduled 'omp for' loops.
771  /// PreviousLowerBound - local variable passed to runtime in the
772  /// enclosing schedule or null if that does not apply.
774  /// PreviousUpperBound - local variable passed to runtime in the
775  /// enclosing schedule or null if that does not apply.
777  /// DistInc - increment expression for distribute loop when found
778  /// combined with a further loop level (e.g. in 'distribute parallel for')
779  /// expression IV = IV + ST
781  /// PrevEUB - expression similar to EUB but to be used when loop
782  /// scheduling uses PrevLB and PrevUB (e.g. in 'distribute parallel for'
783  /// when ensuring that the UB is either the calculated UB by the runtime or
784  /// the end of the assigned distribute chunk)
785  /// expression UB = min (UB, PrevUB)
787  /// Counters Loop counters.
789  /// PrivateCounters Loop counters.
791  /// Expressions for loop counters inits for CodeGen.
793  /// Expressions for loop counters update for CodeGen.
795  /// Final loop counter values for GodeGen.
797  /// List of counters required for the generation of the non-rectangular
798  /// loops.
800  /// List of initializers required for the generation of the non-rectangular
801  /// loops.
803  /// List of final conditions required for the generation of the
804  /// non-rectangular loops.
806  /// Init statement for all captured expressions.
808 
809  /// Expressions used when combining OpenMP loop pragmas
811 
812  /// Check if all the expressions are built (does not check the
813  /// worksharing ones).
814  bool builtAll() {
815  return IterationVarRef != nullptr && LastIteration != nullptr &&
816  NumIterations != nullptr && PreCond != nullptr &&
817  Cond != nullptr && Init != nullptr && Inc != nullptr;
818  }
819 
820  /// Initialize all the fields to null.
821  /// \param Size Number of elements in the
822  /// counters/finals/updates/dependent_counters/dependent_inits/finals_conditions
823  /// arrays.
824  void clear(unsigned Size) {
825  IterationVarRef = nullptr;
826  LastIteration = nullptr;
827  CalcLastIteration = nullptr;
828  PreCond = nullptr;
829  Cond = nullptr;
830  Init = nullptr;
831  Inc = nullptr;
832  IL = nullptr;
833  LB = nullptr;
834  UB = nullptr;
835  ST = nullptr;
836  EUB = nullptr;
837  NLB = nullptr;
838  NUB = nullptr;
839  NumIterations = nullptr;
840  PrevLB = nullptr;
841  PrevUB = nullptr;
842  DistInc = nullptr;
843  PrevEUB = nullptr;
844  Counters.resize(Size);
845  PrivateCounters.resize(Size);
846  Inits.resize(Size);
847  Updates.resize(Size);
848  Finals.resize(Size);
849  DependentCounters.resize(Size);
850  DependentInits.resize(Size);
851  FinalsConditions.resize(Size);
852  for (unsigned I = 0; I < Size; ++I) {
853  Counters[I] = nullptr;
854  PrivateCounters[I] = nullptr;
855  Inits[I] = nullptr;
856  Updates[I] = nullptr;
857  Finals[I] = nullptr;
858  DependentCounters[I] = nullptr;
859  DependentInits[I] = nullptr;
860  FinalsConditions[I] = nullptr;
861  }
862  PreInits = nullptr;
863  DistCombinedFields.LB = nullptr;
864  DistCombinedFields.UB = nullptr;
865  DistCombinedFields.EUB = nullptr;
866  DistCombinedFields.Init = nullptr;
867  DistCombinedFields.Cond = nullptr;
868  DistCombinedFields.NLB = nullptr;
869  DistCombinedFields.NUB = nullptr;
870  DistCombinedFields.DistCond = nullptr;
872  }
873  };
874 
875  /// Get number of collapsed loops.
876  unsigned getLoopsNumber() const { return NumAssociatedLoops; }
877 
878  /// Try to find the next loop sub-statement in the specified statement \p
879  /// CurStmt.
880  /// \param TryImperfectlyNestedLoops true, if we need to try to look for the
881  /// imperfectly nested loop.
882  static Stmt *tryToFindNextInnerLoop(Stmt *CurStmt,
883  bool TryImperfectlyNestedLoops);
884  static const Stmt *tryToFindNextInnerLoop(const Stmt *CurStmt,
885  bool TryImperfectlyNestedLoops) {
886  return tryToFindNextInnerLoop(const_cast<Stmt *>(CurStmt),
887  TryImperfectlyNestedLoops);
888  }
889 
890  /// Calls the specified callback function for all the loops in \p CurStmt,
891  /// from the outermost to the innermost.
892  static bool
893  doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
894  unsigned NumLoops,
895  llvm::function_ref<bool(unsigned, Stmt *)> Callback,
896  llvm::function_ref<void(OMPLoopTransformationDirective *)>
897  OnTransformationCallback);
898  static bool
899  doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
900  unsigned NumLoops,
901  llvm::function_ref<bool(unsigned, const Stmt *)> Callback,
902  llvm::function_ref<void(const OMPLoopTransformationDirective *)>
903  OnTransformationCallback) {
904  auto &&NewCallback = [Callback](unsigned Cnt, Stmt *CurStmt) {
905  return Callback(Cnt, CurStmt);
906  };
907  auto &&NewTransformCb =
908  [OnTransformationCallback](OMPLoopTransformationDirective *A) {
909  OnTransformationCallback(A);
910  };
911  return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
912  NumLoops, NewCallback, NewTransformCb);
913  }
914 
915  /// Calls the specified callback function for all the loops in \p CurStmt,
916  /// from the outermost to the innermost.
917  static bool
918  doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops,
919  unsigned NumLoops,
920  llvm::function_ref<bool(unsigned, Stmt *)> Callback) {
921  auto &&TransformCb = [](OMPLoopTransformationDirective *) {};
922  return doForAllLoops(CurStmt, TryImperfectlyNestedLoops, NumLoops, Callback,
923  TransformCb);
924  }
925  static bool
926  doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops,
927  unsigned NumLoops,
928  llvm::function_ref<bool(unsigned, const Stmt *)> Callback) {
929  auto &&NewCallback = [Callback](unsigned Cnt, const Stmt *CurStmt) {
930  return Callback(Cnt, CurStmt);
931  };
932  return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
933  NumLoops, NewCallback);
934  }
935 
936  /// Calls the specified callback function for all the loop bodies in \p
937  /// CurStmt, from the outermost loop to the innermost.
938  static void doForAllLoopsBodies(
939  Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops,
940  llvm::function_ref<void(unsigned, Stmt *, Stmt *)> Callback);
941  static void doForAllLoopsBodies(
942  const Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops,
943  llvm::function_ref<void(unsigned, const Stmt *, const Stmt *)> Callback) {
944  auto &&NewCallback = [Callback](unsigned Cnt, Stmt *Loop, Stmt *Body) {
945  Callback(Cnt, Loop, Body);
946  };
947  doForAllLoopsBodies(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops,
948  NumLoops, NewCallback);
949  }
950 
951  static bool classof(const Stmt *T) {
952  if (auto *D = dyn_cast<OMPExecutableDirective>(T))
953  return isOpenMPLoopDirective(D->getDirectiveKind());
954  return false;
955  }
956 };
957 
958 /// The base class for all loop transformation directives.
960  friend class ASTStmtReader;
961 
962  /// Number of loops generated by this loop transformation.
963  unsigned NumGeneratedLoops = 0;
964 
965 protected:
968  SourceLocation StartLoc,
969  SourceLocation EndLoc,
970  unsigned NumAssociatedLoops)
971  : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, NumAssociatedLoops) {}
972 
973  /// Set the number of loops generated by this loop transformation.
974  void setNumGeneratedLoops(unsigned Num) { NumGeneratedLoops = Num; }
975 
976 public:
977  /// Return the number of associated (consumed) loops.
978  unsigned getNumAssociatedLoops() const { return getLoopsNumber(); }
979 
980  /// Return the number of loops generated by this loop transformation.
981  unsigned getNumGeneratedLoops() { return NumGeneratedLoops; }
982 
983  /// Get the de-sugared statements after after the loop transformation.
984  ///
985  /// Might be nullptr if either the directive generates no loops and is handled
986  /// directly in CodeGen, or resolving a template-dependence context is
987  /// required.
988  Stmt *getTransformedStmt() const;
989 
990  /// Return preinits statement.
991  Stmt *getPreInits() const;
992 
993  static bool classof(const Stmt *T) {
994  return T->getStmtClass() == OMPTileDirectiveClass ||
995  T->getStmtClass() == OMPUnrollDirectiveClass;
996  }
997 };
998 
999 /// This is a common base class for loop directives ('omp simd', 'omp
1000 /// for', 'omp for simd' etc.). It is responsible for the loop code generation.
1001 ///
1003  friend class ASTStmtReader;
1004 
1005  /// Offsets to the stored exprs.
1006  /// This enumeration contains offsets to all the pointers to children
1007  /// expressions stored in OMPLoopDirective.
1008  /// The first 9 children are necessary for all the loop directives,
1009  /// the next 8 are specific to the worksharing ones, and the next 11 are
1010  /// used for combined constructs containing two pragmas associated to loops.
1011  /// After the fixed children, three arrays of length NumAssociatedLoops are
1012  /// allocated: loop counters, their updates and final values.
1013  /// PrevLowerBound and PrevUpperBound are used to communicate blocking
1014  /// information in composite constructs which require loop blocking
1015  /// DistInc is used to generate the increment expression for the distribute
1016  /// loop when combined with a further nested loop
1017  /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the
1018  /// for loop when combined with a previous distribute loop in the same pragma
1019  /// (e.g. 'distribute parallel for')
1020  ///
1021  enum {
1022  IterationVariableOffset = 0,
1023  LastIterationOffset = 1,
1024  CalcLastIterationOffset = 2,
1025  PreConditionOffset = 3,
1026  CondOffset = 4,
1027  InitOffset = 5,
1028  IncOffset = 6,
1029  PreInitsOffset = 7,
1030  // The '...End' enumerators do not correspond to child expressions - they
1031  // specify the offset to the end (and start of the following counters/
1032  // updates/finals/dependent_counters/dependent_inits/finals_conditions
1033  // arrays).
1034  DefaultEnd = 8,
1035  // The following 8 exprs are used by worksharing and distribute loops only.
1036  IsLastIterVariableOffset = 8,
1037  LowerBoundVariableOffset = 9,
1038  UpperBoundVariableOffset = 10,
1039  StrideVariableOffset = 11,
1040  EnsureUpperBoundOffset = 12,
1041  NextLowerBoundOffset = 13,
1042  NextUpperBoundOffset = 14,
1043  NumIterationsOffset = 15,
1044  // Offset to the end for worksharing loop directives.
1045  WorksharingEnd = 16,
1046  PrevLowerBoundVariableOffset = 16,
1047  PrevUpperBoundVariableOffset = 17,
1048  DistIncOffset = 18,
1049  PrevEnsureUpperBoundOffset = 19,
1050  CombinedLowerBoundVariableOffset = 20,
1051  CombinedUpperBoundVariableOffset = 21,
1052  CombinedEnsureUpperBoundOffset = 22,
1053  CombinedInitOffset = 23,
1054  CombinedConditionOffset = 24,
1055  CombinedNextLowerBoundOffset = 25,
1056  CombinedNextUpperBoundOffset = 26,
1057  CombinedDistConditionOffset = 27,
1058  CombinedParForInDistConditionOffset = 28,
1059  // Offset to the end (and start of the following
1060  // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions
1061  // arrays) for combined distribute loop directives.
1062  CombinedDistributeEnd = 29,
1063  };
1064 
1065  /// Get the counters storage.
1066  MutableArrayRef<Expr *> getCounters() {
1067  auto **Storage = reinterpret_cast<Expr **>(
1069  return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
1070  }
1071 
1072  /// Get the private counters storage.
1073  MutableArrayRef<Expr *> getPrivateCounters() {
1074  auto **Storage = reinterpret_cast<Expr **>(
1076  getLoopsNumber()]);
1077  return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
1078  }
1079 
1080  /// Get the updates storage.
1081  MutableArrayRef<Expr *> getInits() {
1082  auto **Storage = reinterpret_cast<Expr **>(
1084  2 * getLoopsNumber()]);
1085  return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
1086  }
1087 
1088  /// Get the updates storage.
1089  MutableArrayRef<Expr *> getUpdates() {
1090  auto **Storage = reinterpret_cast<Expr **>(
1092  3 * getLoopsNumber()]);
1093  return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
1094  }
1095 
1096  /// Get the final counter updates storage.
1097  MutableArrayRef<Expr *> getFinals() {
1098  auto **Storage = reinterpret_cast<Expr **>(
1100  4 * getLoopsNumber()]);
1101  return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
1102  }
1103 
1104  /// Get the dependent counters storage.
1105  MutableArrayRef<Expr *> getDependentCounters() {
1106  auto **Storage = reinterpret_cast<Expr **>(
1108  5 * getLoopsNumber()]);
1109  return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
1110  }
1111 
1112  /// Get the dependent inits storage.
1113  MutableArrayRef<Expr *> getDependentInits() {
1114  auto **Storage = reinterpret_cast<Expr **>(
1116  6 * getLoopsNumber()]);
1117  return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
1118  }
1119 
1120  /// Get the finals conditions storage.
1121  MutableArrayRef<Expr *> getFinalsConditions() {
1122  auto **Storage = reinterpret_cast<Expr **>(
1124  7 * getLoopsNumber()]);
1125  return llvm::makeMutableArrayRef(Storage, getLoopsNumber());
1126  }
1127 
1128 protected:
1129  /// Build instance of loop directive of class \a Kind.
1130  ///
1131  /// \param SC Statement class.
1132  /// \param Kind Kind of OpenMP directive.
1133  /// \param StartLoc Starting location of the directive (directive keyword).
1134  /// \param EndLoc Ending location of the directive.
1135  /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
1136  ///
1138  SourceLocation StartLoc, SourceLocation EndLoc,
1139  unsigned CollapsedNum)
1140  : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, CollapsedNum) {}
1141 
1142  /// Offset to the start of children expression arrays.
1145  return CombinedDistributeEnd;
1148  return WorksharingEnd;
1149  return DefaultEnd;
1150  }
1151 
1152  /// Children number.
1153  static unsigned numLoopChildren(unsigned CollapsedNum,
1155  return getArraysOffset(Kind) +
1156  8 * CollapsedNum; // Counters, PrivateCounters, Inits,
1157  // Updates, Finals, DependentCounters,
1158  // DependentInits, FinalsConditions.
1159  }
1160 
1162  Data->getChildren()[IterationVariableOffset] = IV;
1163  }
1165  Data->getChildren()[LastIterationOffset] = LI;
1166  }
1168  Data->getChildren()[CalcLastIterationOffset] = CLI;
1169  }
1170  void setPreCond(Expr *PC) { Data->getChildren()[PreConditionOffset] = PC; }
1171  void setCond(Expr *Cond) { Data->getChildren()[CondOffset] = Cond; }
1172  void setInit(Expr *Init) { Data->getChildren()[InitOffset] = Init; }
1173  void setInc(Expr *Inc) { Data->getChildren()[IncOffset] = Inc; }
1174  void setPreInits(Stmt *PreInits) {
1175  Data->getChildren()[PreInitsOffset] = PreInits;
1176  }
1182  "expected worksharing loop directive");
1183  Data->getChildren()[IsLastIterVariableOffset] = IL;
1184  }
1190  "expected worksharing loop directive");
1191  Data->getChildren()[LowerBoundVariableOffset] = LB;
1192  }
1198  "expected worksharing loop directive");
1199  Data->getChildren()[UpperBoundVariableOffset] = UB;
1200  }
1206  "expected worksharing loop directive");
1207  Data->getChildren()[StrideVariableOffset] = ST;
1208  }
1214  "expected worksharing loop directive");
1215  Data->getChildren()[EnsureUpperBoundOffset] = EUB;
1216  }
1222  "expected worksharing loop directive");
1223  Data->getChildren()[NextLowerBoundOffset] = NLB;
1224  }
1230  "expected worksharing loop directive");
1231  Data->getChildren()[NextUpperBoundOffset] = NUB;
1232  }
1238  "expected worksharing loop directive");
1239  Data->getChildren()[NumIterationsOffset] = NI;
1240  }
1243  "expected loop bound sharing directive");
1244  Data->getChildren()[PrevLowerBoundVariableOffset] = PrevLB;
1245  }
1248  "expected loop bound sharing directive");
1249  Data->getChildren()[PrevUpperBoundVariableOffset] = PrevUB;
1250  }
1251  void setDistInc(Expr *DistInc) {
1253  "expected loop bound sharing directive");
1254  Data->getChildren()[DistIncOffset] = DistInc;
1255  }
1258  "expected loop bound sharing directive");
1259  Data->getChildren()[PrevEnsureUpperBoundOffset] = PrevEUB;
1260  }
1263  "expected loop bound sharing directive");
1264  Data->getChildren()[CombinedLowerBoundVariableOffset] = CombLB;
1265  }
1268  "expected loop bound sharing directive");
1269  Data->getChildren()[CombinedUpperBoundVariableOffset] = CombUB;
1270  }
1273  "expected loop bound sharing directive");
1274  Data->getChildren()[CombinedEnsureUpperBoundOffset] = CombEUB;
1275  }
1276  void setCombinedInit(Expr *CombInit) {
1278  "expected loop bound sharing directive");
1279  Data->getChildren()[CombinedInitOffset] = CombInit;
1280  }
1281  void setCombinedCond(Expr *CombCond) {
1283  "expected loop bound sharing directive");
1284  Data->getChildren()[CombinedConditionOffset] = CombCond;
1285  }
1288  "expected loop bound sharing directive");
1289  Data->getChildren()[CombinedNextLowerBoundOffset] = CombNLB;
1290  }
1293  "expected loop bound sharing directive");
1294  Data->getChildren()[CombinedNextUpperBoundOffset] = CombNUB;
1295  }
1296  void setCombinedDistCond(Expr *CombDistCond) {
1298  "expected loop bound distribute sharing directive");
1299  Data->getChildren()[CombinedDistConditionOffset] = CombDistCond;
1300  }
1301  void setCombinedParForInDistCond(Expr *CombParForInDistCond) {
1303  "expected loop bound distribute sharing directive");
1304  Data->getChildren()[CombinedParForInDistConditionOffset] =
1305  CombParForInDistCond;
1306  }
1307  void setCounters(ArrayRef<Expr *> A);
1309  void setInits(ArrayRef<Expr *> A);
1310  void setUpdates(ArrayRef<Expr *> A);
1311  void setFinals(ArrayRef<Expr *> A);
1315 
1316 public:
1318  return cast<Expr>(Data->getChildren()[IterationVariableOffset]);
1319  }
1321  return cast<Expr>(Data->getChildren()[LastIterationOffset]);
1322  }
1324  return cast<Expr>(Data->getChildren()[CalcLastIterationOffset]);
1325  }
1326  Expr *getPreCond() const {
1327  return cast<Expr>(Data->getChildren()[PreConditionOffset]);
1328  }
1329  Expr *getCond() const { return cast<Expr>(Data->getChildren()[CondOffset]); }
1330  Expr *getInit() const { return cast<Expr>(Data->getChildren()[InitOffset]); }
1331  Expr *getInc() const { return cast<Expr>(Data->getChildren()[IncOffset]); }
1332  const Stmt *getPreInits() const {
1333  return Data->getChildren()[PreInitsOffset];
1334  }
1335  Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; }
1341  "expected worksharing loop directive");
1342  return cast<Expr>(Data->getChildren()[IsLastIterVariableOffset]);
1343  }
1349  "expected worksharing loop directive");
1350  return cast<Expr>(Data->getChildren()[LowerBoundVariableOffset]);
1351  }
1357  "expected worksharing loop directive");
1358  return cast<Expr>(Data->getChildren()[UpperBoundVariableOffset]);
1359  }
1365  "expected worksharing loop directive");
1366  return cast<Expr>(Data->getChildren()[StrideVariableOffset]);
1367  }
1373  "expected worksharing loop directive");
1374  return cast<Expr>(Data->getChildren()[EnsureUpperBoundOffset]);
1375  }
1381  "expected worksharing loop directive");
1382  return cast<Expr>(Data->getChildren()[NextLowerBoundOffset]);
1383  }
1389  "expected worksharing loop directive");
1390  return cast<Expr>(Data->getChildren()[NextUpperBoundOffset]);
1391  }
1397  "expected worksharing loop directive");
1398  return cast<Expr>(Data->getChildren()[NumIterationsOffset]);
1399  }
1402  "expected loop bound sharing directive");
1403  return cast<Expr>(Data->getChildren()[PrevLowerBoundVariableOffset]);
1404  }
1407  "expected loop bound sharing directive");
1408  return cast<Expr>(Data->getChildren()[PrevUpperBoundVariableOffset]);
1409  }
1410  Expr *getDistInc() const {
1412  "expected loop bound sharing directive");
1413  return cast<Expr>(Data->getChildren()[DistIncOffset]);
1414  }
1417  "expected loop bound sharing directive");
1418  return cast<Expr>(Data->getChildren()[PrevEnsureUpperBoundOffset]);
1419  }
1422  "expected loop bound sharing directive");
1423  return cast<Expr>(Data->getChildren()[CombinedLowerBoundVariableOffset]);
1424  }
1427  "expected loop bound sharing directive");
1428  return cast<Expr>(Data->getChildren()[CombinedUpperBoundVariableOffset]);
1429  }
1432  "expected loop bound sharing directive");
1433  return cast<Expr>(Data->getChildren()[CombinedEnsureUpperBoundOffset]);
1434  }
1437  "expected loop bound sharing directive");
1438  return cast<Expr>(Data->getChildren()[CombinedInitOffset]);
1439  }
1442  "expected loop bound sharing directive");
1443  return cast<Expr>(Data->getChildren()[CombinedConditionOffset]);
1444  }
1447  "expected loop bound sharing directive");
1448  return cast<Expr>(Data->getChildren()[CombinedNextLowerBoundOffset]);
1449  }
1452  "expected loop bound sharing directive");
1453  return cast<Expr>(Data->getChildren()[CombinedNextUpperBoundOffset]);
1454  }
1457  "expected loop bound distribute sharing directive");
1458  return cast<Expr>(Data->getChildren()[CombinedDistConditionOffset]);
1459  }
1462  "expected loop bound distribute sharing directive");
1463  return cast<Expr>(Data->getChildren()[CombinedParForInDistConditionOffset]);
1464  }
1465  Stmt *getBody();
1466  const Stmt *getBody() const {
1467  return const_cast<OMPLoopDirective *>(this)->getBody();
1468  }
1469 
1470  ArrayRef<Expr *> counters() { return getCounters(); }
1471 
1473  return const_cast<OMPLoopDirective *>(this)->getCounters();
1474  }
1475 
1476  ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
1477 
1479  return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
1480  }
1481 
1482  ArrayRef<Expr *> inits() { return getInits(); }
1483 
1485  return const_cast<OMPLoopDirective *>(this)->getInits();
1486  }
1487 
1488  ArrayRef<Expr *> updates() { return getUpdates(); }
1489 
1491  return const_cast<OMPLoopDirective *>(this)->getUpdates();
1492  }
1493 
1494  ArrayRef<Expr *> finals() { return getFinals(); }
1495 
1497  return const_cast<OMPLoopDirective *>(this)->getFinals();
1498  }
1499 
1500  ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); }
1501 
1503  return const_cast<OMPLoopDirective *>(this)->getDependentCounters();
1504  }
1505 
1506  ArrayRef<Expr *> dependent_inits() { return getDependentInits(); }
1507 
1509  return const_cast<OMPLoopDirective *>(this)->getDependentInits();
1510  }
1511 
1512  ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); }
1513 
1515  return const_cast<OMPLoopDirective *>(this)->getFinalsConditions();
1516  }
1517 
1518  static bool classof(const Stmt *T) {
1519  return T->getStmtClass() == OMPSimdDirectiveClass ||
1520  T->getStmtClass() == OMPForDirectiveClass ||
1521  T->getStmtClass() == OMPForSimdDirectiveClass ||
1522  T->getStmtClass() == OMPParallelForDirectiveClass ||
1523  T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
1524  T->getStmtClass() == OMPTaskLoopDirectiveClass ||
1525  T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
1526  T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass ||
1527  T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass ||
1528  T->getStmtClass() == OMPMasterTaskLoopDirectiveClass ||
1529  T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass ||
1530  T->getStmtClass() == OMPGenericLoopDirectiveClass ||
1531  T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass ||
1532  T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass ||
1533  T->getStmtClass() == OMPParallelGenericLoopDirectiveClass ||
1534  T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass ||
1535  T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass ||
1536  T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass ||
1537  T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass ||
1538  T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass ||
1539  T->getStmtClass() == OMPDistributeDirectiveClass ||
1540  T->getStmtClass() == OMPTargetParallelForDirectiveClass ||
1541  T->getStmtClass() == OMPDistributeParallelForDirectiveClass ||
1542  T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass ||
1543  T->getStmtClass() == OMPDistributeSimdDirectiveClass ||
1544  T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass ||
1545  T->getStmtClass() == OMPTargetSimdDirectiveClass ||
1546  T->getStmtClass() == OMPTeamsDistributeDirectiveClass ||
1547  T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass ||
1548  T->getStmtClass() ==
1549  OMPTeamsDistributeParallelForSimdDirectiveClass ||
1550  T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass ||
1551  T->getStmtClass() ==
1552  OMPTargetTeamsDistributeParallelForDirectiveClass ||
1553  T->getStmtClass() ==
1554  OMPTargetTeamsDistributeParallelForSimdDirectiveClass ||
1555  T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass ||
1556  T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
1557  }
1558 };
1559 
1560 /// This represents '#pragma omp simd' directive.
1561 ///
1562 /// \code
1563 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
1564 /// \endcode
1565 /// In this example directive '#pragma omp simd' has clauses 'private'
1566 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
1567 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
1568 ///
1570  friend class ASTStmtReader;
1572  /// Build directive with the given start and end location.
1573  ///
1574  /// \param StartLoc Starting location of the directive kind.
1575  /// \param EndLoc Ending location of the directive.
1576  /// \param CollapsedNum Number of collapsed nested loops.
1577  ///
1579  unsigned CollapsedNum)
1580  : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, StartLoc,
1581  EndLoc, CollapsedNum) {}
1582 
1583  /// Build an empty directive.
1584  ///
1585  /// \param CollapsedNum Number of collapsed nested loops.
1586  ///
1587  explicit OMPSimdDirective(unsigned CollapsedNum)
1588  : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd,
1589  SourceLocation(), SourceLocation(), CollapsedNum) {}
1590 
1591 public:
1592  /// Creates directive with a list of \a Clauses.
1593  ///
1594  /// \param C AST context.
1595  /// \param StartLoc Starting location of the directive kind.
1596  /// \param EndLoc Ending Location of the directive.
1597  /// \param CollapsedNum Number of collapsed loops.
1598  /// \param Clauses List of clauses.
1599  /// \param AssociatedStmt Statement, associated with the directive.
1600  /// \param Exprs Helper expressions for CodeGen.
1601  ///
1602  static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1603  SourceLocation EndLoc, unsigned CollapsedNum,
1604  ArrayRef<OMPClause *> Clauses,
1605  Stmt *AssociatedStmt,
1606  const HelperExprs &Exprs);
1607 
1608  /// Creates an empty directive with the place
1609  /// for \a NumClauses clauses.
1610  ///
1611  /// \param C AST context.
1612  /// \param CollapsedNum Number of collapsed nested loops.
1613  /// \param NumClauses Number of clauses.
1614  ///
1615  static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1616  unsigned CollapsedNum, EmptyShell);
1617 
1618  static bool classof(const Stmt *T) {
1619  return T->getStmtClass() == OMPSimdDirectiveClass;
1620  }
1621 };
1622 
1623 /// This represents '#pragma omp for' directive.
1624 ///
1625 /// \code
1626 /// #pragma omp for private(a,b) reduction(+:c,d)
1627 /// \endcode
1628 /// In this example directive '#pragma omp for' has clauses 'private' with the
1629 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
1630 /// and 'd'.
1631 ///
1633  friend class ASTStmtReader;
1635  /// true if current directive has inner cancel directive.
1636  bool HasCancel = false;
1637 
1638  /// Build directive with the given start and end location.
1639  ///
1640  /// \param StartLoc Starting location of the directive kind.
1641  /// \param EndLoc Ending location of the directive.
1642  /// \param CollapsedNum Number of collapsed nested loops.
1643  ///
1645  unsigned CollapsedNum)
1646  : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, StartLoc,
1647  EndLoc, CollapsedNum) {}
1648 
1649  /// Build an empty directive.
1650  ///
1651  /// \param CollapsedNum Number of collapsed nested loops.
1652  ///
1653  explicit OMPForDirective(unsigned CollapsedNum)
1654  : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for,
1655  SourceLocation(), SourceLocation(), CollapsedNum) {}
1656 
1657  /// Sets special task reduction descriptor.
1658  void setTaskReductionRefExpr(Expr *E) {
1660  llvm::omp::OMPD_for)] = E;
1661  }
1662 
1663  /// Set cancel state.
1664  void setHasCancel(bool Has) { HasCancel = Has; }
1665 
1666 public:
1667  /// Creates directive with a list of \a Clauses.
1668  ///
1669  /// \param C AST context.
1670  /// \param StartLoc Starting location of the directive kind.
1671  /// \param EndLoc Ending Location of the directive.
1672  /// \param CollapsedNum Number of collapsed loops.
1673  /// \param Clauses List of clauses.
1674  /// \param AssociatedStmt Statement, associated with the directive.
1675  /// \param Exprs Helper expressions for CodeGen.
1676  /// \param TaskRedRef Task reduction special reference expression to handle
1677  /// taskgroup descriptor.
1678  /// \param HasCancel true if current directive has inner cancel directive.
1679  ///
1680  static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1681  SourceLocation EndLoc, unsigned CollapsedNum,
1682  ArrayRef<OMPClause *> Clauses,
1683  Stmt *AssociatedStmt, const HelperExprs &Exprs,
1684  Expr *TaskRedRef, bool HasCancel);
1685 
1686  /// Creates an empty directive with the place
1687  /// for \a NumClauses clauses.
1688  ///
1689  /// \param C AST context.
1690  /// \param CollapsedNum Number of collapsed nested loops.
1691  /// \param NumClauses Number of clauses.
1692  ///
1693  static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1694  unsigned CollapsedNum, EmptyShell);
1695 
1696  /// Returns special task reduction reference expression.
1698  return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
1699  getLoopsNumber(), llvm::omp::OMPD_for)]);
1700  }
1702  return const_cast<OMPForDirective *>(this)->getTaskReductionRefExpr();
1703  }
1704 
1705  /// Return true if current directive has inner cancel directive.
1706  bool hasCancel() const { return HasCancel; }
1707 
1708  static bool classof(const Stmt *T) {
1709  return T->getStmtClass() == OMPForDirectiveClass;
1710  }
1711 };
1712 
1713 /// This represents '#pragma omp for simd' directive.
1714 ///
1715 /// \code
1716 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
1717 /// \endcode
1718 /// In this example directive '#pragma omp for simd' has clauses 'private'
1719 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
1720 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
1721 ///
1723  friend class ASTStmtReader;
1725  /// Build directive with the given start and end location.
1726  ///
1727  /// \param StartLoc Starting location of the directive kind.
1728  /// \param EndLoc Ending location of the directive.
1729  /// \param CollapsedNum Number of collapsed nested loops.
1730  ///
1732  unsigned CollapsedNum)
1733  : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
1734  StartLoc, EndLoc, CollapsedNum) {}
1735 
1736  /// Build an empty directive.
1737  ///
1738  /// \param CollapsedNum Number of collapsed nested loops.
1739  ///
1740  explicit OMPForSimdDirective(unsigned CollapsedNum)
1741  : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
1742  SourceLocation(), SourceLocation(), CollapsedNum) {}
1743 
1744 public:
1745  /// Creates directive with a list of \a Clauses.
1746  ///
1747  /// \param C AST context.
1748  /// \param StartLoc Starting location of the directive kind.
1749  /// \param EndLoc Ending Location of the directive.
1750  /// \param CollapsedNum Number of collapsed loops.
1751  /// \param Clauses List of clauses.
1752  /// \param AssociatedStmt Statement, associated with the directive.
1753  /// \param Exprs Helper expressions for CodeGen.
1754  ///
1755  static OMPForSimdDirective *
1756  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1757  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1758  Stmt *AssociatedStmt, const HelperExprs &Exprs);
1759 
1760  /// Creates an empty directive with the place
1761  /// for \a NumClauses clauses.
1762  ///
1763  /// \param C AST context.
1764  /// \param CollapsedNum Number of collapsed nested loops.
1765  /// \param NumClauses Number of clauses.
1766  ///
1767  static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
1768  unsigned NumClauses,
1769  unsigned CollapsedNum, EmptyShell);
1770 
1771  static bool classof(const Stmt *T) {
1772  return T->getStmtClass() == OMPForSimdDirectiveClass;
1773  }
1774 };
1775 
1776 /// This represents '#pragma omp sections' directive.
1777 ///
1778 /// \code
1779 /// #pragma omp sections private(a,b) reduction(+:c,d)
1780 /// \endcode
1781 /// In this example directive '#pragma omp sections' has clauses 'private' with
1782 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
1783 /// 'c' and 'd'.
1784 ///
1786  friend class ASTStmtReader;
1788 
1789  /// true if current directive has inner cancel directive.
1790  bool HasCancel = false;
1791 
1792  /// Build directive with the given start and end location.
1793  ///
1794  /// \param StartLoc Starting location of the directive kind.
1795  /// \param EndLoc Ending location of the directive.
1796  ///
1798  : OMPExecutableDirective(OMPSectionsDirectiveClass,
1799  llvm::omp::OMPD_sections, StartLoc, EndLoc) {}
1800 
1801  /// Build an empty directive.
1802  ///
1803  explicit OMPSectionsDirective()
1804  : OMPExecutableDirective(OMPSectionsDirectiveClass,
1805  llvm::omp::OMPD_sections, SourceLocation(),
1806  SourceLocation()) {}
1807 
1808  /// Sets special task reduction descriptor.
1809  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
1810 
1811  /// Set cancel state.
1812  void setHasCancel(bool Has) { HasCancel = Has; }
1813 
1814 public:
1815  /// Creates directive with a list of \a Clauses.
1816  ///
1817  /// \param C AST context.
1818  /// \param StartLoc Starting location of the directive kind.
1819  /// \param EndLoc Ending Location of the directive.
1820  /// \param Clauses List of clauses.
1821  /// \param AssociatedStmt Statement, associated with the directive.
1822  /// \param TaskRedRef Task reduction special reference expression to handle
1823  /// taskgroup descriptor.
1824  /// \param HasCancel true if current directive has inner directive.
1825  ///
1826  static OMPSectionsDirective *
1827  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1828  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
1829  bool HasCancel);
1830 
1831  /// Creates an empty directive with the place for \a NumClauses
1832  /// clauses.
1833  ///
1834  /// \param C AST context.
1835  /// \param NumClauses Number of clauses.
1836  ///
1837  static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
1838  unsigned NumClauses, EmptyShell);
1839 
1840  /// Returns special task reduction reference expression.
1842  return cast_or_null<Expr>(Data->getChildren()[0]);
1843  }
1845  return const_cast<OMPSectionsDirective *>(this)->getTaskReductionRefExpr();
1846  }
1847 
1848  /// Return true if current directive has inner cancel directive.
1849  bool hasCancel() const { return HasCancel; }
1850 
1851  static bool classof(const Stmt *T) {
1852  return T->getStmtClass() == OMPSectionsDirectiveClass;
1853  }
1854 };
1855 
1856 /// This represents '#pragma omp section' directive.
1857 ///
1858 /// \code
1859 /// #pragma omp section
1860 /// \endcode
1861 ///
1863  friend class ASTStmtReader;
1865 
1866  /// true if current directive has inner cancel directive.
1867  bool HasCancel = false;
1868 
1869  /// Build directive with the given start and end location.
1870  ///
1871  /// \param StartLoc Starting location of the directive kind.
1872  /// \param EndLoc Ending location of the directive.
1873  ///
1875  : OMPExecutableDirective(OMPSectionDirectiveClass,
1876  llvm::omp::OMPD_section, StartLoc, EndLoc) {}
1877 
1878  /// Build an empty directive.
1879  ///
1880  explicit OMPSectionDirective()
1881  : OMPExecutableDirective(OMPSectionDirectiveClass,
1882  llvm::omp::OMPD_section, SourceLocation(),
1883  SourceLocation()) {}
1884 
1885 public:
1886  /// Creates directive.
1887  ///
1888  /// \param C AST context.
1889  /// \param StartLoc Starting location of the directive kind.
1890  /// \param EndLoc Ending Location of the directive.
1891  /// \param AssociatedStmt Statement, associated with the directive.
1892  /// \param HasCancel true if current directive has inner directive.
1893  ///
1894  static OMPSectionDirective *Create(const ASTContext &C,
1895  SourceLocation StartLoc,
1896  SourceLocation EndLoc,
1897  Stmt *AssociatedStmt, bool HasCancel);
1898 
1899  /// Creates an empty directive.
1900  ///
1901  /// \param C AST context.
1902  ///
1903  static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1904 
1905  /// Set cancel state.
1906  void setHasCancel(bool Has) { HasCancel = Has; }
1907 
1908  /// Return true if current directive has inner cancel directive.
1909  bool hasCancel() const { return HasCancel; }
1910 
1911  static bool classof(const Stmt *T) {
1912  return T->getStmtClass() == OMPSectionDirectiveClass;
1913  }
1914 };
1915 
1916 /// This represents '#pragma omp single' directive.
1917 ///
1918 /// \code
1919 /// #pragma omp single private(a,b) copyprivate(c,d)
1920 /// \endcode
1921 /// In this example directive '#pragma omp single' has clauses 'private' with
1922 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
1923 ///
1925  friend class ASTStmtReader;
1927  /// Build directive with the given start and end location.
1928  ///
1929  /// \param StartLoc Starting location of the directive kind.
1930  /// \param EndLoc Ending location of the directive.
1931  ///
1933  : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
1934  StartLoc, EndLoc) {}
1935 
1936  /// Build an empty directive.
1937  ///
1938  explicit OMPSingleDirective()
1939  : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
1941 
1942 public:
1943  /// Creates directive with a list of \a Clauses.
1944  ///
1945  /// \param C AST context.
1946  /// \param StartLoc Starting location of the directive kind.
1947  /// \param EndLoc Ending Location of the directive.
1948  /// \param Clauses List of clauses.
1949  /// \param AssociatedStmt Statement, associated with the directive.
1950  ///
1951  static OMPSingleDirective *
1952  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1953  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1954 
1955  /// Creates an empty directive with the place for \a NumClauses
1956  /// clauses.
1957  ///
1958  /// \param C AST context.
1959  /// \param NumClauses Number of clauses.
1960  ///
1961  static OMPSingleDirective *CreateEmpty(const ASTContext &C,
1962  unsigned NumClauses, EmptyShell);
1963 
1964  static bool classof(const Stmt *T) {
1965  return T->getStmtClass() == OMPSingleDirectiveClass;
1966  }
1967 };
1968 
1969 /// This represents '#pragma omp master' directive.
1970 ///
1971 /// \code
1972 /// #pragma omp master
1973 /// \endcode
1974 ///
1976  friend class ASTStmtReader;
1978  /// Build directive with the given start and end location.
1979  ///
1980  /// \param StartLoc Starting location of the directive kind.
1981  /// \param EndLoc Ending location of the directive.
1982  ///
1984  : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
1985  StartLoc, EndLoc) {}
1986 
1987  /// Build an empty directive.
1988  ///
1989  explicit OMPMasterDirective()
1990  : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
1992 
1993 public:
1994  /// Creates directive.
1995  ///
1996  /// \param C AST context.
1997  /// \param StartLoc Starting location of the directive kind.
1998  /// \param EndLoc Ending Location of the directive.
1999  /// \param AssociatedStmt Statement, associated with the directive.
2000  ///
2001  static OMPMasterDirective *Create(const ASTContext &C,
2002  SourceLocation StartLoc,
2003  SourceLocation EndLoc,
2004  Stmt *AssociatedStmt);
2005 
2006  /// Creates an empty directive.
2007  ///
2008  /// \param C AST context.
2009  ///
2010  static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2011 
2012  static bool classof(const Stmt *T) {
2013  return T->getStmtClass() == OMPMasterDirectiveClass;
2014  }
2015 };
2016 
2017 /// This represents '#pragma omp critical' directive.
2018 ///
2019 /// \code
2020 /// #pragma omp critical
2021 /// \endcode
2022 ///
2024  friend class ASTStmtReader;
2026  /// Name of the directive.
2027  DeclarationNameInfo DirName;
2028  /// Build directive with the given start and end location.
2029  ///
2030  /// \param Name Name of the directive.
2031  /// \param StartLoc Starting location of the directive kind.
2032  /// \param EndLoc Ending location of the directive.
2033  ///
2035  SourceLocation EndLoc)
2036  : OMPExecutableDirective(OMPCriticalDirectiveClass,
2037  llvm::omp::OMPD_critical, StartLoc, EndLoc),
2038  DirName(Name) {}
2039 
2040  /// Build an empty directive.
2041  ///
2042  explicit OMPCriticalDirective()
2043  : OMPExecutableDirective(OMPCriticalDirectiveClass,
2044  llvm::omp::OMPD_critical, SourceLocation(),
2045  SourceLocation()) {}
2046 
2047  /// Set name of the directive.
2048  ///
2049  /// \param Name Name of the directive.
2050  ///
2051  void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
2052 
2053 public:
2054  /// Creates directive.
2055  ///
2056  /// \param C AST context.
2057  /// \param Name Name of the directive.
2058  /// \param StartLoc Starting location of the directive kind.
2059  /// \param EndLoc Ending Location of the directive.
2060  /// \param Clauses List of clauses.
2061  /// \param AssociatedStmt Statement, associated with the directive.
2062  ///
2063  static OMPCriticalDirective *
2064  Create(const ASTContext &C, const DeclarationNameInfo &Name,
2065  SourceLocation StartLoc, SourceLocation EndLoc,
2066  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2067 
2068  /// Creates an empty directive.
2069  ///
2070  /// \param C AST context.
2071  /// \param NumClauses Number of clauses.
2072  ///
2073  static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
2074  unsigned NumClauses, EmptyShell);
2075 
2076  /// Return name of the directive.
2077  ///
2078  DeclarationNameInfo getDirectiveName() const { return DirName; }
2079 
2080  static bool classof(const Stmt *T) {
2081  return T->getStmtClass() == OMPCriticalDirectiveClass;
2082  }
2083 };
2084 
2085 /// This represents '#pragma omp parallel for' directive.
2086 ///
2087 /// \code
2088 /// #pragma omp parallel for private(a,b) reduction(+:c,d)
2089 /// \endcode
2090 /// In this example directive '#pragma omp parallel for' has clauses 'private'
2091 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
2092 /// variables 'c' and 'd'.
2093 ///
2095  friend class ASTStmtReader;
2097 
2098  /// true if current region has inner cancel directive.
2099  bool HasCancel = false;
2100 
2101  /// Build directive with the given start and end location.
2102  ///
2103  /// \param StartLoc Starting location of the directive kind.
2104  /// \param EndLoc Ending location of the directive.
2105  /// \param CollapsedNum Number of collapsed nested loops.
2106  ///
2108  unsigned CollapsedNum)
2109  : OMPLoopDirective(OMPParallelForDirectiveClass,
2110  llvm::omp::OMPD_parallel_for, StartLoc, EndLoc,
2111  CollapsedNum) {}
2112 
2113  /// Build an empty directive.
2114  ///
2115  /// \param CollapsedNum Number of collapsed nested loops.
2116  ///
2117  explicit OMPParallelForDirective(unsigned CollapsedNum)
2118  : OMPLoopDirective(OMPParallelForDirectiveClass,
2119  llvm::omp::OMPD_parallel_for, SourceLocation(),
2120  SourceLocation(), CollapsedNum) {}
2121 
2122  /// Sets special task reduction descriptor.
2123  void setTaskReductionRefExpr(Expr *E) {
2125  llvm::omp::OMPD_parallel_for)] = E;
2126  }
2127 
2128  /// Set cancel state.
2129  void setHasCancel(bool Has) { HasCancel = Has; }
2130 
2131 public:
2132  /// Creates directive with a list of \a Clauses.
2133  ///
2134  /// \param C AST context.
2135  /// \param StartLoc Starting location of the directive kind.
2136  /// \param EndLoc Ending Location of the directive.
2137  /// \param CollapsedNum Number of collapsed loops.
2138  /// \param Clauses List of clauses.
2139  /// \param AssociatedStmt Statement, associated with the directive.
2140  /// \param Exprs Helper expressions for CodeGen.
2141  /// \param TaskRedRef Task reduction special reference expression to handle
2142  /// taskgroup descriptor.
2143  /// \param HasCancel true if current directive has inner cancel directive.
2144  ///
2145  static OMPParallelForDirective *
2146  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2147  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2148  Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
2149  bool HasCancel);
2150 
2151  /// Creates an empty directive with the place
2152  /// for \a NumClauses clauses.
2153  ///
2154  /// \param C AST context.
2155  /// \param CollapsedNum Number of collapsed nested loops.
2156  /// \param NumClauses Number of clauses.
2157  ///
2158  static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
2159  unsigned NumClauses,
2160  unsigned CollapsedNum,
2161  EmptyShell);
2162 
2163  /// Returns special task reduction reference expression.
2165  return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
2166  getLoopsNumber(), llvm::omp::OMPD_parallel_for)]);
2167  }
2169  return const_cast<OMPParallelForDirective *>(this)
2171  }
2172 
2173  /// Return true if current directive has inner cancel directive.
2174  bool hasCancel() const { return HasCancel; }
2175 
2176  static bool classof(const Stmt *T) {
2177  return T->getStmtClass() == OMPParallelForDirectiveClass;
2178  }
2179 };
2180 
2181 /// This represents '#pragma omp parallel for simd' directive.
2182 ///
2183 /// \code
2184 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
2185 /// \endcode
2186 /// In this example directive '#pragma omp parallel for simd' has clauses
2187 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
2188 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and
2189 /// 'd'.
2190 ///
2192  friend class ASTStmtReader;
2194  /// Build directive with the given start and end location.
2195  ///
2196  /// \param StartLoc Starting location of the directive kind.
2197  /// \param EndLoc Ending location of the directive.
2198  /// \param CollapsedNum Number of collapsed nested loops.
2199  ///
2201  unsigned CollapsedNum)
2202  : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
2203  llvm::omp::OMPD_parallel_for_simd, StartLoc, EndLoc,
2204  CollapsedNum) {}
2205 
2206  /// Build an empty directive.
2207  ///
2208  /// \param CollapsedNum Number of collapsed nested loops.
2209  ///
2210  explicit OMPParallelForSimdDirective(unsigned CollapsedNum)
2211  : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
2212  llvm::omp::OMPD_parallel_for_simd, SourceLocation(),
2213  SourceLocation(), CollapsedNum) {}
2214 
2215 public:
2216  /// Creates directive with a list of \a Clauses.
2217  ///
2218  /// \param C AST context.
2219  /// \param StartLoc Starting location of the directive kind.
2220  /// \param EndLoc Ending Location of the directive.
2221  /// \param CollapsedNum Number of collapsed loops.
2222  /// \param Clauses List of clauses.
2223  /// \param AssociatedStmt Statement, associated with the directive.
2224  /// \param Exprs Helper expressions for CodeGen.
2225  ///
2226  static OMPParallelForSimdDirective *
2227  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2228  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2229  Stmt *AssociatedStmt, const HelperExprs &Exprs);
2230 
2231  /// Creates an empty directive with the place
2232  /// for \a NumClauses clauses.
2233  ///
2234  /// \param C AST context.
2235  /// \param CollapsedNum Number of collapsed nested loops.
2236  /// \param NumClauses Number of clauses.
2237  ///
2238  static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
2239  unsigned NumClauses,
2240  unsigned CollapsedNum,
2241  EmptyShell);
2242 
2243  static bool classof(const Stmt *T) {
2244  return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
2245  }
2246 };
2247 
2248 /// This represents '#pragma omp parallel master' directive.
2249 ///
2250 /// \code
2251 /// #pragma omp parallel master private(a,b)
2252 /// \endcode
2253 /// In this example directive '#pragma omp parallel master' has clauses
2254 /// 'private' with the variables 'a' and 'b'
2255 ///
2257  friend class ASTStmtReader;
2259 
2261  : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
2262  llvm::omp::OMPD_parallel_master, StartLoc,
2263  EndLoc) {}
2264 
2265  explicit OMPParallelMasterDirective()
2266  : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
2267  llvm::omp::OMPD_parallel_master,
2269 
2270  /// Sets special task reduction descriptor.
2271  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2272 
2273 public:
2274  /// Creates directive with a list of \a Clauses.
2275  ///
2276  /// \param C AST context.
2277  /// \param StartLoc Starting location of the directive kind.
2278  /// \param EndLoc Ending Location of the directive.
2279  /// \param Clauses List of clauses.
2280  /// \param AssociatedStmt Statement, associated with the directive.
2281  /// \param TaskRedRef Task reduction special reference expression to handle
2282  /// taskgroup descriptor.
2283  ///
2284  static OMPParallelMasterDirective *
2285  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2286  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
2287 
2288  /// Creates an empty directive with the place for \a NumClauses
2289  /// clauses.
2290  ///
2291  /// \param C AST context.
2292  /// \param NumClauses Number of clauses.
2293  ///
2294  static OMPParallelMasterDirective *
2295  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2296 
2297  /// Returns special task reduction reference expression.
2299  return cast_or_null<Expr>(Data->getChildren()[0]);
2300  }
2302  return const_cast<OMPParallelMasterDirective *>(this)
2304  }
2305 
2306  static bool classof(const Stmt *T) {
2307  return T->getStmtClass() == OMPParallelMasterDirectiveClass;
2308  }
2309 };
2310 
2311 /// This represents '#pragma omp parallel masked' directive.
2312 ///
2313 /// \code
2314 /// #pragma omp parallel masked filter(tid)
2315 /// \endcode
2316 /// In this example directive '#pragma omp parallel masked' has a clause
2317 /// 'filter' with the variable tid
2318 ///
2320  friend class ASTStmtReader;
2322 
2324  : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
2325  llvm::omp::OMPD_parallel_masked, StartLoc,
2326  EndLoc) {}
2327 
2328  explicit OMPParallelMaskedDirective()
2329  : OMPExecutableDirective(OMPParallelMaskedDirectiveClass,
2330  llvm::omp::OMPD_parallel_masked,
2332 
2333  /// Sets special task reduction descriptor.
2334  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2335 
2336 public:
2337  /// Creates directive with a list of \a Clauses.
2338  ///
2339  /// \param C AST context.
2340  /// \param StartLoc Starting location of the directive kind.
2341  /// \param EndLoc Ending Location of the directive.
2342  /// \param Clauses List of clauses.
2343  /// \param AssociatedStmt Statement, associated with the directive.
2344  /// \param TaskRedRef Task reduction special reference expression to handle
2345  /// taskgroup descriptor.
2346  ///
2347  static OMPParallelMaskedDirective *
2348  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2349  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
2350 
2351  /// Creates an empty directive with the place for \a NumClauses
2352  /// clauses.
2353  ///
2354  /// \param C AST context.
2355  /// \param NumClauses Number of clauses.
2356  ///
2357  static OMPParallelMaskedDirective *
2358  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2359 
2360  /// Returns special task reduction reference expression.
2362  return cast_or_null<Expr>(Data->getChildren()[0]);
2363  }
2365  return const_cast<OMPParallelMaskedDirective *>(this)
2367  }
2368 
2369  static bool classof(const Stmt *T) {
2370  return T->getStmtClass() == OMPParallelMaskedDirectiveClass;
2371  }
2372 };
2373 
2374 /// This represents '#pragma omp parallel sections' directive.
2375 ///
2376 /// \code
2377 /// #pragma omp parallel sections private(a,b) reduction(+:c,d)
2378 /// \endcode
2379 /// In this example directive '#pragma omp parallel sections' has clauses
2380 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
2381 /// and variables 'c' and 'd'.
2382 ///
2384  friend class ASTStmtReader;
2386 
2387  /// true if current directive has inner cancel directive.
2388  bool HasCancel = false;
2389 
2390  /// Build directive with the given start and end location.
2391  ///
2392  /// \param StartLoc Starting location of the directive kind.
2393  /// \param EndLoc Ending location of the directive.
2394  ///
2396  : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
2397  llvm::omp::OMPD_parallel_sections, StartLoc,
2398  EndLoc) {}
2399 
2400  /// Build an empty directive.
2401  ///
2402  explicit OMPParallelSectionsDirective()
2403  : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
2404  llvm::omp::OMPD_parallel_sections,
2406 
2407  /// Sets special task reduction descriptor.
2408  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2409 
2410  /// Set cancel state.
2411  void setHasCancel(bool Has) { HasCancel = Has; }
2412 
2413 public:
2414  /// Creates directive with a list of \a Clauses.
2415  ///
2416  /// \param C AST context.
2417  /// \param StartLoc Starting location of the directive kind.
2418  /// \param EndLoc Ending Location of the directive.
2419  /// \param Clauses List of clauses.
2420  /// \param AssociatedStmt Statement, associated with the directive.
2421  /// \param TaskRedRef Task reduction special reference expression to handle
2422  /// taskgroup descriptor.
2423  /// \param HasCancel true if current directive has inner cancel directive.
2424  ///
2425  static OMPParallelSectionsDirective *
2426  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2427  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
2428  bool HasCancel);
2429 
2430  /// Creates an empty directive with the place for \a NumClauses
2431  /// clauses.
2432  ///
2433  /// \param C AST context.
2434  /// \param NumClauses Number of clauses.
2435  ///
2436  static OMPParallelSectionsDirective *
2437  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2438 
2439  /// Returns special task reduction reference expression.
2441  return cast_or_null<Expr>(Data->getChildren()[0]);
2442  }
2444  return const_cast<OMPParallelSectionsDirective *>(this)
2446  }
2447 
2448  /// Return true if current directive has inner cancel directive.
2449  bool hasCancel() const { return HasCancel; }
2450 
2451  static bool classof(const Stmt *T) {
2452  return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
2453  }
2454 };
2455 
2456 /// This represents '#pragma omp task' directive.
2457 ///
2458 /// \code
2459 /// #pragma omp task private(a,b) final(d)
2460 /// \endcode
2461 /// In this example directive '#pragma omp task' has clauses 'private' with the
2462 /// variables 'a' and 'b' and 'final' with condition 'd'.
2463 ///
2465  friend class ASTStmtReader;
2467  /// true if this directive has inner cancel directive.
2468  bool HasCancel = false;
2469 
2470  /// Build directive with the given start and end location.
2471  ///
2472  /// \param StartLoc Starting location of the directive kind.
2473  /// \param EndLoc Ending location of the directive.
2474  ///
2476  : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
2477  StartLoc, EndLoc) {}
2478 
2479  /// Build an empty directive.
2480  ///
2481  explicit OMPTaskDirective()
2482  : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
2484 
2485  /// Set cancel state.
2486  void setHasCancel(bool Has) { HasCancel = Has; }
2487 
2488 public:
2489  /// Creates directive with a list of \a Clauses.
2490  ///
2491  /// \param C AST context.
2492  /// \param StartLoc Starting location of the directive kind.
2493  /// \param EndLoc Ending Location of the directive.
2494  /// \param Clauses List of clauses.
2495  /// \param AssociatedStmt Statement, associated with the directive.
2496  /// \param HasCancel true, if current directive has inner cancel directive.
2497  ///
2498  static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2499  SourceLocation EndLoc,
2500  ArrayRef<OMPClause *> Clauses,
2501  Stmt *AssociatedStmt, bool HasCancel);
2502 
2503  /// Creates an empty directive with the place for \a NumClauses
2504  /// clauses.
2505  ///
2506  /// \param C AST context.
2507  /// \param NumClauses Number of clauses.
2508  ///
2509  static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
2510  EmptyShell);
2511 
2512  /// Return true if current directive has inner cancel directive.
2513  bool hasCancel() const { return HasCancel; }
2514 
2515  static bool classof(const Stmt *T) {
2516  return T->getStmtClass() == OMPTaskDirectiveClass;
2517  }
2518 };
2519 
2520 /// This represents '#pragma omp taskyield' directive.
2521 ///
2522 /// \code
2523 /// #pragma omp taskyield
2524 /// \endcode
2525 ///
2527  friend class ASTStmtReader;
2529  /// Build directive with the given start and end location.
2530  ///
2531  /// \param StartLoc Starting location of the directive kind.
2532  /// \param EndLoc Ending location of the directive.
2533  ///
2535  : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
2536  llvm::omp::OMPD_taskyield, StartLoc, EndLoc) {}
2537 
2538  /// Build an empty directive.
2539  ///
2540  explicit OMPTaskyieldDirective()
2541  : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
2542  llvm::omp::OMPD_taskyield, SourceLocation(),
2543  SourceLocation()) {}
2544 
2545 public:
2546  /// Creates directive.
2547  ///
2548  /// \param C AST context.
2549  /// \param StartLoc Starting location of the directive kind.
2550  /// \param EndLoc Ending Location of the directive.
2551  ///
2552  static OMPTaskyieldDirective *
2553  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
2554 
2555  /// Creates an empty directive.
2556  ///
2557  /// \param C AST context.
2558  ///
2559  static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2560 
2561  static bool classof(const Stmt *T) {
2562  return T->getStmtClass() == OMPTaskyieldDirectiveClass;
2563  }
2564 };
2565 
2566 /// This represents '#pragma omp barrier' directive.
2567 ///
2568 /// \code
2569 /// #pragma omp barrier
2570 /// \endcode
2571 ///
2573  friend class ASTStmtReader;
2575  /// Build directive with the given start and end location.
2576  ///
2577  /// \param StartLoc Starting location of the directive kind.
2578  /// \param EndLoc Ending location of the directive.
2579  ///
2581  : OMPExecutableDirective(OMPBarrierDirectiveClass,
2582  llvm::omp::OMPD_barrier, StartLoc, EndLoc) {}
2583 
2584  /// Build an empty directive.
2585  ///
2586  explicit OMPBarrierDirective()
2587  : OMPExecutableDirective(OMPBarrierDirectiveClass,
2588  llvm::omp::OMPD_barrier, SourceLocation(),
2589  SourceLocation()) {}
2590 
2591 public:
2592  /// Creates directive.
2593  ///
2594  /// \param C AST context.
2595  /// \param StartLoc Starting location of the directive kind.
2596  /// \param EndLoc Ending Location of the directive.
2597  ///
2598  static OMPBarrierDirective *
2599  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
2600 
2601  /// Creates an empty directive.
2602  ///
2603  /// \param C AST context.
2604  ///
2605  static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2606 
2607  static bool classof(const Stmt *T) {
2608  return T->getStmtClass() == OMPBarrierDirectiveClass;
2609  }
2610 };
2611 
2612 /// This represents '#pragma omp taskwait' directive.
2613 ///
2614 /// \code
2615 /// #pragma omp taskwait
2616 /// \endcode
2617 ///
2619  friend class ASTStmtReader;
2621  /// Build directive with the given start and end location.
2622  ///
2623  /// \param StartLoc Starting location of the directive kind.
2624  /// \param EndLoc Ending location of the directive.
2625  ///
2627  : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
2628  llvm::omp::OMPD_taskwait, StartLoc, EndLoc) {}
2629 
2630  /// Build an empty directive.
2631  ///
2632  explicit OMPTaskwaitDirective()
2633  : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
2634  llvm::omp::OMPD_taskwait, SourceLocation(),
2635  SourceLocation()) {}
2636 
2637 public:
2638  /// Creates directive.
2639  ///
2640  /// \param C AST context.
2641  /// \param StartLoc Starting location of the directive kind.
2642  /// \param EndLoc Ending Location of the directive.
2643  /// \param Clauses List of clauses.
2644  ///
2645  static OMPTaskwaitDirective *Create(const ASTContext &C,
2646  SourceLocation StartLoc,
2647  SourceLocation EndLoc,
2648  ArrayRef<OMPClause *> Clauses);
2649 
2650  /// Creates an empty directive.
2651  ///
2652  /// \param C AST context.
2653  /// \param NumClauses Number of clauses.
2654  ///
2655  static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C,
2656  unsigned NumClauses, EmptyShell);
2657 
2658  static bool classof(const Stmt *T) {
2659  return T->getStmtClass() == OMPTaskwaitDirectiveClass;
2660  }
2661 };
2662 
2663 /// This represents '#pragma omp taskgroup' directive.
2664 ///
2665 /// \code
2666 /// #pragma omp taskgroup
2667 /// \endcode
2668 ///
2670  friend class ASTStmtReader;
2672  /// Build directive with the given start and end location.
2673  ///
2674  /// \param StartLoc Starting location of the directive kind.
2675  /// \param EndLoc Ending location of the directive.
2676  ///
2678  : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
2679  llvm::omp::OMPD_taskgroup, StartLoc, EndLoc) {}
2680 
2681  /// Build an empty directive.
2682  ///
2683  explicit OMPTaskgroupDirective()
2684  : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
2685  llvm::omp::OMPD_taskgroup, SourceLocation(),
2686  SourceLocation()) {}
2687 
2688  /// Sets the task_reduction return variable.
2689  void setReductionRef(Expr *RR) { Data->getChildren()[0] = RR; }
2690 
2691 public:
2692  /// Creates directive.
2693  ///
2694  /// \param C AST context.
2695  /// \param StartLoc Starting location of the directive kind.
2696  /// \param EndLoc Ending Location of the directive.
2697  /// \param Clauses List of clauses.
2698  /// \param AssociatedStmt Statement, associated with the directive.
2699  /// \param ReductionRef Reference to the task_reduction return variable.
2700  ///
2701  static OMPTaskgroupDirective *
2702  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2703  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
2704  Expr *ReductionRef);
2705 
2706  /// Creates an empty directive.
2707  ///
2708  /// \param C AST context.
2709  /// \param NumClauses Number of clauses.
2710  ///
2711  static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C,
2712  unsigned NumClauses, EmptyShell);
2713 
2714 
2715  /// Returns reference to the task_reduction return variable.
2716  const Expr *getReductionRef() const {
2717  return const_cast<OMPTaskgroupDirective *>(this)->getReductionRef();
2718  }
2719  Expr *getReductionRef() { return cast_or_null<Expr>(Data->getChildren()[0]); }
2720 
2721  static bool classof(const Stmt *T) {
2722  return T->getStmtClass() == OMPTaskgroupDirectiveClass;
2723  }
2724 };
2725 
2726 /// This represents '#pragma omp flush' directive.
2727 ///
2728 /// \code
2729 /// #pragma omp flush(a,b)
2730 /// \endcode
2731 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
2732 /// and 'b'.
2733 /// 'omp flush' directive does not have clauses but have an optional list of
2734 /// variables to flush. This list of variables is stored within some fake clause
2735 /// FlushClause.
2737  friend class ASTStmtReader;
2739  /// Build directive with the given start and end location.
2740  ///
2741  /// \param StartLoc Starting location of the directive kind.
2742  /// \param EndLoc Ending location of the directive.
2743  ///
2745  : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
2746  StartLoc, EndLoc) {}
2747 
2748  /// Build an empty directive.
2749  ///
2750  explicit OMPFlushDirective()
2751  : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
2753 
2754 public:
2755  /// Creates directive with a list of \a Clauses.
2756  ///
2757  /// \param C AST context.
2758  /// \param StartLoc Starting location of the directive kind.
2759  /// \param EndLoc Ending Location of the directive.
2760  /// \param Clauses List of clauses (only single OMPFlushClause clause is
2761  /// allowed).
2762  ///
2763  static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2764  SourceLocation EndLoc,
2765  ArrayRef<OMPClause *> Clauses);
2766 
2767  /// Creates an empty directive with the place for \a NumClauses
2768  /// clauses.
2769  ///
2770  /// \param C AST context.
2771  /// \param NumClauses Number of clauses.
2772  ///
2773  static OMPFlushDirective *CreateEmpty(const ASTContext &C,
2774  unsigned NumClauses, EmptyShell);
2775 
2776  static bool classof(const Stmt *T) {
2777  return T->getStmtClass() == OMPFlushDirectiveClass;
2778  }
2779 };
2780 
2781 /// This represents '#pragma omp depobj' directive.
2782 ///
2783 /// \code
2784 /// #pragma omp depobj(a) depend(in:x,y)
2785 /// \endcode
2786 /// In this example directive '#pragma omp depobj' initializes a depobj object
2787 /// 'a' with dependence type 'in' and a list with 'x' and 'y' locators.
2789  friend class ASTStmtReader;
2791 
2792  /// Build directive with the given start and end location.
2793  ///
2794  /// \param StartLoc Starting location of the directive kind.
2795  /// \param EndLoc Ending location of the directive.
2796  ///
2798  : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
2799  StartLoc, EndLoc) {}
2800 
2801  /// Build an empty directive.
2802  ///
2803  explicit OMPDepobjDirective()
2804  : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
2806 
2807 public:
2808  /// Creates directive with a list of \a Clauses.
2809  ///
2810  /// \param C AST context.
2811  /// \param StartLoc Starting location of the directive kind.
2812  /// \param EndLoc Ending Location of the directive.
2813  /// \param Clauses List of clauses.
2814  ///
2815  static OMPDepobjDirective *Create(const ASTContext &C,
2816  SourceLocation StartLoc,
2817  SourceLocation EndLoc,
2818  ArrayRef<OMPClause *> Clauses);
2819 
2820  /// Creates an empty directive with the place for \a NumClauses
2821  /// clauses.
2822  ///
2823  /// \param C AST context.
2824  /// \param NumClauses Number of clauses.
2825  ///
2826  static OMPDepobjDirective *CreateEmpty(const ASTContext &C,
2827  unsigned NumClauses, EmptyShell);
2828 
2829  static bool classof(const Stmt *T) {
2830  return T->getStmtClass() == OMPDepobjDirectiveClass;
2831  }
2832 };
2833 
2834 /// This represents '#pragma omp ordered' directive.
2835 ///
2836 /// \code
2837 /// #pragma omp ordered
2838 /// \endcode
2839 ///
2841  friend class ASTStmtReader;
2843  /// Build directive with the given start and end location.
2844  ///
2845  /// \param StartLoc Starting location of the directive kind.
2846  /// \param EndLoc Ending location of the directive.
2847  ///
2849  : OMPExecutableDirective(OMPOrderedDirectiveClass,
2850  llvm::omp::OMPD_ordered, StartLoc, EndLoc) {}
2851 
2852  /// Build an empty directive.
2853  ///
2854  explicit OMPOrderedDirective()
2855  : OMPExecutableDirective(OMPOrderedDirectiveClass,
2856  llvm::omp::OMPD_ordered, SourceLocation(),
2857  SourceLocation()) {}
2858 
2859 public:
2860  /// Creates directive.
2861  ///
2862  /// \param C AST context.
2863  /// \param StartLoc Starting location of the directive kind.
2864  /// \param EndLoc Ending Location of the directive.
2865  /// \param Clauses List of clauses.
2866  /// \param AssociatedStmt Statement, associated with the directive.
2867  ///
2868  static OMPOrderedDirective *
2869  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2870  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2871 
2872  /// Creates an empty directive.
2873  ///
2874  /// \param C AST context.
2875  /// \param NumClauses Number of clauses.
2876  /// \param IsStandalone true, if the the standalone directive is created.
2877  ///
2878  static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
2879  unsigned NumClauses,
2880  bool IsStandalone, EmptyShell);
2881 
2882  static bool classof(const Stmt *T) {
2883  return T->getStmtClass() == OMPOrderedDirectiveClass;
2884  }
2885 };
2886 
2887 /// This represents '#pragma omp atomic' directive.
2888 ///
2889 /// \code
2890 /// #pragma omp atomic capture
2891 /// \endcode
2892 /// In this example directive '#pragma omp atomic' has clause 'capture'.
2893 ///
2895  friend class ASTStmtReader;
2897 
2898  struct FlagTy {
2899  /// Used for 'atomic update' or 'atomic capture' constructs. They may
2900  /// have atomic expressions of forms:
2901  /// \code
2902  /// x = x binop expr;
2903  /// x = expr binop x;
2904  /// \endcode
2905  /// This field is 1 for the first form of the expression and 0 for the
2906  /// second. Required for correct codegen of non-associative operations (like
2907  /// << or >>).
2908  uint8_t IsXLHSInRHSPart : 1;
2909  /// Used for 'atomic update' or 'atomic capture' constructs. They may
2910  /// have atomic expressions of forms:
2911  /// \code
2912  /// v = x; <update x>;
2913  /// <update x>; v = x;
2914  /// \endcode
2915  /// This field is 1 for the first(postfix) form of the expression and 0
2916  /// otherwise.
2917  uint8_t IsPostfixUpdate : 1;
2918  /// 1 if 'v' is updated only when the condition is false (compare capture
2919  /// only).
2920  uint8_t IsFailOnly : 1;
2921  } Flags;
2922 
2923  /// Build directive with the given start and end location.
2924  ///
2925  /// \param StartLoc Starting location of the directive kind.
2926  /// \param EndLoc Ending location of the directive.
2927  ///
2929  : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
2930  StartLoc, EndLoc) {}
2931 
2932  /// Build an empty directive.
2933  ///
2934  explicit OMPAtomicDirective()
2935  : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
2936  SourceLocation(), SourceLocation()) {}
2937 
2938  enum DataPositionTy : size_t {
2939  POS_X = 0,
2940  POS_V,
2941  POS_E,
2942  POS_UpdateExpr,
2943  POS_D,
2944  POS_Cond,
2945  POS_R,
2946  };
2947 
2948  /// Set 'x' part of the associated expression/statement.
2949  void setX(Expr *X) { Data->getChildren()[DataPositionTy::POS_X] = X; }
2950  /// Set helper expression of the form
2951  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
2952  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2953  void setUpdateExpr(Expr *UE) {
2954  Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE;
2955  }
2956  /// Set 'v' part of the associated expression/statement.
2957  void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; }
2958  /// Set 'r' part of the associated expression/statement.
2959  void setR(Expr *R) { Data->getChildren()[DataPositionTy::POS_R] = R; }
2960  /// Set 'expr' part of the associated expression/statement.
2961  void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; }
2962  /// Set 'd' part of the associated expression/statement.
2963  void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; }
2964  /// Set conditional expression in `atomic compare`.
2965  void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; }
2966 
2967 public:
2968  struct Expressions {
2969  /// 'x' part of the associated expression/statement.
2970  Expr *X = nullptr;
2971  /// 'v' part of the associated expression/statement.
2972  Expr *V = nullptr;
2973  // 'r' part of the associated expression/statement.
2974  Expr *R = nullptr;
2975  /// 'expr' part of the associated expression/statement.
2976  Expr *E = nullptr;
2977  /// UE Helper expression of the form:
2978  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
2979  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2980  Expr *UE = nullptr;
2981  /// 'd' part of the associated expression/statement.
2982  Expr *D = nullptr;
2983  /// Conditional expression in `atomic compare` construct.
2984  Expr *Cond = nullptr;
2985  /// True if UE has the first form and false if the second.
2987  /// True if original value of 'x' must be stored in 'v', not an updated one.
2989  /// True if 'v' is updated only when the condition is false (compare capture
2990  /// only).
2992  };
2993 
2994  /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
2995  /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
2996  /// detailed description of 'x', 'v' and 'expr').
2997  ///
2998  /// \param C AST context.
2999  /// \param StartLoc Starting location of the directive kind.
3000  /// \param EndLoc Ending Location of the directive.
3001  /// \param Clauses List of clauses.
3002  /// \param AssociatedStmt Statement, associated with the directive.
3003  /// \param Exprs Associated expressions or statements.
3004  static OMPAtomicDirective *Create(const ASTContext &C,
3005  SourceLocation StartLoc,
3006  SourceLocation EndLoc,
3007  ArrayRef<OMPClause *> Clauses,
3008  Stmt *AssociatedStmt, Expressions Exprs);
3009 
3010  /// Creates an empty directive with the place for \a NumClauses
3011  /// clauses.
3012  ///
3013  /// \param C AST context.
3014  /// \param NumClauses Number of clauses.
3015  ///
3016  static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
3017  unsigned NumClauses, EmptyShell);
3018 
3019  /// Get 'x' part of the associated expression/statement.
3020  Expr *getX() {
3021  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
3022  }
3023  const Expr *getX() const {
3024  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
3025  }
3026  /// Get helper expression of the form
3027  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
3028  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3030  return cast_or_null<Expr>(
3031  Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
3032  }
3033  const Expr *getUpdateExpr() const {
3034  return cast_or_null<Expr>(
3035  Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
3036  }
3037  /// Return true if helper update expression has form
3038  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
3039  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
3040  bool isXLHSInRHSPart() const { return Flags.IsXLHSInRHSPart; }
3041  /// Return true if 'v' expression must be updated to original value of
3042  /// 'x', false if 'v' must be updated to the new value of 'x'.
3043  bool isPostfixUpdate() const { return Flags.IsPostfixUpdate; }
3044  /// Return true if 'v' is updated only when the condition is evaluated false
3045  /// (compare capture only).
3046  bool isFailOnly() const { return Flags.IsFailOnly; }
3047  /// Get 'v' part of the associated expression/statement.
3048  Expr *getV() {
3049  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
3050  }
3051  const Expr *getV() const {
3052  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
3053  }
3054  /// Get 'r' part of the associated expression/statement.
3055  Expr *getR() {
3056  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
3057  }
3058  const Expr *getR() const {
3059  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]);
3060  }
3061  /// Get 'expr' part of the associated expression/statement.
3063  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
3064  }
3065  const Expr *getExpr() const {
3066  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
3067  }
3068  /// Get 'd' part of the associated expression/statement.
3069  Expr *getD() {
3070  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
3071  }
3072  Expr *getD() const {
3073  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
3074  }
3075  /// Get the 'cond' part of the source atomic expression.
3077  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
3078  }
3079  Expr *getCondExpr() const {
3080  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
3081  }
3082 
3083  static bool classof(const Stmt *T) {
3084  return T->getStmtClass() == OMPAtomicDirectiveClass;
3085  }
3086 };
3087 
3088 /// This represents '#pragma omp target' directive.
3089 ///
3090 /// \code
3091 /// #pragma omp target if(a)
3092 /// \endcode
3093 /// In this example directive '#pragma omp target' has clause 'if' with
3094 /// condition 'a'.
3095 ///
3097  friend class ASTStmtReader;
3099  /// Build directive with the given start and end location.
3100  ///
3101  /// \param StartLoc Starting location of the directive kind.
3102  /// \param EndLoc Ending location of the directive.
3103  ///
3105  : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
3106  StartLoc, EndLoc) {}
3107 
3108  /// Build an empty directive.
3109  ///
3110  explicit OMPTargetDirective()
3111  : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
3113 
3114 public:
3115  /// Creates directive with a list of \a Clauses.
3116  ///
3117  /// \param C AST context.
3118  /// \param StartLoc Starting location of the directive kind.
3119  /// \param EndLoc Ending Location of the directive.
3120  /// \param Clauses List of clauses.
3121  /// \param AssociatedStmt Statement, associated with the directive.
3122  ///
3123  static OMPTargetDirective *
3124  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3125  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3126 
3127  /// Creates an empty directive with the place for \a NumClauses
3128  /// clauses.
3129  ///
3130  /// \param C AST context.
3131  /// \param NumClauses Number of clauses.
3132  ///
3133  static OMPTargetDirective *CreateEmpty(const ASTContext &C,
3134  unsigned NumClauses, EmptyShell);
3135 
3136  static bool classof(const Stmt *T) {
3137  return T->getStmtClass() == OMPTargetDirectiveClass;
3138  }
3139 };
3140 
3141 /// This represents '#pragma omp target data' directive.
3142 ///
3143 /// \code
3144 /// #pragma omp target data device(0) if(a) map(b[:])
3145 /// \endcode
3146 /// In this example directive '#pragma omp target data' has clauses 'device'
3147 /// with the value '0', 'if' with condition 'a' and 'map' with array
3148 /// section 'b[:]'.
3149 ///
3151  friend class ASTStmtReader;
3153  /// Build directive with the given start and end location.
3154  ///
3155  /// \param StartLoc Starting location of the directive kind.
3156  /// \param EndLoc Ending Location of the directive.
3157  ///
3159  : OMPExecutableDirective(OMPTargetDataDirectiveClass,
3160  llvm::omp::OMPD_target_data, StartLoc, EndLoc) {}
3161 
3162  /// Build an empty directive.
3163  ///
3164  explicit OMPTargetDataDirective()
3165  : OMPExecutableDirective(OMPTargetDataDirectiveClass,
3166  llvm::omp::OMPD_target_data, SourceLocation(),
3167  SourceLocation()) {}
3168 
3169 public:
3170  /// Creates directive with a list of \a Clauses.
3171  ///
3172  /// \param C AST context.
3173  /// \param StartLoc Starting location of the directive kind.
3174  /// \param EndLoc Ending Location of the directive.
3175  /// \param Clauses List of clauses.
3176  /// \param AssociatedStmt Statement, associated with the directive.
3177  ///
3178  static OMPTargetDataDirective *
3179  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3180  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3181 
3182  /// Creates an empty directive with the place for \a N clauses.
3183  ///
3184  /// \param C AST context.
3185  /// \param N The number of clauses.
3186  ///
3187  static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
3188  EmptyShell);
3189 
3190  static bool classof(const Stmt *T) {
3191  return T->getStmtClass() == OMPTargetDataDirectiveClass;
3192  }
3193 };
3194 
3195 /// This represents '#pragma omp target enter data' directive.
3196 ///
3197 /// \code
3198 /// #pragma omp target enter data device(0) if(a) map(b[:])
3199 /// \endcode
3200 /// In this example directive '#pragma omp target enter data' has clauses
3201 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
3202 /// section 'b[:]'.
3203 ///
3205  friend class ASTStmtReader;
3207  /// Build directive with the given start and end location.
3208  ///
3209  /// \param StartLoc Starting location of the directive kind.
3210  /// \param EndLoc Ending Location of the directive.
3211  ///
3213  : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3214  llvm::omp::OMPD_target_enter_data, StartLoc,
3215  EndLoc) {}
3216 
3217  /// Build an empty directive.
3218  ///
3219  explicit OMPTargetEnterDataDirective()
3220  : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3221  llvm::omp::OMPD_target_enter_data,
3223 
3224 public:
3225  /// Creates directive with a list of \a Clauses.
3226  ///
3227  /// \param C AST context.
3228  /// \param StartLoc Starting location of the directive kind.
3229  /// \param EndLoc Ending Location of the directive.
3230  /// \param Clauses List of clauses.
3231  /// \param AssociatedStmt Statement, associated with the directive.
3232  ///
3233  static OMPTargetEnterDataDirective *
3234  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3235  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3236 
3237  /// Creates an empty directive with the place for \a N clauses.
3238  ///
3239  /// \param C AST context.
3240  /// \param N The number of clauses.
3241  ///
3242  static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C,
3243  unsigned N, EmptyShell);
3244 
3245  static bool classof(const Stmt *T) {
3246  return T->getStmtClass() == OMPTargetEnterDataDirectiveClass;
3247  }
3248 };
3249 
3250 /// This represents '#pragma omp target exit data' directive.
3251 ///
3252 /// \code
3253 /// #pragma omp target exit data device(0) if(a) map(b[:])
3254 /// \endcode
3255 /// In this example directive '#pragma omp target exit data' has clauses
3256 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
3257 /// section 'b[:]'.
3258 ///
3260  friend class ASTStmtReader;
3262  /// Build directive with the given start and end location.
3263  ///
3264  /// \param StartLoc Starting location of the directive kind.
3265  /// \param EndLoc Ending Location of the directive.
3266  ///
3268  : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3269  llvm::omp::OMPD_target_exit_data, StartLoc,
3270  EndLoc) {}
3271 
3272  /// Build an empty directive.
3273  ///
3274  explicit OMPTargetExitDataDirective()
3275  : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3276  llvm::omp::OMPD_target_exit_data,
3278 
3279 public:
3280  /// Creates directive with a list of \a Clauses.
3281  ///
3282  /// \param C AST context.
3283  /// \param StartLoc Starting location of the directive kind.
3284  /// \param EndLoc Ending Location of the directive.
3285  /// \param Clauses List of clauses.
3286  /// \param AssociatedStmt Statement, associated with the directive.
3287  ///
3288  static OMPTargetExitDataDirective *
3289  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3290  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3291 
3292  /// Creates an empty directive with the place for \a N clauses.
3293  ///
3294  /// \param C AST context.
3295  /// \param N The number of clauses.
3296  ///
3297  static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
3298  unsigned N, EmptyShell);
3299 
3300  static bool classof(const Stmt *T) {
3301  return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
3302  }
3303 };
3304 
3305 /// This represents '#pragma omp target parallel' directive.
3306 ///
3307 /// \code
3308 /// #pragma omp target parallel if(a)
3309 /// \endcode
3310 /// In this example directive '#pragma omp target parallel' has clause 'if' with
3311 /// condition 'a'.
3312 ///
3314  friend class ASTStmtReader;
3316  /// true if the construct has inner cancel directive.
3317  bool HasCancel = false;
3318 
3319  /// Build directive with the given start and end location.
3320  ///
3321  /// \param StartLoc Starting location of the directive kind.
3322  /// \param EndLoc Ending location of the directive.
3323  ///
3325  : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3326  llvm::omp::OMPD_target_parallel, StartLoc,
3327  EndLoc) {}
3328 
3329  /// Build an empty directive.
3330  ///
3331  explicit OMPTargetParallelDirective()
3332  : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3333  llvm::omp::OMPD_target_parallel,
3335 
3336  /// Sets special task reduction descriptor.
3337  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
3338  /// Set cancel state.
3339  void setHasCancel(bool Has) { HasCancel = Has; }
3340 
3341 public:
3342  /// Creates directive with a list of \a Clauses.
3343  ///
3344  /// \param C AST context.
3345  /// \param StartLoc Starting location of the directive kind.
3346  /// \param EndLoc Ending Location of the directive.
3347  /// \param Clauses List of clauses.
3348  /// \param AssociatedStmt Statement, associated with the directive.
3349  /// \param TaskRedRef Task reduction special reference expression to handle
3350  /// taskgroup descriptor.
3351  /// \param HasCancel true if this directive has inner cancel directive.
3352  ///
3353  static OMPTargetParallelDirective *
3354  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3355  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
3356  bool HasCancel);
3357 
3358  /// Creates an empty directive with the place for \a NumClauses
3359  /// clauses.
3360  ///
3361  /// \param C AST context.
3362  /// \param NumClauses Number of clauses.
3363  ///
3364  static OMPTargetParallelDirective *
3365  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
3366 
3367  /// Returns special task reduction reference expression.
3369  return cast_or_null<Expr>(Data->getChildren()[0]);
3370  }
3372  return const_cast<OMPTargetParallelDirective *>(this)
3374  }
3375 
3376  /// Return true if current directive has inner cancel directive.
3377  bool hasCancel() const { return HasCancel; }
3378 
3379  static bool classof(const Stmt *T) {
3380  return T->getStmtClass() == OMPTargetParallelDirectiveClass;
3381  }
3382 };
3383 
3384 /// This represents '#pragma omp target parallel for' directive.
3385 ///
3386 /// \code
3387 /// #pragma omp target parallel for private(a,b) reduction(+:c,d)
3388 /// \endcode
3389 /// In this example directive '#pragma omp target parallel for' has clauses
3390 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
3391 /// and variables 'c' and 'd'.
3392 ///
3394  friend class ASTStmtReader;
3396 
3397  /// true if current region has inner cancel directive.
3398  bool HasCancel = false;
3399 
3400  /// Build directive with the given start and end location.
3401  ///
3402  /// \param StartLoc Starting location of the directive kind.
3403  /// \param EndLoc Ending location of the directive.
3404  /// \param CollapsedNum Number of collapsed nested loops.
3405  ///
3407  unsigned CollapsedNum)
3408  : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3409  llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc,
3410  CollapsedNum) {}
3411 
3412  /// Build an empty directive.
3413  ///
3414  /// \param CollapsedNum Number of collapsed nested loops.
3415  ///
3416  explicit OMPTargetParallelForDirective(unsigned CollapsedNum)
3417  : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3418  llvm::omp::OMPD_target_parallel_for, SourceLocation(),
3419  SourceLocation(), CollapsedNum) {}
3420 
3421  /// Sets special task reduction descriptor.
3422  void setTaskReductionRefExpr(Expr *E) {
3424  getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E;
3425  }
3426 
3427  /// Set cancel state.
3428  void setHasCancel(bool Has) { HasCancel = Has; }
3429 
3430 public:
3431  /// Creates directive with a list of \a Clauses.
3432  ///
3433  /// \param C AST context.
3434  /// \param StartLoc Starting location of the directive kind.
3435  /// \param EndLoc Ending Location of the directive.
3436  /// \param CollapsedNum Number of collapsed loops.
3437  /// \param Clauses List of clauses.
3438  /// \param AssociatedStmt Statement, associated with the directive.
3439  /// \param Exprs Helper expressions for CodeGen.
3440  /// \param TaskRedRef Task reduction special reference expression to handle
3441  /// taskgroup descriptor.
3442  /// \param HasCancel true if current directive has inner cancel directive.
3443  ///
3444  static OMPTargetParallelForDirective *
3445  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3446  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3447  Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
3448  bool HasCancel);
3449 
3450  /// Creates an empty directive with the place
3451  /// for \a NumClauses clauses.
3452  ///
3453  /// \param C AST context.
3454  /// \param CollapsedNum Number of collapsed nested loops.
3455  /// \param NumClauses Number of clauses.
3456  ///
3457  static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C,
3458  unsigned NumClauses,
3459  unsigned CollapsedNum,
3460  EmptyShell);
3461 
3462  /// Returns special task reduction reference expression.
3464  return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
3465  getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]);
3466  }
3468  return const_cast<OMPTargetParallelForDirective *>(this)
3470  }
3471 
3472  /// Return true if current directive has inner cancel directive.
3473  bool hasCancel() const { return HasCancel; }
3474 
3475  static bool classof(const Stmt *T) {
3476  return T->getStmtClass() == OMPTargetParallelForDirectiveClass;
3477  }
3478 };
3479 
3480 /// This represents '#pragma omp teams' directive.
3481 ///
3482 /// \code
3483 /// #pragma omp teams if(a)
3484 /// \endcode
3485 /// In this example directive '#pragma omp teams' has clause 'if' with
3486 /// condition 'a'.
3487 ///
3489  friend class ASTStmtReader;
3491  /// Build directive with the given start and end location.
3492  ///
3493  /// \param StartLoc Starting location of the directive kind.
3494  /// \param EndLoc Ending location of the directive.
3495  ///
3497  : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3498  StartLoc, EndLoc) {}
3499 
3500  /// Build an empty directive.
3501  ///
3502  explicit OMPTeamsDirective()
3503  : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3505 
3506 public:
3507  /// Creates directive with a list of \a Clauses.
3508  ///
3509  /// \param C AST context.
3510  /// \param StartLoc Starting location of the directive kind.
3511  /// \param EndLoc Ending Location of the directive.
3512  /// \param Clauses List of clauses.
3513  /// \param AssociatedStmt Statement, associated with the directive.
3514  ///
3515  static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
3516  SourceLocation EndLoc,
3517  ArrayRef<OMPClause *> Clauses,
3518  Stmt *AssociatedStmt);
3519 
3520  /// Creates an empty directive with the place for \a NumClauses
3521  /// clauses.
3522  ///
3523  /// \param C AST context.
3524  /// \param NumClauses Number of clauses.
3525  ///
3526  static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
3527  unsigned NumClauses, EmptyShell);
3528 
3529  static bool classof(const Stmt *T) {
3530  return T->getStmtClass() == OMPTeamsDirectiveClass;
3531  }
3532 };
3533 
3534 /// This represents '#pragma omp cancellation point' directive.
3535 ///
3536 /// \code
3537 /// #pragma omp cancellation point for
3538 /// \endcode
3539 ///
3540 /// In this example a cancellation point is created for innermost 'for' region.
3542  friend class ASTStmtReader;
3544  OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
3545  /// Build directive with the given start and end location.
3546  ///
3547  /// \param StartLoc Starting location of the directive kind.
3548  /// \param EndLoc Ending location of the directive.
3549  /// statements and child expressions.
3550  ///
3552  : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3553  llvm::omp::OMPD_cancellation_point, StartLoc,
3554  EndLoc) {}
3555 
3556  /// Build an empty directive.
3558  : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3559  llvm::omp::OMPD_cancellation_point,
3561 
3562  /// Set cancel region for current cancellation point.
3563  /// \param CR Cancellation region.
3564  void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
3565 
3566 public:
3567  /// Creates directive.
3568  ///
3569  /// \param C AST context.
3570  /// \param StartLoc Starting location of the directive kind.
3571  /// \param EndLoc Ending Location of the directive.
3572  ///
3573  static OMPCancellationPointDirective *
3574  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3575  OpenMPDirectiveKind CancelRegion);
3576 
3577  /// Creates an empty directive.
3578  ///
3579  /// \param C AST context.
3580  ///
3581  static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
3582  EmptyShell);
3583 
3584  /// Get cancellation region for the current cancellation point.
3585  OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
3586 
3587  static bool classof(const Stmt *T) {
3588  return T->getStmtClass() == OMPCancellationPointDirectiveClass;
3589  }
3590 };
3591 
3592 /// This represents '#pragma omp cancel' directive.
3593 ///
3594 /// \code
3595 /// #pragma omp cancel for
3596 /// \endcode
3597 ///
3598 /// In this example a cancel is created for innermost 'for' region.
3600  friend class ASTStmtReader;
3602  OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
3603  /// Build directive with the given start and end location.
3604  ///
3605  /// \param StartLoc Starting location of the directive kind.
3606  /// \param EndLoc Ending location of the directive.
3607  ///
3609  : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3610  StartLoc, EndLoc) {}
3611 
3612  /// Build an empty directive.
3613  ///
3614  explicit OMPCancelDirective()
3615  : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3617 
3618  /// Set cancel region for current cancellation point.
3619  /// \param CR Cancellation region.
3620  void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
3621 
3622 public:
3623  /// Creates directive.
3624  ///
3625  /// \param C AST context.
3626  /// \param StartLoc Starting location of the directive kind.
3627  /// \param EndLoc Ending Location of the directive.
3628  /// \param Clauses List of clauses.
3629  ///
3630  static OMPCancelDirective *
3631  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3632  ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
3633 
3634  /// Creates an empty directive.
3635  ///
3636  /// \param C AST context.
3637  /// \param NumClauses Number of clauses.
3638  ///
3639  static OMPCancelDirective *CreateEmpty(const ASTContext &C,
3640  unsigned NumClauses, EmptyShell);
3641 
3642  /// Get cancellation region for the current cancellation point.
3643  OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
3644 
3645  static bool classof(const Stmt *T) {
3646  return T->getStmtClass() == OMPCancelDirectiveClass;
3647  }
3648 };
3649 
3650 /// This represents '#pragma omp taskloop' directive.
3651 ///
3652 /// \code
3653 /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
3654 /// \endcode
3655 /// In this example directive '#pragma omp taskloop' has clauses 'private'
3656 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
3657 /// 'num_tasks' with expression 'num'.
3658 ///
3660  friend class ASTStmtReader;
3662  /// true if the construct has inner cancel directive.
3663  bool HasCancel = false;
3664 
3665  /// Build directive with the given start and end location.
3666  ///
3667  /// \param StartLoc Starting location of the directive kind.
3668  /// \param EndLoc Ending location of the directive.
3669  /// \param CollapsedNum Number of collapsed nested loops.
3670  ///
3672  unsigned CollapsedNum)
3673  : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3674  StartLoc, EndLoc, CollapsedNum) {}
3675 
3676  /// Build an empty directive.
3677  ///
3678  /// \param CollapsedNum Number of collapsed nested loops.
3679  ///
3680  explicit OMPTaskLoopDirective(unsigned CollapsedNum)
3681  : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3682  SourceLocation(), SourceLocation(), CollapsedNum) {}
3683 
3684  /// Set cancel state.
3685  void setHasCancel(bool Has) { HasCancel = Has; }
3686 
3687 public:
3688  /// Creates directive with a list of \a Clauses.
3689  ///
3690  /// \param C AST context.
3691  /// \param StartLoc Starting location of the directive kind.
3692  /// \param EndLoc Ending Location of the directive.
3693  /// \param CollapsedNum Number of collapsed loops.
3694  /// \param Clauses List of clauses.
3695  /// \param AssociatedStmt Statement, associated with the directive.
3696  /// \param Exprs Helper expressions for CodeGen.
3697  /// \param HasCancel true if this directive has inner cancel directive.
3698  ///
3699  static OMPTaskLoopDirective *
3700  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3701  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3702  Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3703 
3704  /// Creates an empty directive with the place
3705  /// for \a NumClauses clauses.
3706  ///
3707  /// \param C AST context.
3708  /// \param CollapsedNum Number of collapsed nested loops.
3709  /// \param NumClauses Number of clauses.
3710  ///
3711  static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
3712  unsigned NumClauses,
3713  unsigned CollapsedNum, EmptyShell);
3714 
3715  /// Return true if current directive has inner cancel directive.
3716  bool hasCancel() const { return HasCancel; }
3717 
3718  static bool classof(const Stmt *T) {
3719  return T->getStmtClass() == OMPTaskLoopDirectiveClass;
3720  }
3721 };
3722 
3723 /// This represents '#pragma omp taskloop simd' directive.
3724 ///
3725 /// \code
3726 /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
3727 /// \endcode
3728 /// In this example directive '#pragma omp taskloop simd' has clauses 'private'
3729 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
3730 /// 'num_tasks' with expression 'num'.
3731 ///
3733  friend class ASTStmtReader;
3735  /// Build directive with the given start and end location.
3736  ///
3737  /// \param StartLoc Starting location of the directive kind.
3738  /// \param EndLoc Ending location of the directive.
3739  /// \param CollapsedNum Number of collapsed nested loops.
3740  ///
3742  unsigned CollapsedNum)
3743  : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3744  llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc,
3745  CollapsedNum) {}
3746 
3747  /// Build an empty directive.
3748  ///
3749  /// \param CollapsedNum Number of collapsed nested loops.
3750  ///
3751  explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum)
3752  : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3753  llvm::omp::OMPD_taskloop_simd, SourceLocation(),
3754  SourceLocation(), CollapsedNum) {}
3755 
3756 public:
3757  /// Creates directive with a list of \a Clauses.
3758  ///
3759  /// \param C AST context.
3760  /// \param StartLoc Starting location of the directive kind.
3761  /// \param EndLoc Ending Location of the directive.
3762  /// \param CollapsedNum Number of collapsed loops.
3763  /// \param Clauses List of clauses.
3764  /// \param AssociatedStmt Statement, associated with the directive.
3765  /// \param Exprs Helper expressions for CodeGen.
3766  ///
3767  static OMPTaskLoopSimdDirective *
3768  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3769  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3770  Stmt *AssociatedStmt, const HelperExprs &Exprs);
3771 
3772  /// Creates an empty directive with the place
3773  /// for \a NumClauses clauses.
3774  ///
3775  /// \param C AST context.
3776  /// \param CollapsedNum Number of collapsed nested loops.
3777  /// \param NumClauses Number of clauses.
3778  ///
3779  static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
3780  unsigned NumClauses,
3781  unsigned CollapsedNum,
3782  EmptyShell);
3783 
3784  static bool classof(const Stmt *T) {
3785  return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
3786  }
3787 };
3788 
3789 /// This represents '#pragma omp master taskloop' directive.
3790 ///
3791 /// \code
3792 /// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num)
3793 /// \endcode
3794 /// In this example directive '#pragma omp master taskloop' has clauses
3795 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3796 /// and 'num_tasks' with expression 'num'.
3797 ///
3799  friend class ASTStmtReader;
3801  /// true if the construct has inner cancel directive.
3802  bool HasCancel = false;
3803 
3804  /// Build directive with the given start and end location.
3805  ///
3806  /// \param StartLoc Starting location of the directive kind.
3807  /// \param EndLoc Ending location of the directive.
3808  /// \param CollapsedNum Number of collapsed nested loops.
3809  ///
3811  unsigned CollapsedNum)
3812  : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3813  llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc,
3814  CollapsedNum) {}
3815 
3816  /// Build an empty directive.
3817  ///
3818  /// \param CollapsedNum Number of collapsed nested loops.
3819  ///
3820  explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum)
3821  : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3822  llvm::omp::OMPD_master_taskloop, SourceLocation(),
3823  SourceLocation(), CollapsedNum) {}
3824 
3825  /// Set cancel state.
3826  void setHasCancel(bool Has) { HasCancel = Has; }
3827 
3828 public:
3829  /// Creates directive with a list of \a Clauses.
3830  ///
3831  /// \param C AST context.
3832  /// \param StartLoc Starting location of the directive kind.
3833  /// \param EndLoc Ending Location of the directive.
3834  /// \param CollapsedNum Number of collapsed loops.
3835  /// \param Clauses List of clauses.
3836  /// \param AssociatedStmt Statement, associated with the directive.
3837  /// \param Exprs Helper expressions for CodeGen.
3838  /// \param HasCancel true if this directive has inner cancel directive.
3839  ///
3840  static OMPMasterTaskLoopDirective *
3841  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3842  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3843  Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3844 
3845  /// Creates an empty directive with the place
3846  /// for \a NumClauses clauses.
3847  ///
3848  /// \param C AST context.
3849  /// \param CollapsedNum Number of collapsed nested loops.
3850  /// \param NumClauses Number of clauses.
3851  ///
3852  static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
3853  unsigned NumClauses,
3854  unsigned CollapsedNum,
3855  EmptyShell);
3856 
3857  /// Return true if current directive has inner cancel directive.
3858  bool hasCancel() const { return HasCancel; }
3859 
3860  static bool classof(const Stmt *T) {
3861  return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass;
3862  }
3863 };
3864 
3865 /// This represents '#pragma omp masked taskloop' directive.
3866 ///
3867 /// \code
3868 /// #pragma omp masked taskloop private(a,b) grainsize(val) num_tasks(num)
3869 /// \endcode
3870 /// In this example directive '#pragma omp masked taskloop' has clauses
3871 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3872 /// and 'num_tasks' with expression 'num'.
3873 ///
3875  friend class ASTStmtReader;
3877  /// true if the construct has inner cancel directive.
3878  bool HasCancel = false;
3879 
3880  /// Build directive with the given start and end location.
3881  ///
3882  /// \param StartLoc Starting location of the directive kind.
3883  /// \param EndLoc Ending location of the directive.
3884  /// \param CollapsedNum Number of collapsed nested loops.
3885  ///
3887  unsigned CollapsedNum)
3888  : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
3889  llvm::omp::OMPD_masked_taskloop, StartLoc, EndLoc,
3890  CollapsedNum) {}
3891 
3892  /// Build an empty directive.
3893  ///
3894  /// \param CollapsedNum Number of collapsed nested loops.
3895  ///
3896  explicit OMPMaskedTaskLoopDirective(unsigned CollapsedNum)
3897  : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass,
3898  llvm::omp::OMPD_masked_taskloop, SourceLocation(),
3899  SourceLocation(), CollapsedNum) {}
3900 
3901  /// Set cancel state.
3902  void setHasCancel(bool Has) { HasCancel = Has; }
3903 
3904 public:
3905  /// Creates directive with a list of \a Clauses.
3906  ///
3907  /// \param C AST context.
3908  /// \param StartLoc Starting location of the directive kind.
3909  /// \param EndLoc Ending Location of the directive.
3910  /// \param CollapsedNum Number of collapsed loops.
3911  /// \param Clauses List of clauses.
3912  /// \param AssociatedStmt Statement, associated with the directive.
3913  /// \param Exprs Helper expressions for CodeGen.
3914  /// \param HasCancel true if this directive has inner cancel directive.
3915  ///
3916  static OMPMaskedTaskLoopDirective *
3917  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3918  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3919  Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3920 
3921  /// Creates an empty directive with the place
3922  /// for \a NumClauses clauses.
3923  ///
3924  /// \param C AST context.
3925  /// \param CollapsedNum Number of collapsed nested loops.
3926  /// \param NumClauses Number of clauses.
3927  ///
3928  static OMPMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
3929  unsigned NumClauses,
3930  unsigned CollapsedNum,
3931  EmptyShell);
3932 
3933  /// Return true if current directive has inner cancel directive.
3934  bool hasCancel() const { return HasCancel; }
3935 
3936  static bool classof(const Stmt *T) {
3937  return T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass;
3938  }
3939 };
3940 
3941 /// This represents '#pragma omp master taskloop simd' directive.
3942 ///
3943 /// \code
3944 /// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num)
3945 /// \endcode
3946 /// In this example directive '#pragma omp master taskloop simd' has clauses
3947 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3948 /// and 'num_tasks' with expression 'num'.
3949 ///
3951  friend class ASTStmtReader;
3953  /// Build directive with the given start and end location.
3954  ///
3955  /// \param StartLoc Starting location of the directive kind.
3956  /// \param EndLoc Ending location of the directive.
3957  /// \param CollapsedNum Number of collapsed nested loops.
3958  ///
3960  unsigned CollapsedNum)
3961  : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
3962  llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc,
3963  CollapsedNum) {}
3964 
3965  /// Build an empty directive.
3966  ///
3967  /// \param CollapsedNum Number of collapsed nested loops.
3968  ///
3969  explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum)
3970  : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
3971  llvm::omp::OMPD_master_taskloop_simd, SourceLocation(),
3972  SourceLocation(), CollapsedNum) {}
3973 
3974 public:
3975  /// Creates directive with a list of \p Clauses.
3976  ///
3977  /// \param C AST context.
3978  /// \param StartLoc Starting location of the directive kind.
3979  /// \param EndLoc Ending Location of the directive.
3980  /// \param CollapsedNum Number of collapsed loops.
3981  /// \param Clauses List of clauses.
3982  /// \param AssociatedStmt Statement, associated with the directive.
3983  /// \param Exprs Helper expressions for CodeGen.
3984  ///
3985  static OMPMasterTaskLoopSimdDirective *
3986  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3987  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3988  Stmt *AssociatedStmt, const HelperExprs &Exprs);
3989 
3990  /// Creates an empty directive with the place for \p NumClauses clauses.
3991  ///
3992  /// \param C AST context.
3993  /// \param CollapsedNum Number of collapsed nested loops.
3994  /// \param NumClauses Number of clauses.
3995  ///
3996  static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
3997  unsigned NumClauses,
3998  unsigned CollapsedNum,
3999  EmptyShell);
4000 
4001  static bool classof(const Stmt *T) {
4002  return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass;
4003  }
4004 };
4005 
4006 /// This represents '#pragma omp masked taskloop simd' directive.
4007 ///
4008 /// \code
4009 /// #pragma omp masked taskloop simd private(a,b) grainsize(val) num_tasks(num)
4010 /// \endcode
4011 /// In this example directive '#pragma omp masked taskloop simd' has clauses
4012 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4013 /// and 'num_tasks' with expression 'num'.
4014 ///
4016  friend class ASTStmtReader;
4018  /// Build directive with the given start and end location.
4019  ///
4020  /// \param StartLoc Starting location of the directive kind.
4021  /// \param EndLoc Ending location of the directive.
4022  /// \param CollapsedNum Number of collapsed nested loops.
4023  ///
4025  unsigned CollapsedNum)
4026  : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
4027  llvm::omp::OMPD_masked_taskloop_simd, StartLoc, EndLoc,
4028  CollapsedNum) {}
4029 
4030  /// Build an empty directive.
4031  ///
4032  /// \param CollapsedNum Number of collapsed nested loops.
4033  ///
4034  explicit OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
4035  : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass,
4036  llvm::omp::OMPD_masked_taskloop_simd, SourceLocation(),
4037  SourceLocation(), CollapsedNum) {}
4038 
4039 public:
4040  /// Creates directive with a list of \p Clauses.
4041  ///
4042  /// \param C AST context.
4043  /// \param StartLoc Starting location of the directive kind.
4044  /// \param EndLoc Ending Location of the directive.
4045  /// \param CollapsedNum Number of collapsed loops.
4046  /// \param Clauses List of clauses.
4047  /// \param AssociatedStmt Statement, associated with the directive.
4048  /// \param Exprs Helper expressions for CodeGen.
4049  ///
4050  static OMPMaskedTaskLoopSimdDirective *
4051  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4052  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4053  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4054 
4055  /// Creates an empty directive with the place for \p NumClauses clauses.
4056  ///
4057  /// \param C AST context.
4058  /// \param CollapsedNum Number of collapsed nested loops.
4059  /// \param NumClauses Number of clauses.
4060  ///
4061  static OMPMaskedTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
4062  unsigned NumClauses,
4063  unsigned CollapsedNum,
4064  EmptyShell);
4065 
4066  static bool classof(const Stmt *T) {
4067  return T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass;
4068  }
4069 };
4070 
4071 /// This represents '#pragma omp parallel master taskloop' directive.
4072 ///
4073 /// \code
4074 /// #pragma omp parallel master taskloop private(a,b) grainsize(val)
4075 /// num_tasks(num)
4076 /// \endcode
4077 /// In this example directive '#pragma omp parallel master taskloop' has clauses
4078 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4079 /// and 'num_tasks' with expression 'num'.
4080 ///
4082  friend class ASTStmtReader;
4084  /// true if the construct has inner cancel directive.
4085  bool HasCancel = false;
4086 
4087  /// Build directive with the given start and end location.
4088  ///
4089  /// \param StartLoc Starting location of the directive kind.
4090  /// \param EndLoc Ending location of the directive.
4091  /// \param CollapsedNum Number of collapsed nested loops.
4092  ///
4094  SourceLocation EndLoc,
4095  unsigned CollapsedNum)
4096  : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
4097  llvm::omp::OMPD_parallel_master_taskloop, StartLoc,
4098  EndLoc, CollapsedNum) {}
4099 
4100  /// Build an empty directive.
4101  ///
4102  /// \param CollapsedNum Number of collapsed nested loops.
4103  ///
4104  explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum)
4105  : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
4106  llvm::omp::OMPD_parallel_master_taskloop,
4107  SourceLocation(), SourceLocation(), CollapsedNum) {}
4108 
4109  /// Set cancel state.
4110  void setHasCancel(bool Has) { HasCancel = Has; }
4111 
4112 public:
4113  /// Creates directive with a list of \a Clauses.
4114  ///
4115  /// \param C AST context.
4116  /// \param StartLoc Starting location of the directive kind.
4117  /// \param EndLoc Ending Location of the directive.
4118  /// \param CollapsedNum Number of collapsed loops.
4119  /// \param Clauses List of clauses.
4120  /// \param AssociatedStmt Statement, associated with the directive.
4121  /// \param Exprs Helper expressions for CodeGen.
4122  /// \param HasCancel true if this directive has inner cancel directive.
4123  ///
4124  static OMPParallelMasterTaskLoopDirective *
4125  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4126  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4127  Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
4128 
4129  /// Creates an empty directive with the place
4130  /// for \a NumClauses clauses.
4131  ///
4132  /// \param C AST context.
4133  /// \param CollapsedNum Number of collapsed nested loops.
4134  /// \param NumClauses Number of clauses.
4135  ///
4136  static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
4137  unsigned NumClauses,
4138  unsigned CollapsedNum,
4139  EmptyShell);
4140 
4141  /// Return true if current directive has inner cancel directive.
4142  bool hasCancel() const { return HasCancel; }
4143 
4144  static bool classof(const Stmt *T) {
4145  return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass;
4146  }
4147 };
4148 
4149 /// This represents '#pragma omp parallel masked taskloop' directive.
4150 ///
4151 /// \code
4152 /// #pragma omp parallel masked taskloop private(a,b) grainsize(val)
4153 /// num_tasks(num)
4154 /// \endcode
4155 /// In this example directive '#pragma omp parallel masked taskloop' has clauses
4156 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
4157 /// and 'num_tasks' with expression 'num'.
4158 ///
4160  friend class ASTStmtReader;
4162  /// true if the construct has inner cancel directive.
4163  bool HasCancel = false;
4164 
4165  /// Build directive with the given start and end location.
4166  ///
4167  /// \param StartLoc Starting location of the directive kind.
4168  /// \param EndLoc Ending location of the directive.
4169  /// \param CollapsedNum Number of collapsed nested loops.
4170  ///
4172  SourceLocation EndLoc,
4173  unsigned CollapsedNum)
4174  : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
4175  llvm::omp::OMPD_parallel_masked_taskloop, StartLoc,
4176  EndLoc, CollapsedNum) {}
4177 
4178  /// Build an empty directive.
4179  ///
4180  /// \param CollapsedNum Number of collapsed nested loops.
4181  ///
4182  explicit OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum)
4183  : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass,
4184  llvm::omp::OMPD_parallel_masked_taskloop,
4185  SourceLocation(), SourceLocation(), CollapsedNum) {}
4186 
4187  /// Set cancel state.
4188  void setHasCancel(bool Has) { HasCancel = Has; }
4189 
4190 public:
4191  /// Creates directive with a list of \a Clauses.
4192  ///
4193  /// \param C AST context.
4194  /// \param StartLoc Starting location of the directive kind.
4195  /// \param EndLoc Ending Location of the directive.
4196  /// \param CollapsedNum Number of collapsed loops.
4197  /// \param Clauses List of clauses.
4198  /// \param AssociatedStmt Statement, associated with the directive.
4199  /// \param Exprs Helper expressions for CodeGen.
4200  /// \param HasCancel true if this directive has inner cancel directive.
4201  ///
4202  static OMPParallelMaskedTaskLoopDirective *
4203  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4204  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4205  Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
4206 
4207  /// Creates an empty directive with the place
4208  /// for \a NumClauses clauses.
4209  ///
4210  /// \param C AST context.
4211  /// \param CollapsedNum Number of collapsed nested loops.
4212  /// \param NumClauses Number of clauses.
4213  ///
4214  static OMPParallelMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C,
4215  unsigned NumClauses,
4216  unsigned CollapsedNum,
4217  EmptyShell);
4218 
4219  /// Return true if current directive has inner cancel directive.
4220  bool hasCancel() const { return HasCancel; }
4221 
4222  static bool classof(const Stmt *T) {
4223  return T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass;
4224  }
4225 };
4226 
4227 /// This represents '#pragma omp parallel master taskloop simd' directive.
4228 ///
4229 /// \code
4230 /// #pragma omp parallel master taskloop simd private(a,b) grainsize(val)
4231 /// num_tasks(num)
4232 /// \endcode
4233 /// In this example directive '#pragma omp parallel master taskloop simd' has
4234 /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
4235 /// expression 'val' and 'num_tasks' with expression 'num'.
4236 ///
4238  friend class ASTStmtReader;
4240  /// Build directive with the given start and end location.
4241  ///
4242  /// \param StartLoc Starting location of the directive kind.
4243  /// \param EndLoc Ending location of the directive.
4244  /// \param CollapsedNum Number of collapsed nested loops.
4245  ///
4247  SourceLocation EndLoc,
4248  unsigned CollapsedNum)
4249  : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
4250  llvm::omp::OMPD_parallel_master_taskloop_simd,
4251  StartLoc, EndLoc, CollapsedNum) {}
4252 
4253  /// Build an empty directive.
4254  ///
4255  /// \param CollapsedNum Number of collapsed nested loops.
4256  ///
4257  explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum)
4258  : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
4259  llvm::omp::OMPD_parallel_master_taskloop_simd,
4260  SourceLocation(), SourceLocation(), CollapsedNum) {}
4261 
4262 public:
4263  /// Creates directive with a list of \p Clauses.
4264  ///
4265  /// \param C AST context.
4266  /// \param StartLoc Starting location of the directive kind.
4267  /// \param EndLoc Ending Location of the directive.
4268  /// \param CollapsedNum Number of collapsed loops.
4269  /// \param Clauses List of clauses.
4270  /// \param AssociatedStmt Statement, associated with the directive.
4271  /// \param Exprs Helper expressions for CodeGen.
4272  ///
4273  static OMPParallelMasterTaskLoopSimdDirective *
4274  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4275  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4276  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4277 
4278  /// Creates an empty directive with the place
4279  /// for \a NumClauses clauses.
4280  ///
4281  /// \param C AST context.
4282  /// \param CollapsedNum Number of collapsed nested loops.
4283  /// \param NumClauses Number of clauses.
4284  ///
4285  static OMPParallelMasterTaskLoopSimdDirective *
4286  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4287  EmptyShell);
4288 
4289  static bool classof(const Stmt *T) {
4290  return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass;
4291  }
4292 };
4293 
4294 /// This represents '#pragma omp parallel masked taskloop simd' directive.
4295 ///
4296 /// \code
4297 /// #pragma omp parallel masked taskloop simd private(a,b) grainsize(val)
4298 /// num_tasks(num)
4299 /// \endcode
4300 /// In this example directive '#pragma omp parallel masked taskloop simd' has
4301 /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
4302 /// expression 'val' and 'num_tasks' with expression 'num'.
4303 ///
4305  friend class ASTStmtReader;
4307  /// Build directive with the given start and end location.
4308  ///
4309  /// \param StartLoc Starting location of the directive kind.
4310  /// \param EndLoc Ending location of the directive.
4311  /// \param CollapsedNum Number of collapsed nested loops.
4312  ///
4314  SourceLocation EndLoc,
4315  unsigned CollapsedNum)
4316  : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
4317  llvm::omp::OMPD_parallel_masked_taskloop_simd,
4318  StartLoc, EndLoc, CollapsedNum) {}
4319 
4320  /// Build an empty directive.
4321  ///
4322  /// \param CollapsedNum Number of collapsed nested loops.
4323  ///
4324  explicit OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum)
4325  : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass,
4326  llvm::omp::OMPD_parallel_masked_taskloop_simd,
4327  SourceLocation(), SourceLocation(), CollapsedNum) {}
4328 
4329 public:
4330  /// Creates directive with a list of \p Clauses.
4331  ///
4332  /// \param C AST context.
4333  /// \param StartLoc Starting location of the directive kind.
4334  /// \param EndLoc Ending Location of the directive.
4335  /// \param CollapsedNum Number of collapsed loops.
4336  /// \param Clauses List of clauses.
4337  /// \param AssociatedStmt Statement, associated with the directive.
4338  /// \param Exprs Helper expressions for CodeGen.
4339  ///
4340  static OMPParallelMaskedTaskLoopSimdDirective *
4341  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4342  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4343  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4344 
4345  /// Creates an empty directive with the place
4346  /// for \a NumClauses clauses.
4347  ///
4348  /// \param C AST context.
4349  /// \param CollapsedNum Number of collapsed nested loops.
4350  /// \param NumClauses Number of clauses.
4351  ///
4352  static OMPParallelMaskedTaskLoopSimdDirective *
4353  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4354  EmptyShell);
4355 
4356  static bool classof(const Stmt *T) {
4357  return T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass;
4358  }
4359 };
4360 
4361 /// This represents '#pragma omp distribute' directive.
4362 ///
4363 /// \code
4364 /// #pragma omp distribute private(a,b)
4365 /// \endcode
4366 /// In this example directive '#pragma omp distribute' has clauses 'private'
4367 /// with the variables 'a' and 'b'
4368 ///
4370  friend class ASTStmtReader;
4372 
4373  /// Build directive with the given start and end location.
4374  ///
4375  /// \param StartLoc Starting location of the directive kind.
4376  /// \param EndLoc Ending location of the directive.
4377  /// \param CollapsedNum Number of collapsed nested loops.
4378  ///
4380  unsigned CollapsedNum)
4381  : OMPLoopDirective(OMPDistributeDirectiveClass,
4382  llvm::omp::OMPD_distribute, StartLoc, EndLoc,
4383  CollapsedNum) {}
4384 
4385  /// Build an empty directive.
4386  ///
4387  /// \param CollapsedNum Number of collapsed nested loops.
4388  ///
4389  explicit OMPDistributeDirective(unsigned CollapsedNum)
4390  : OMPLoopDirective(OMPDistributeDirectiveClass,
4391  llvm::omp::OMPD_distribute, SourceLocation(),
4392  SourceLocation(), CollapsedNum) {}
4393 
4394 public:
4395  /// Creates directive with a list of \a Clauses.
4396  ///
4397  /// \param C AST context.
4398  /// \param StartLoc Starting location of the directive kind.
4399  /// \param EndLoc Ending Location of the directive.
4400  /// \param CollapsedNum Number of collapsed loops.
4401  /// \param Clauses List of clauses.
4402  /// \param AssociatedStmt Statement, associated with the directive.
4403  /// \param Exprs Helper expressions for CodeGen.
4404  ///
4405  static OMPDistributeDirective *
4406  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4407  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4408  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4409 
4410  /// Creates an empty directive with the place
4411  /// for \a NumClauses clauses.
4412  ///
4413  /// \param C AST context.
4414  /// \param CollapsedNum Number of collapsed nested loops.
4415  /// \param NumClauses Number of clauses.
4416  ///
4417  static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
4418  unsigned NumClauses,
4419  unsigned CollapsedNum, EmptyShell);
4420 
4421  static bool classof(const Stmt *T) {
4422  return T->getStmtClass() == OMPDistributeDirectiveClass;
4423  }
4424 };
4425 
4426 /// This represents '#pragma omp target update' directive.
4427 ///
4428 /// \code
4429 /// #pragma omp target update to(a) from(b) device(1)
4430 /// \endcode
4431 /// In this example directive '#pragma omp target update' has clause 'to' with
4432 /// argument 'a', clause 'from' with argument 'b' and clause 'device' with
4433 /// argument '1'.
4434 ///
4436  friend class ASTStmtReader;
4438  /// Build directive with the given start and end location.
4439  ///
4440  /// \param StartLoc Starting location of the directive kind.
4441  /// \param EndLoc Ending Location of the directive.
4442  ///
4444  : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
4445  llvm::omp::OMPD_target_update, StartLoc,
4446  EndLoc) {}
4447 
4448  /// Build an empty directive.
4449  ///
4450  explicit OMPTargetUpdateDirective()
4451  : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
4452  llvm::omp::OMPD_target_update, SourceLocation(),
4453  SourceLocation()) {}
4454 
4455 public:
4456  /// Creates directive with a list of \a Clauses.
4457  ///
4458  /// \param C AST context.
4459  /// \param StartLoc Starting location of the directive kind.
4460  /// \param EndLoc Ending Location of the directive.
4461  /// \param Clauses List of clauses.
4462  /// \param AssociatedStmt Statement, associated with the directive.
4463  ///
4464  static OMPTargetUpdateDirective *
4465  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4466  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
4467 
4468  /// Creates an empty directive with the place for \a NumClauses
4469  /// clauses.
4470  ///
4471  /// \param C AST context.
4472  /// \param NumClauses The number of clauses.
4473  ///
4474  static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C,
4475  unsigned NumClauses, EmptyShell);
4476 
4477  static bool classof(const Stmt *T) {
4478  return T->getStmtClass() == OMPTargetUpdateDirectiveClass;
4479  }
4480 };
4481 
4482 /// This represents '#pragma omp distribute parallel for' composite
4483 /// directive.
4484 ///
4485 /// \code
4486 /// #pragma omp distribute parallel for private(a,b)
4487 /// \endcode
4488 /// In this example directive '#pragma omp distribute parallel for' has clause
4489 /// 'private' with the variables 'a' and 'b'
4490 ///
4492  friend class ASTStmtReader;
4494  /// true if the construct has inner cancel directive.
4495  bool HasCancel = false;
4496 
4497  /// Build directive with the given start and end location.
4498  ///
4499  /// \param StartLoc Starting location of the directive kind.
4500  /// \param EndLoc Ending location of the directive.
4501  /// \param CollapsedNum Number of collapsed nested loops.
4502  ///
4504  SourceLocation EndLoc,
4505  unsigned CollapsedNum)
4506  : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4507  llvm::omp::OMPD_distribute_parallel_for, StartLoc,
4508  EndLoc, CollapsedNum) {}
4509 
4510  /// Build an empty directive.
4511  ///
4512  /// \param CollapsedNum Number of collapsed nested loops.
4513  ///
4514  explicit OMPDistributeParallelForDirective(unsigned CollapsedNum)
4515  : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4516  llvm::omp::OMPD_distribute_parallel_for,
4517  SourceLocation(), SourceLocation(), CollapsedNum) {}
4518 
4519  /// Sets special task reduction descriptor.
4520  void setTaskReductionRefExpr(Expr *E) {
4522  getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E;
4523  }
4524 
4525  /// Set cancel state.
4526  void setHasCancel(bool Has) { HasCancel = Has; }
4527 
4528 public:
4529  /// Creates directive with a list of \a Clauses.
4530  ///
4531  /// \param C AST context.
4532  /// \param StartLoc Starting location of the directive kind.
4533  /// \param EndLoc Ending Location of the directive.
4534  /// \param CollapsedNum Number of collapsed loops.
4535  /// \param Clauses List of clauses.
4536  /// \param AssociatedStmt Statement, associated with the directive.
4537  /// \param Exprs Helper expressions for CodeGen.
4538  /// \param TaskRedRef Task reduction special reference expression to handle
4539  /// taskgroup descriptor.
4540  /// \param HasCancel true if this directive has inner cancel directive.
4541  ///
4542  static OMPDistributeParallelForDirective *
4543  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4544  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4545  Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
4546  bool HasCancel);
4547 
4548  /// Creates an empty directive with the place
4549  /// for \a NumClauses clauses.
4550  ///
4551  /// \param C AST context.
4552  /// \param CollapsedNum Number of collapsed nested loops.
4553  /// \param NumClauses Number of clauses.
4554  ///
4555  static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C,
4556  unsigned NumClauses,
4557  unsigned CollapsedNum,
4558  EmptyShell);
4559 
4560  /// Returns special task reduction reference expression.
4562  return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
4563  getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]);
4564  }
4566  return const_cast<OMPDistributeParallelForDirective *>(this)
4568  }
4569 
4570  /// Return true if current directive has inner cancel directive.
4571  bool hasCancel() const { return HasCancel; }
4572 
4573  static bool classof(const Stmt *T) {
4574  return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
4575  }
4576 };
4577 
4578 /// This represents '#pragma omp distribute parallel for simd' composite
4579 /// directive.
4580 ///
4581 /// \code
4582 /// #pragma omp distribute parallel for simd private(x)
4583 /// \endcode
4584 /// In this example directive '#pragma omp distribute parallel for simd' has
4585 /// clause 'private' with the variables 'x'
4586 ///
4588  friend class ASTStmtReader;
4590 
4591  /// Build directive with the given start and end location.
4592  ///
4593  /// \param StartLoc Starting location of the directive kind.
4594  /// \param EndLoc Ending location of the directive.
4595  /// \param CollapsedNum Number of collapsed nested loops.
4596  ///
4598  SourceLocation EndLoc,
4599  unsigned CollapsedNum)
4600  : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4601  llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc,
4602  EndLoc, CollapsedNum) {}
4603 
4604  /// Build an empty directive.
4605  ///
4606  /// \param CollapsedNum Number of collapsed nested loops.
4607  ///
4608  explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum)
4609  : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4610  llvm::omp::OMPD_distribute_parallel_for_simd,
4611  SourceLocation(), SourceLocation(), CollapsedNum) {}
4612 
4613 public:
4614  /// Creates directive with a list of \a Clauses.
4615  ///
4616  /// \param C AST context.
4617  /// \param StartLoc Starting location of the directive kind.
4618  /// \param EndLoc Ending Location of the directive.
4619  /// \param CollapsedNum Number of collapsed loops.
4620  /// \param Clauses List of clauses.
4621  /// \param AssociatedStmt Statement, associated with the directive.
4622  /// \param Exprs Helper expressions for CodeGen.
4623  ///
4624  static OMPDistributeParallelForSimdDirective *Create(
4625  const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4626  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4627  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4628 
4629  /// Creates an empty directive with the place for \a NumClauses clauses.
4630  ///
4631  /// \param C AST context.
4632  /// \param CollapsedNum Number of collapsed nested loops.
4633  /// \param NumClauses Number of clauses.
4634  ///
4635  static OMPDistributeParallelForSimdDirective *CreateEmpty(
4636  const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4637  EmptyShell);
4638 
4639  static bool classof(const Stmt *T) {
4640  return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass;
4641  }
4642 };
4643 
4644 /// This represents '#pragma omp distribute simd' composite directive.
4645 ///
4646 /// \code
4647 /// #pragma omp distribute simd private(x)
4648 /// \endcode
4649 /// In this example directive '#pragma omp distribute simd' has clause
4650 /// 'private' with the variables 'x'
4651 ///
4653  friend class ASTStmtReader;
4655 
4656  /// Build directive with the given start and end location.
4657  ///
4658  /// \param StartLoc Starting location of the directive kind.
4659  /// \param EndLoc Ending location of the directive.
4660  /// \param CollapsedNum Number of collapsed nested loops.
4661  ///
4663  unsigned CollapsedNum)
4664  : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4665  llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc,
4666  CollapsedNum) {}
4667 
4668  /// Build an empty directive.
4669  ///
4670  /// \param CollapsedNum Number of collapsed nested loops.
4671  ///
4672  explicit OMPDistributeSimdDirective(unsigned CollapsedNum)
4673  : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4674  llvm::omp::OMPD_distribute_simd, SourceLocation(),
4675  SourceLocation(), CollapsedNum) {}
4676 
4677 public:
4678  /// Creates directive with a list of \a Clauses.
4679  ///
4680  /// \param C AST context.
4681  /// \param StartLoc Starting location of the directive kind.
4682  /// \param EndLoc Ending Location of the directive.
4683  /// \param CollapsedNum Number of collapsed loops.
4684  /// \param Clauses List of clauses.
4685  /// \param AssociatedStmt Statement, associated with the directive.
4686  /// \param Exprs Helper expressions for CodeGen.
4687  ///
4688  static OMPDistributeSimdDirective *
4689  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4690  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4691  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4692 
4693  /// Creates an empty directive with the place for \a NumClauses clauses.
4694  ///
4695  /// \param C AST context.
4696  /// \param CollapsedNum Number of collapsed nested loops.
4697  /// \param NumClauses Number of clauses.
4698  ///
4699  static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C,
4700  unsigned NumClauses,
4701  unsigned CollapsedNum,
4702  EmptyShell);
4703 
4704  static bool classof(const Stmt *T) {
4705  return T->getStmtClass() == OMPDistributeSimdDirectiveClass;
4706  }
4707 };
4708 
4709 /// This represents '#pragma omp target parallel for simd' directive.
4710 ///
4711 /// \code
4712 /// #pragma omp target parallel for simd private(a) map(b) safelen(c)
4713 /// \endcode
4714 /// In this example directive '#pragma omp target parallel for simd' has clauses
4715 /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen'
4716 /// with the variable 'c'.
4717 ///
4719  friend class ASTStmtReader;
4721 
4722  /// Build directive with the given start and end location.
4723  ///
4724  /// \param StartLoc Starting location of the directive kind.
4725  /// \param EndLoc Ending location of the directive.
4726  /// \param CollapsedNum Number of collapsed nested loops.
4727  ///
4729  SourceLocation EndLoc,
4730  unsigned CollapsedNum)
4731  : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4732  llvm::omp::OMPD_target_parallel_for_simd, StartLoc,
4733  EndLoc, CollapsedNum) {}
4734 
4735  /// Build an empty directive.
4736  ///
4737  /// \param CollapsedNum Number of collapsed nested loops.
4738  ///
4739  explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum)
4740  : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4741  llvm::omp::OMPD_target_parallel_for_simd,
4742  SourceLocation(), SourceLocation(), CollapsedNum) {}
4743 
4744 public:
4745  /// Creates directive with a list of \a Clauses.
4746  ///
4747  /// \param C AST context.
4748  /// \param StartLoc Starting location of the directive kind.
4749  /// \param EndLoc Ending Location of the directive.
4750  /// \param CollapsedNum Number of collapsed loops.
4751  /// \param Clauses List of clauses.
4752  /// \param AssociatedStmt Statement, associated with the directive.
4753  /// \param Exprs Helper expressions for CodeGen.
4754  ///
4755  static OMPTargetParallelForSimdDirective *
4756  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4757  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4758  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4759 
4760  /// Creates an empty directive with the place for \a NumClauses clauses.
4761  ///
4762  /// \param C AST context.
4763  /// \param CollapsedNum Number of collapsed nested loops.
4764  /// \param NumClauses Number of clauses.
4765  ///
4766  static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C,
4767  unsigned NumClauses,
4768  unsigned CollapsedNum,
4769  EmptyShell);
4770 
4771  static bool classof(const Stmt *T) {
4772  return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
4773  }
4774 };
4775 
4776 /// This represents '#pragma omp target simd' directive.
4777 ///
4778 /// \code
4779 /// #pragma omp target simd private(a) map(b) safelen(c)
4780 /// \endcode
4781 /// In this example directive '#pragma omp target simd' has clauses 'private'
4782 /// with the variable 'a', 'map' with the variable 'b' and 'safelen' with
4783 /// the variable 'c'.
4784 ///
4786  friend class ASTStmtReader;
4788 
4789  /// Build directive with the given start and end location.
4790  ///
4791  /// \param StartLoc Starting location of the directive kind.
4792  /// \param EndLoc Ending location of the directive.
4793  /// \param CollapsedNum Number of collapsed nested loops.
4794  ///
4796  unsigned CollapsedNum)
4797  : OMPLoopDirective(OMPTargetSimdDirectiveClass,
4798  llvm::omp::OMPD_target_simd, StartLoc, EndLoc,
4799  CollapsedNum) {}
4800 
4801  /// Build an empty directive.
4802  ///
4803  /// \param CollapsedNum Number of collapsed nested loops.
4804  ///
4805  explicit OMPTargetSimdDirective(unsigned CollapsedNum)
4806  : OMPLoopDirective(OMPTargetSimdDirectiveClass,
4807  llvm::omp::OMPD_target_simd, SourceLocation(),
4808  SourceLocation(), CollapsedNum) {}
4809 
4810 public:
4811  /// Creates directive with a list of \a Clauses.
4812  ///
4813  /// \param C AST context.
4814  /// \param StartLoc Starting location of the directive kind.
4815  /// \param EndLoc Ending Location of the directive.
4816  /// \param CollapsedNum Number of collapsed loops.
4817  /// \param Clauses List of clauses.
4818  /// \param AssociatedStmt Statement, associated with the directive.
4819  /// \param Exprs Helper expressions for CodeGen.
4820  ///
4821  static OMPTargetSimdDirective *
4822  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4823  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4824  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4825 
4826  /// Creates an empty directive with the place for \a NumClauses clauses.
4827  ///
4828  /// \param C AST context.
4829  /// \param CollapsedNum Number of collapsed nested loops.
4830  /// \param NumClauses Number of clauses.
4831  ///
4832  static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C,
4833  unsigned NumClauses,
4834  unsigned CollapsedNum,
4835  EmptyShell);
4836 
4837  static bool classof(const Stmt *T) {
4838  return T->getStmtClass() == OMPTargetSimdDirectiveClass;
4839  }
4840 };
4841 
4842 /// This represents '#pragma omp teams distribute' directive.
4843 ///
4844 /// \code
4845 /// #pragma omp teams distribute private(a,b)
4846 /// \endcode
4847 /// In this example directive '#pragma omp teams distribute' has clauses
4848 /// 'private' with the variables 'a' and 'b'
4849 ///
4851  friend class ASTStmtReader;
4853 
4854  /// Build directive with the given start and end location.
4855  ///
4856  /// \param StartLoc Starting location of the directive kind.
4857  /// \param EndLoc Ending location of the directive.
4858  /// \param CollapsedNum Number of collapsed nested loops.
4859  ///
4861  unsigned CollapsedNum)
4862  : OMPLoopDirective(OMPTeamsDistributeDirectiveClass,
4863  llvm::omp::OMPD_teams_distribute, StartLoc, EndLoc,
4864  CollapsedNum) {}
4865 
4866  /// Build an empty directive.
4867  ///
4868  /// \param CollapsedNum Number of collapsed nested loops.
4869  ///
4870  explicit OMPTeamsDistributeDirective(unsigned CollapsedNum)
4871  : OMPLoopDirective(OMPTeamsDistributeDirectiveClass,
4872  llvm::omp::OMPD_teams_distribute, SourceLocation(),
4873  SourceLocation(), CollapsedNum) {}
4874 
4875 public:
4876  /// Creates directive with a list of \a Clauses.
4877  ///
4878  /// \param C AST context.
4879  /// \param StartLoc Starting location of the directive kind.
4880  /// \param EndLoc Ending Location of the directive.
4881  /// \param CollapsedNum Number of collapsed loops.
4882  /// \param Clauses List of clauses.
4883  /// \param AssociatedStmt Statement, associated with the directive.
4884  /// \param Exprs Helper expressions for CodeGen.
4885  ///
4886  static OMPTeamsDistributeDirective *
4887  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4888  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4889  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4890 
4891  /// Creates an empty directive with the place for \a NumClauses clauses.
4892  ///
4893  /// \param C AST context.
4894  /// \param CollapsedNum Number of collapsed nested loops.
4895  /// \param NumClauses Number of clauses.
4896  ///
4897  static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C,
4898  unsigned NumClauses,
4899  unsigned CollapsedNum,
4900  EmptyShell);
4901 
4902  static bool classof(const Stmt *T) {
4903  return T->getStmtClass() == OMPTeamsDistributeDirectiveClass;
4904  }
4905 };
4906 
4907 /// This represents '#pragma omp teams distribute simd'
4908 /// combined directive.
4909 ///
4910 /// \code
4911 /// #pragma omp teams distribute simd private(a,b)
4912 /// \endcode
4913 /// In this example directive '#pragma omp teams distribute simd'
4914 /// has clause 'private' with the variables 'a' and 'b'
4915 ///
4917  friend class ASTStmtReader;
4919 
4920  /// Build directive with the given start and end location.
4921  ///
4922  /// \param StartLoc Starting location of the directive kind.
4923  /// \param EndLoc Ending location of the directive.
4924  /// \param CollapsedNum Number of collapsed nested loops.
4925  ///
4927  SourceLocation EndLoc, unsigned CollapsedNum)
4928  : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass,
4929  llvm::omp::OMPD_teams_distribute_simd, StartLoc,
4930  EndLoc, CollapsedNum) {}
4931 
4932  /// Build an empty directive.
4933  ///
4934  /// \param CollapsedNum Number of collapsed nested loops.
4935  ///
4936  explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum)
4937  : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass,
4938  llvm::omp::OMPD_teams_distribute_simd,
4939  SourceLocation(), SourceLocation(), CollapsedNum) {}
4940 
4941 public:
4942  /// Creates directive with a list of \a Clauses.
4943  ///
4944  /// \param C AST context.
4945  /// \param StartLoc Starting location of the directive kind.
4946  /// \param EndLoc Ending Location of the directive.
4947  /// \param CollapsedNum Number of collapsed loops.
4948  /// \param Clauses List of clauses.
4949  /// \param AssociatedStmt Statement, associated with the directive.
4950  /// \param Exprs Helper expressions for CodeGen.
4951  ///
4952  static OMPTeamsDistributeSimdDirective *
4953  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4954  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4955  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4956 
4957  /// Creates an empty directive with the place
4958  /// for \a NumClauses clauses.
4959  ///
4960  /// \param C AST context.
4961  /// \param CollapsedNum Number of collapsed nested loops.
4962  /// \param NumClauses Number of clauses.
4963  ///
4964  static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C,
4965  unsigned NumClauses,
4966  unsigned CollapsedNum,
4967  EmptyShell);
4968 
4969  static bool classof(const Stmt *T) {
4970  return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass;
4971  }
4972 };
4973 
4974 /// This represents '#pragma omp teams distribute parallel for simd' composite
4975 /// directive.
4976 ///
4977 /// \code
4978 /// #pragma omp teams distribute parallel for simd private(x)
4979 /// \endcode
4980 /// In this example directive '#pragma omp teams distribute parallel for simd'
4981 /// has clause 'private' with the variables 'x'
4982 ///
4984  : public OMPLoopDirective {
4985  friend class ASTStmtReader;
4987 
4988  /// Build directive with the given start and end location.
4989  ///
4990  /// \param StartLoc Starting location of the directive kind.
4991  /// \param EndLoc Ending location of the directive.
4992  /// \param CollapsedNum Number of collapsed nested loops.
4993  ///
4995  SourceLocation EndLoc,
4996  unsigned CollapsedNum)
4997  : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass,
4998  llvm::omp::OMPD_teams_distribute_parallel_for_simd,
4999  StartLoc, EndLoc, CollapsedNum) {}
5000 
5001  /// Build an empty directive.
5002  ///
5003  /// \param CollapsedNum Number of collapsed nested loops.
5004  ///
5005  explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum)
5006  : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass,
5007  llvm::omp::OMPD_teams_distribute_parallel_for_simd,
5008  SourceLocation(), SourceLocation(), CollapsedNum) {}
5009 
5010 public:
5011  /// Creates directive with a list of \a Clauses.
5012  ///
5013  /// \param C AST context.
5014  /// \param StartLoc Starting location of the directive kind.
5015  /// \param EndLoc Ending Location of the directive.
5016  /// \param CollapsedNum Number of collapsed loops.
5017  /// \param Clauses List of clauses.
5018  /// \param AssociatedStmt Statement, associated with the directive.
5019  /// \param Exprs Helper expressions for CodeGen.
5020  ///
5021  static OMPTeamsDistributeParallelForSimdDirective *
5022  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5023  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5024  Stmt *AssociatedStmt, const HelperExprs &Exprs);
5025 
5026  /// Creates an empty directive with the place for \a NumClauses clauses.
5027  ///
5028  /// \param C AST context.
5029  /// \param CollapsedNum Number of collapsed nested loops.
5030  /// \param NumClauses Number of clauses.
5031  ///
5032  static OMPTeamsDistributeParallelForSimdDirective *
5033  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5034  EmptyShell);
5035 
5036  static bool classof(const Stmt *T) {
5037  return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass;
5038  }
5039 };
5040 
5041 /// This represents '#pragma omp teams distribute parallel for' composite
5042 /// directive.
5043 ///
5044 /// \code
5045 /// #pragma omp teams distribute parallel for private(x)
5046 /// \endcode
5047 /// In this example directive '#pragma omp teams distribute parallel for'
5048 /// has clause 'private' with the variables 'x'
5049 ///
5051  friend class ASTStmtReader;
5053  /// true if the construct has inner cancel directive.
5054  bool HasCancel = false;
5055 
5056  /// Build directive with the given start and end location.
5057  ///
5058  /// \param StartLoc Starting location of the directive kind.
5059  /// \param EndLoc Ending location of the directive.
5060  /// \param CollapsedNum Number of collapsed nested loops.
5061  ///
5063  SourceLocation EndLoc,
5064  unsigned CollapsedNum)
5065  : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass,
5066  llvm::omp::OMPD_teams_distribute_parallel_for,
5067  StartLoc, EndLoc, CollapsedNum) {}
5068 
5069  /// Build an empty directive.
5070  ///
5071  /// \param CollapsedNum Number of collapsed nested loops.
5072  ///
5073  explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum)
5074  : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass,
5075  llvm::omp::OMPD_teams_distribute_parallel_for,
5076  SourceLocation(), SourceLocation(), CollapsedNum) {}
5077 
5078  /// Sets special task reduction descriptor.
5079  void setTaskReductionRefExpr(Expr *E) {
5081  getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)] = E;
5082  }
5083 
5084  /// Set cancel state.
5085  void setHasCancel(bool Has) { HasCancel = Has; }
5086 
5087 public:
5088  /// Creates directive with a list of \a Clauses.
5089  ///
5090  /// \param C AST context.
5091  /// \param StartLoc Starting location of the directive kind.
5092  /// \param EndLoc Ending Location of the directive.
5093  /// \param CollapsedNum Number of collapsed loops.
5094  /// \param Clauses List of clauses.
5095  /// \param AssociatedStmt Statement, associated with the directive.
5096  /// \param Exprs Helper expressions for CodeGen.
5097  /// \param TaskRedRef Task reduction special reference expression to handle
5098  /// taskgroup descriptor.
5099  /// \param HasCancel true if this directive has inner cancel directive.
5100  ///
5101  static OMPTeamsDistributeParallelForDirective *
5102  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5103  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5104  Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
5105  bool HasCancel);
5106 
5107  /// Creates an empty directive with the place for \a NumClauses clauses.
5108  ///
5109  /// \param C AST context.
5110  /// \param CollapsedNum Number of collapsed nested loops.
5111  /// \param NumClauses Number of clauses.
5112  ///
5113  static OMPTeamsDistributeParallelForDirective *
5114  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5115  EmptyShell);
5116 
5117  /// Returns special task reduction reference expression.
5119  return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
5120  getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)]);
5121  }
5123  return const_cast<OMPTeamsDistributeParallelForDirective *>(this)
5125  }
5126 
5127  /// Return true if current directive has inner cancel directive.
5128  bool hasCancel() const { return