clang  15.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() == OMPMasterTaskLoopDirectiveClass ||
1527  T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass ||
1528  T->getStmtClass() == OMPGenericLoopDirectiveClass ||
1529  T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass ||
1530  T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass ||
1531  T->getStmtClass() == OMPParallelGenericLoopDirectiveClass ||
1532  T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass ||
1533  T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass ||
1534  T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass ||
1535  T->getStmtClass() == OMPDistributeDirectiveClass ||
1536  T->getStmtClass() == OMPTargetParallelForDirectiveClass ||
1537  T->getStmtClass() == OMPDistributeParallelForDirectiveClass ||
1538  T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass ||
1539  T->getStmtClass() == OMPDistributeSimdDirectiveClass ||
1540  T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass ||
1541  T->getStmtClass() == OMPTargetSimdDirectiveClass ||
1542  T->getStmtClass() == OMPTeamsDistributeDirectiveClass ||
1543  T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass ||
1544  T->getStmtClass() ==
1545  OMPTeamsDistributeParallelForSimdDirectiveClass ||
1546  T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass ||
1547  T->getStmtClass() ==
1548  OMPTargetTeamsDistributeParallelForDirectiveClass ||
1549  T->getStmtClass() ==
1550  OMPTargetTeamsDistributeParallelForSimdDirectiveClass ||
1551  T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass ||
1552  T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
1553  }
1554 };
1555 
1556 /// This represents '#pragma omp simd' directive.
1557 ///
1558 /// \code
1559 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
1560 /// \endcode
1561 /// In this example directive '#pragma omp simd' has clauses 'private'
1562 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
1563 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
1564 ///
1566  friend class ASTStmtReader;
1568  /// Build directive with the given start and end location.
1569  ///
1570  /// \param StartLoc Starting location of the directive kind.
1571  /// \param EndLoc Ending location of the directive.
1572  /// \param CollapsedNum Number of collapsed nested loops.
1573  ///
1575  unsigned CollapsedNum)
1576  : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, StartLoc,
1577  EndLoc, CollapsedNum) {}
1578 
1579  /// Build an empty directive.
1580  ///
1581  /// \param CollapsedNum Number of collapsed nested loops.
1582  ///
1583  explicit OMPSimdDirective(unsigned CollapsedNum)
1584  : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd,
1585  SourceLocation(), SourceLocation(), CollapsedNum) {}
1586 
1587 public:
1588  /// Creates directive with a list of \a Clauses.
1589  ///
1590  /// \param C AST context.
1591  /// \param StartLoc Starting location of the directive kind.
1592  /// \param EndLoc Ending Location of the directive.
1593  /// \param CollapsedNum Number of collapsed loops.
1594  /// \param Clauses List of clauses.
1595  /// \param AssociatedStmt Statement, associated with the directive.
1596  /// \param Exprs Helper expressions for CodeGen.
1597  ///
1598  static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1599  SourceLocation EndLoc, unsigned CollapsedNum,
1600  ArrayRef<OMPClause *> Clauses,
1601  Stmt *AssociatedStmt,
1602  const HelperExprs &Exprs);
1603 
1604  /// Creates an empty directive with the place
1605  /// for \a NumClauses clauses.
1606  ///
1607  /// \param C AST context.
1608  /// \param CollapsedNum Number of collapsed nested loops.
1609  /// \param NumClauses Number of clauses.
1610  ///
1611  static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1612  unsigned CollapsedNum, EmptyShell);
1613 
1614  static bool classof(const Stmt *T) {
1615  return T->getStmtClass() == OMPSimdDirectiveClass;
1616  }
1617 };
1618 
1619 /// This represents '#pragma omp for' directive.
1620 ///
1621 /// \code
1622 /// #pragma omp for private(a,b) reduction(+:c,d)
1623 /// \endcode
1624 /// In this example directive '#pragma omp for' has clauses 'private' with the
1625 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
1626 /// and 'd'.
1627 ///
1629  friend class ASTStmtReader;
1631  /// true if current directive has inner cancel directive.
1632  bool HasCancel = false;
1633 
1634  /// Build directive with the given start and end location.
1635  ///
1636  /// \param StartLoc Starting location of the directive kind.
1637  /// \param EndLoc Ending location of the directive.
1638  /// \param CollapsedNum Number of collapsed nested loops.
1639  ///
1641  unsigned CollapsedNum)
1642  : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, StartLoc,
1643  EndLoc, CollapsedNum) {}
1644 
1645  /// Build an empty directive.
1646  ///
1647  /// \param CollapsedNum Number of collapsed nested loops.
1648  ///
1649  explicit OMPForDirective(unsigned CollapsedNum)
1650  : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for,
1651  SourceLocation(), SourceLocation(), CollapsedNum) {}
1652 
1653  /// Sets special task reduction descriptor.
1654  void setTaskReductionRefExpr(Expr *E) {
1656  llvm::omp::OMPD_for)] = E;
1657  }
1658 
1659  /// Set cancel state.
1660  void setHasCancel(bool Has) { HasCancel = Has; }
1661 
1662 public:
1663  /// Creates directive with a list of \a Clauses.
1664  ///
1665  /// \param C AST context.
1666  /// \param StartLoc Starting location of the directive kind.
1667  /// \param EndLoc Ending Location of the directive.
1668  /// \param CollapsedNum Number of collapsed loops.
1669  /// \param Clauses List of clauses.
1670  /// \param AssociatedStmt Statement, associated with the directive.
1671  /// \param Exprs Helper expressions for CodeGen.
1672  /// \param TaskRedRef Task reduction special reference expression to handle
1673  /// taskgroup descriptor.
1674  /// \param HasCancel true if current directive has inner cancel directive.
1675  ///
1676  static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1677  SourceLocation EndLoc, unsigned CollapsedNum,
1678  ArrayRef<OMPClause *> Clauses,
1679  Stmt *AssociatedStmt, const HelperExprs &Exprs,
1680  Expr *TaskRedRef, bool HasCancel);
1681 
1682  /// Creates an empty directive with the place
1683  /// for \a NumClauses clauses.
1684  ///
1685  /// \param C AST context.
1686  /// \param CollapsedNum Number of collapsed nested loops.
1687  /// \param NumClauses Number of clauses.
1688  ///
1689  static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1690  unsigned CollapsedNum, EmptyShell);
1691 
1692  /// Returns special task reduction reference expression.
1694  return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
1695  getLoopsNumber(), llvm::omp::OMPD_for)]);
1696  }
1698  return const_cast<OMPForDirective *>(this)->getTaskReductionRefExpr();
1699  }
1700 
1701  /// Return true if current directive has inner cancel directive.
1702  bool hasCancel() const { return HasCancel; }
1703 
1704  static bool classof(const Stmt *T) {
1705  return T->getStmtClass() == OMPForDirectiveClass;
1706  }
1707 };
1708 
1709 /// This represents '#pragma omp for simd' directive.
1710 ///
1711 /// \code
1712 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
1713 /// \endcode
1714 /// In this example directive '#pragma omp for simd' has clauses 'private'
1715 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
1716 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
1717 ///
1719  friend class ASTStmtReader;
1721  /// Build directive with the given start and end location.
1722  ///
1723  /// \param StartLoc Starting location of the directive kind.
1724  /// \param EndLoc Ending location of the directive.
1725  /// \param CollapsedNum Number of collapsed nested loops.
1726  ///
1728  unsigned CollapsedNum)
1729  : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
1730  StartLoc, EndLoc, CollapsedNum) {}
1731 
1732  /// Build an empty directive.
1733  ///
1734  /// \param CollapsedNum Number of collapsed nested loops.
1735  ///
1736  explicit OMPForSimdDirective(unsigned CollapsedNum)
1737  : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd,
1738  SourceLocation(), SourceLocation(), CollapsedNum) {}
1739 
1740 public:
1741  /// Creates directive with a list of \a Clauses.
1742  ///
1743  /// \param C AST context.
1744  /// \param StartLoc Starting location of the directive kind.
1745  /// \param EndLoc Ending Location of the directive.
1746  /// \param CollapsedNum Number of collapsed loops.
1747  /// \param Clauses List of clauses.
1748  /// \param AssociatedStmt Statement, associated with the directive.
1749  /// \param Exprs Helper expressions for CodeGen.
1750  ///
1751  static OMPForSimdDirective *
1752  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1753  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1754  Stmt *AssociatedStmt, const HelperExprs &Exprs);
1755 
1756  /// Creates an empty directive with the place
1757  /// for \a NumClauses clauses.
1758  ///
1759  /// \param C AST context.
1760  /// \param CollapsedNum Number of collapsed nested loops.
1761  /// \param NumClauses Number of clauses.
1762  ///
1763  static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
1764  unsigned NumClauses,
1765  unsigned CollapsedNum, EmptyShell);
1766 
1767  static bool classof(const Stmt *T) {
1768  return T->getStmtClass() == OMPForSimdDirectiveClass;
1769  }
1770 };
1771 
1772 /// This represents '#pragma omp sections' directive.
1773 ///
1774 /// \code
1775 /// #pragma omp sections private(a,b) reduction(+:c,d)
1776 /// \endcode
1777 /// In this example directive '#pragma omp sections' has clauses 'private' with
1778 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
1779 /// 'c' and 'd'.
1780 ///
1782  friend class ASTStmtReader;
1784 
1785  /// true if current directive has inner cancel directive.
1786  bool HasCancel = false;
1787 
1788  /// Build directive with the given start and end location.
1789  ///
1790  /// \param StartLoc Starting location of the directive kind.
1791  /// \param EndLoc Ending location of the directive.
1792  ///
1794  : OMPExecutableDirective(OMPSectionsDirectiveClass,
1795  llvm::omp::OMPD_sections, StartLoc, EndLoc) {}
1796 
1797  /// Build an empty directive.
1798  ///
1799  explicit OMPSectionsDirective()
1800  : OMPExecutableDirective(OMPSectionsDirectiveClass,
1801  llvm::omp::OMPD_sections, SourceLocation(),
1802  SourceLocation()) {}
1803 
1804  /// Sets special task reduction descriptor.
1805  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
1806 
1807  /// Set cancel state.
1808  void setHasCancel(bool Has) { HasCancel = Has; }
1809 
1810 public:
1811  /// Creates directive with a list of \a Clauses.
1812  ///
1813  /// \param C AST context.
1814  /// \param StartLoc Starting location of the directive kind.
1815  /// \param EndLoc Ending Location of the directive.
1816  /// \param Clauses List of clauses.
1817  /// \param AssociatedStmt Statement, associated with the directive.
1818  /// \param TaskRedRef Task reduction special reference expression to handle
1819  /// taskgroup descriptor.
1820  /// \param HasCancel true if current directive has inner directive.
1821  ///
1822  static OMPSectionsDirective *
1823  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1824  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
1825  bool HasCancel);
1826 
1827  /// Creates an empty directive with the place for \a NumClauses
1828  /// clauses.
1829  ///
1830  /// \param C AST context.
1831  /// \param NumClauses Number of clauses.
1832  ///
1833  static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
1834  unsigned NumClauses, EmptyShell);
1835 
1836  /// Returns special task reduction reference expression.
1838  return cast_or_null<Expr>(Data->getChildren()[0]);
1839  }
1841  return const_cast<OMPSectionsDirective *>(this)->getTaskReductionRefExpr();
1842  }
1843 
1844  /// Return true if current directive has inner cancel directive.
1845  bool hasCancel() const { return HasCancel; }
1846 
1847  static bool classof(const Stmt *T) {
1848  return T->getStmtClass() == OMPSectionsDirectiveClass;
1849  }
1850 };
1851 
1852 /// This represents '#pragma omp section' directive.
1853 ///
1854 /// \code
1855 /// #pragma omp section
1856 /// \endcode
1857 ///
1859  friend class ASTStmtReader;
1861 
1862  /// true if current directive has inner cancel directive.
1863  bool HasCancel = false;
1864 
1865  /// Build directive with the given start and end location.
1866  ///
1867  /// \param StartLoc Starting location of the directive kind.
1868  /// \param EndLoc Ending location of the directive.
1869  ///
1871  : OMPExecutableDirective(OMPSectionDirectiveClass,
1872  llvm::omp::OMPD_section, StartLoc, EndLoc) {}
1873 
1874  /// Build an empty directive.
1875  ///
1876  explicit OMPSectionDirective()
1877  : OMPExecutableDirective(OMPSectionDirectiveClass,
1878  llvm::omp::OMPD_section, SourceLocation(),
1879  SourceLocation()) {}
1880 
1881 public:
1882  /// Creates directive.
1883  ///
1884  /// \param C AST context.
1885  /// \param StartLoc Starting location of the directive kind.
1886  /// \param EndLoc Ending Location of the directive.
1887  /// \param AssociatedStmt Statement, associated with the directive.
1888  /// \param HasCancel true if current directive has inner directive.
1889  ///
1890  static OMPSectionDirective *Create(const ASTContext &C,
1891  SourceLocation StartLoc,
1892  SourceLocation EndLoc,
1893  Stmt *AssociatedStmt, bool HasCancel);
1894 
1895  /// Creates an empty directive.
1896  ///
1897  /// \param C AST context.
1898  ///
1899  static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1900 
1901  /// Set cancel state.
1902  void setHasCancel(bool Has) { HasCancel = Has; }
1903 
1904  /// Return true if current directive has inner cancel directive.
1905  bool hasCancel() const { return HasCancel; }
1906 
1907  static bool classof(const Stmt *T) {
1908  return T->getStmtClass() == OMPSectionDirectiveClass;
1909  }
1910 };
1911 
1912 /// This represents '#pragma omp single' directive.
1913 ///
1914 /// \code
1915 /// #pragma omp single private(a,b) copyprivate(c,d)
1916 /// \endcode
1917 /// In this example directive '#pragma omp single' has clauses 'private' with
1918 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
1919 ///
1921  friend class ASTStmtReader;
1923  /// Build directive with the given start and end location.
1924  ///
1925  /// \param StartLoc Starting location of the directive kind.
1926  /// \param EndLoc Ending location of the directive.
1927  ///
1929  : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
1930  StartLoc, EndLoc) {}
1931 
1932  /// Build an empty directive.
1933  ///
1934  explicit OMPSingleDirective()
1935  : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single,
1937 
1938 public:
1939  /// Creates directive with a list of \a Clauses.
1940  ///
1941  /// \param C AST context.
1942  /// \param StartLoc Starting location of the directive kind.
1943  /// \param EndLoc Ending Location of the directive.
1944  /// \param Clauses List of clauses.
1945  /// \param AssociatedStmt Statement, associated with the directive.
1946  ///
1947  static OMPSingleDirective *
1948  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1949  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1950 
1951  /// Creates an empty directive with the place for \a NumClauses
1952  /// clauses.
1953  ///
1954  /// \param C AST context.
1955  /// \param NumClauses Number of clauses.
1956  ///
1957  static OMPSingleDirective *CreateEmpty(const ASTContext &C,
1958  unsigned NumClauses, EmptyShell);
1959 
1960  static bool classof(const Stmt *T) {
1961  return T->getStmtClass() == OMPSingleDirectiveClass;
1962  }
1963 };
1964 
1965 /// This represents '#pragma omp master' directive.
1966 ///
1967 /// \code
1968 /// #pragma omp master
1969 /// \endcode
1970 ///
1972  friend class ASTStmtReader;
1974  /// Build directive with the given start and end location.
1975  ///
1976  /// \param StartLoc Starting location of the directive kind.
1977  /// \param EndLoc Ending location of the directive.
1978  ///
1980  : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
1981  StartLoc, EndLoc) {}
1982 
1983  /// Build an empty directive.
1984  ///
1985  explicit OMPMasterDirective()
1986  : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master,
1988 
1989 public:
1990  /// Creates directive.
1991  ///
1992  /// \param C AST context.
1993  /// \param StartLoc Starting location of the directive kind.
1994  /// \param EndLoc Ending Location of the directive.
1995  /// \param AssociatedStmt Statement, associated with the directive.
1996  ///
1997  static OMPMasterDirective *Create(const ASTContext &C,
1998  SourceLocation StartLoc,
1999  SourceLocation EndLoc,
2000  Stmt *AssociatedStmt);
2001 
2002  /// Creates an empty directive.
2003  ///
2004  /// \param C AST context.
2005  ///
2006  static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2007 
2008  static bool classof(const Stmt *T) {
2009  return T->getStmtClass() == OMPMasterDirectiveClass;
2010  }
2011 };
2012 
2013 /// This represents '#pragma omp critical' directive.
2014 ///
2015 /// \code
2016 /// #pragma omp critical
2017 /// \endcode
2018 ///
2020  friend class ASTStmtReader;
2022  /// Name of the directive.
2023  DeclarationNameInfo DirName;
2024  /// Build directive with the given start and end location.
2025  ///
2026  /// \param Name Name of the directive.
2027  /// \param StartLoc Starting location of the directive kind.
2028  /// \param EndLoc Ending location of the directive.
2029  ///
2031  SourceLocation EndLoc)
2032  : OMPExecutableDirective(OMPCriticalDirectiveClass,
2033  llvm::omp::OMPD_critical, StartLoc, EndLoc),
2034  DirName(Name) {}
2035 
2036  /// Build an empty directive.
2037  ///
2038  explicit OMPCriticalDirective()
2039  : OMPExecutableDirective(OMPCriticalDirectiveClass,
2040  llvm::omp::OMPD_critical, SourceLocation(),
2041  SourceLocation()) {}
2042 
2043  /// Set name of the directive.
2044  ///
2045  /// \param Name Name of the directive.
2046  ///
2047  void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
2048 
2049 public:
2050  /// Creates directive.
2051  ///
2052  /// \param C AST context.
2053  /// \param Name Name of the directive.
2054  /// \param StartLoc Starting location of the directive kind.
2055  /// \param EndLoc Ending Location of the directive.
2056  /// \param Clauses List of clauses.
2057  /// \param AssociatedStmt Statement, associated with the directive.
2058  ///
2059  static OMPCriticalDirective *
2060  Create(const ASTContext &C, const DeclarationNameInfo &Name,
2061  SourceLocation StartLoc, SourceLocation EndLoc,
2062  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2063 
2064  /// Creates an empty directive.
2065  ///
2066  /// \param C AST context.
2067  /// \param NumClauses Number of clauses.
2068  ///
2069  static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
2070  unsigned NumClauses, EmptyShell);
2071 
2072  /// Return name of the directive.
2073  ///
2074  DeclarationNameInfo getDirectiveName() const { return DirName; }
2075 
2076  static bool classof(const Stmt *T) {
2077  return T->getStmtClass() == OMPCriticalDirectiveClass;
2078  }
2079 };
2080 
2081 /// This represents '#pragma omp parallel for' directive.
2082 ///
2083 /// \code
2084 /// #pragma omp parallel for private(a,b) reduction(+:c,d)
2085 /// \endcode
2086 /// In this example directive '#pragma omp parallel for' has clauses 'private'
2087 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
2088 /// variables 'c' and 'd'.
2089 ///
2091  friend class ASTStmtReader;
2093 
2094  /// true if current region has inner cancel directive.
2095  bool HasCancel = false;
2096 
2097  /// Build directive with the given start and end location.
2098  ///
2099  /// \param StartLoc Starting location of the directive kind.
2100  /// \param EndLoc Ending location of the directive.
2101  /// \param CollapsedNum Number of collapsed nested loops.
2102  ///
2104  unsigned CollapsedNum)
2105  : OMPLoopDirective(OMPParallelForDirectiveClass,
2106  llvm::omp::OMPD_parallel_for, StartLoc, EndLoc,
2107  CollapsedNum) {}
2108 
2109  /// Build an empty directive.
2110  ///
2111  /// \param CollapsedNum Number of collapsed nested loops.
2112  ///
2113  explicit OMPParallelForDirective(unsigned CollapsedNum)
2114  : OMPLoopDirective(OMPParallelForDirectiveClass,
2115  llvm::omp::OMPD_parallel_for, SourceLocation(),
2116  SourceLocation(), CollapsedNum) {}
2117 
2118  /// Sets special task reduction descriptor.
2119  void setTaskReductionRefExpr(Expr *E) {
2121  llvm::omp::OMPD_parallel_for)] = E;
2122  }
2123 
2124  /// Set cancel state.
2125  void setHasCancel(bool Has) { HasCancel = Has; }
2126 
2127 public:
2128  /// Creates directive with a list of \a Clauses.
2129  ///
2130  /// \param C AST context.
2131  /// \param StartLoc Starting location of the directive kind.
2132  /// \param EndLoc Ending Location of the directive.
2133  /// \param CollapsedNum Number of collapsed loops.
2134  /// \param Clauses List of clauses.
2135  /// \param AssociatedStmt Statement, associated with the directive.
2136  /// \param Exprs Helper expressions for CodeGen.
2137  /// \param TaskRedRef Task reduction special reference expression to handle
2138  /// taskgroup descriptor.
2139  /// \param HasCancel true if current directive has inner cancel directive.
2140  ///
2141  static OMPParallelForDirective *
2142  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2143  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2144  Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
2145  bool HasCancel);
2146 
2147  /// Creates an empty directive with the place
2148  /// for \a NumClauses clauses.
2149  ///
2150  /// \param C AST context.
2151  /// \param CollapsedNum Number of collapsed nested loops.
2152  /// \param NumClauses Number of clauses.
2153  ///
2154  static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
2155  unsigned NumClauses,
2156  unsigned CollapsedNum,
2157  EmptyShell);
2158 
2159  /// Returns special task reduction reference expression.
2161  return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
2162  getLoopsNumber(), llvm::omp::OMPD_parallel_for)]);
2163  }
2165  return const_cast<OMPParallelForDirective *>(this)
2167  }
2168 
2169  /// Return true if current directive has inner cancel directive.
2170  bool hasCancel() const { return HasCancel; }
2171 
2172  static bool classof(const Stmt *T) {
2173  return T->getStmtClass() == OMPParallelForDirectiveClass;
2174  }
2175 };
2176 
2177 /// This represents '#pragma omp parallel for simd' directive.
2178 ///
2179 /// \code
2180 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
2181 /// \endcode
2182 /// In this example directive '#pragma omp parallel for simd' has clauses
2183 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
2184 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and
2185 /// 'd'.
2186 ///
2188  friend class ASTStmtReader;
2190  /// Build directive with the given start and end location.
2191  ///
2192  /// \param StartLoc Starting location of the directive kind.
2193  /// \param EndLoc Ending location of the directive.
2194  /// \param CollapsedNum Number of collapsed nested loops.
2195  ///
2197  unsigned CollapsedNum)
2198  : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
2199  llvm::omp::OMPD_parallel_for_simd, StartLoc, EndLoc,
2200  CollapsedNum) {}
2201 
2202  /// Build an empty directive.
2203  ///
2204  /// \param CollapsedNum Number of collapsed nested loops.
2205  ///
2206  explicit OMPParallelForSimdDirective(unsigned CollapsedNum)
2207  : OMPLoopDirective(OMPParallelForSimdDirectiveClass,
2208  llvm::omp::OMPD_parallel_for_simd, SourceLocation(),
2209  SourceLocation(), CollapsedNum) {}
2210 
2211 public:
2212  /// Creates directive with a list of \a Clauses.
2213  ///
2214  /// \param C AST context.
2215  /// \param StartLoc Starting location of the directive kind.
2216  /// \param EndLoc Ending Location of the directive.
2217  /// \param CollapsedNum Number of collapsed loops.
2218  /// \param Clauses List of clauses.
2219  /// \param AssociatedStmt Statement, associated with the directive.
2220  /// \param Exprs Helper expressions for CodeGen.
2221  ///
2222  static OMPParallelForSimdDirective *
2223  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2224  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2225  Stmt *AssociatedStmt, const HelperExprs &Exprs);
2226 
2227  /// Creates an empty directive with the place
2228  /// for \a NumClauses clauses.
2229  ///
2230  /// \param C AST context.
2231  /// \param CollapsedNum Number of collapsed nested loops.
2232  /// \param NumClauses Number of clauses.
2233  ///
2234  static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
2235  unsigned NumClauses,
2236  unsigned CollapsedNum,
2237  EmptyShell);
2238 
2239  static bool classof(const Stmt *T) {
2240  return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
2241  }
2242 };
2243 
2244 /// This represents '#pragma omp parallel master' directive.
2245 ///
2246 /// \code
2247 /// #pragma omp parallel master private(a,b)
2248 /// \endcode
2249 /// In this example directive '#pragma omp parallel master' has clauses
2250 /// 'private' with the variables 'a' and 'b'
2251 ///
2253  friend class ASTStmtReader;
2255 
2257  : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
2258  llvm::omp::OMPD_parallel_master, StartLoc,
2259  EndLoc) {}
2260 
2261  explicit OMPParallelMasterDirective()
2262  : OMPExecutableDirective(OMPParallelMasterDirectiveClass,
2263  llvm::omp::OMPD_parallel_master,
2265 
2266  /// Sets special task reduction descriptor.
2267  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2268 
2269 public:
2270  /// Creates directive with a list of \a Clauses.
2271  ///
2272  /// \param C AST context.
2273  /// \param StartLoc Starting location of the directive kind.
2274  /// \param EndLoc Ending Location of the directive.
2275  /// \param Clauses List of clauses.
2276  /// \param AssociatedStmt Statement, associated with the directive.
2277  /// \param TaskRedRef Task reduction special reference expression to handle
2278  /// taskgroup descriptor.
2279  ///
2280  static OMPParallelMasterDirective *
2281  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2282  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef);
2283 
2284  /// Creates an empty directive with the place for \a NumClauses
2285  /// clauses.
2286  ///
2287  /// \param C AST context.
2288  /// \param NumClauses Number of clauses.
2289  ///
2290  static OMPParallelMasterDirective *
2291  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2292 
2293  /// Returns special task reduction reference expression.
2295  return cast_or_null<Expr>(Data->getChildren()[0]);
2296  }
2298  return const_cast<OMPParallelMasterDirective *>(this)
2300  }
2301 
2302  static bool classof(const Stmt *T) {
2303  return T->getStmtClass() == OMPParallelMasterDirectiveClass;
2304  }
2305 };
2306 
2307 /// This represents '#pragma omp parallel sections' directive.
2308 ///
2309 /// \code
2310 /// #pragma omp parallel sections private(a,b) reduction(+:c,d)
2311 /// \endcode
2312 /// In this example directive '#pragma omp parallel sections' has clauses
2313 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
2314 /// and variables 'c' and 'd'.
2315 ///
2317  friend class ASTStmtReader;
2319 
2320  /// true if current directive has inner cancel directive.
2321  bool HasCancel = false;
2322 
2323  /// Build directive with the given start and end location.
2324  ///
2325  /// \param StartLoc Starting location of the directive kind.
2326  /// \param EndLoc Ending location of the directive.
2327  ///
2329  : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
2330  llvm::omp::OMPD_parallel_sections, StartLoc,
2331  EndLoc) {}
2332 
2333  /// Build an empty directive.
2334  ///
2335  explicit OMPParallelSectionsDirective()
2336  : OMPExecutableDirective(OMPParallelSectionsDirectiveClass,
2337  llvm::omp::OMPD_parallel_sections,
2339 
2340  /// Sets special task reduction descriptor.
2341  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
2342 
2343  /// Set cancel state.
2344  void setHasCancel(bool Has) { HasCancel = Has; }
2345 
2346 public:
2347  /// Creates directive with a list of \a Clauses.
2348  ///
2349  /// \param C AST context.
2350  /// \param StartLoc Starting location of the directive kind.
2351  /// \param EndLoc Ending Location of the directive.
2352  /// \param Clauses List of clauses.
2353  /// \param AssociatedStmt Statement, associated with the directive.
2354  /// \param TaskRedRef Task reduction special reference expression to handle
2355  /// taskgroup descriptor.
2356  /// \param HasCancel true if current directive has inner cancel directive.
2357  ///
2358  static OMPParallelSectionsDirective *
2359  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2360  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
2361  bool HasCancel);
2362 
2363  /// Creates an empty directive with the place for \a NumClauses
2364  /// clauses.
2365  ///
2366  /// \param C AST context.
2367  /// \param NumClauses Number of clauses.
2368  ///
2369  static OMPParallelSectionsDirective *
2370  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2371 
2372  /// Returns special task reduction reference expression.
2374  return cast_or_null<Expr>(Data->getChildren()[0]);
2375  }
2377  return const_cast<OMPParallelSectionsDirective *>(this)
2379  }
2380 
2381  /// Return true if current directive has inner cancel directive.
2382  bool hasCancel() const { return HasCancel; }
2383 
2384  static bool classof(const Stmt *T) {
2385  return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
2386  }
2387 };
2388 
2389 /// This represents '#pragma omp task' directive.
2390 ///
2391 /// \code
2392 /// #pragma omp task private(a,b) final(d)
2393 /// \endcode
2394 /// In this example directive '#pragma omp task' has clauses 'private' with the
2395 /// variables 'a' and 'b' and 'final' with condition 'd'.
2396 ///
2398  friend class ASTStmtReader;
2400  /// true if this directive has inner cancel directive.
2401  bool HasCancel = false;
2402 
2403  /// Build directive with the given start and end location.
2404  ///
2405  /// \param StartLoc Starting location of the directive kind.
2406  /// \param EndLoc Ending location of the directive.
2407  ///
2409  : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
2410  StartLoc, EndLoc) {}
2411 
2412  /// Build an empty directive.
2413  ///
2414  explicit OMPTaskDirective()
2415  : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task,
2417 
2418  /// Set cancel state.
2419  void setHasCancel(bool Has) { HasCancel = Has; }
2420 
2421 public:
2422  /// Creates directive with a list of \a Clauses.
2423  ///
2424  /// \param C AST context.
2425  /// \param StartLoc Starting location of the directive kind.
2426  /// \param EndLoc Ending Location of the directive.
2427  /// \param Clauses List of clauses.
2428  /// \param AssociatedStmt Statement, associated with the directive.
2429  /// \param HasCancel true, if current directive has inner cancel directive.
2430  ///
2431  static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2432  SourceLocation EndLoc,
2433  ArrayRef<OMPClause *> Clauses,
2434  Stmt *AssociatedStmt, bool HasCancel);
2435 
2436  /// Creates an empty directive with the place for \a NumClauses
2437  /// clauses.
2438  ///
2439  /// \param C AST context.
2440  /// \param NumClauses Number of clauses.
2441  ///
2442  static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
2443  EmptyShell);
2444 
2445  /// Return true if current directive has inner cancel directive.
2446  bool hasCancel() const { return HasCancel; }
2447 
2448  static bool classof(const Stmt *T) {
2449  return T->getStmtClass() == OMPTaskDirectiveClass;
2450  }
2451 };
2452 
2453 /// This represents '#pragma omp taskyield' directive.
2454 ///
2455 /// \code
2456 /// #pragma omp taskyield
2457 /// \endcode
2458 ///
2460  friend class ASTStmtReader;
2462  /// Build directive with the given start and end location.
2463  ///
2464  /// \param StartLoc Starting location of the directive kind.
2465  /// \param EndLoc Ending location of the directive.
2466  ///
2468  : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
2469  llvm::omp::OMPD_taskyield, StartLoc, EndLoc) {}
2470 
2471  /// Build an empty directive.
2472  ///
2473  explicit OMPTaskyieldDirective()
2474  : OMPExecutableDirective(OMPTaskyieldDirectiveClass,
2475  llvm::omp::OMPD_taskyield, SourceLocation(),
2476  SourceLocation()) {}
2477 
2478 public:
2479  /// Creates directive.
2480  ///
2481  /// \param C AST context.
2482  /// \param StartLoc Starting location of the directive kind.
2483  /// \param EndLoc Ending Location of the directive.
2484  ///
2485  static OMPTaskyieldDirective *
2486  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
2487 
2488  /// Creates an empty directive.
2489  ///
2490  /// \param C AST context.
2491  ///
2492  static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2493 
2494  static bool classof(const Stmt *T) {
2495  return T->getStmtClass() == OMPTaskyieldDirectiveClass;
2496  }
2497 };
2498 
2499 /// This represents '#pragma omp barrier' directive.
2500 ///
2501 /// \code
2502 /// #pragma omp barrier
2503 /// \endcode
2504 ///
2506  friend class ASTStmtReader;
2508  /// Build directive with the given start and end location.
2509  ///
2510  /// \param StartLoc Starting location of the directive kind.
2511  /// \param EndLoc Ending location of the directive.
2512  ///
2514  : OMPExecutableDirective(OMPBarrierDirectiveClass,
2515  llvm::omp::OMPD_barrier, StartLoc, EndLoc) {}
2516 
2517  /// Build an empty directive.
2518  ///
2519  explicit OMPBarrierDirective()
2520  : OMPExecutableDirective(OMPBarrierDirectiveClass,
2521  llvm::omp::OMPD_barrier, SourceLocation(),
2522  SourceLocation()) {}
2523 
2524 public:
2525  /// Creates directive.
2526  ///
2527  /// \param C AST context.
2528  /// \param StartLoc Starting location of the directive kind.
2529  /// \param EndLoc Ending Location of the directive.
2530  ///
2531  static OMPBarrierDirective *
2532  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
2533 
2534  /// Creates an empty directive.
2535  ///
2536  /// \param C AST context.
2537  ///
2538  static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
2539 
2540  static bool classof(const Stmt *T) {
2541  return T->getStmtClass() == OMPBarrierDirectiveClass;
2542  }
2543 };
2544 
2545 /// This represents '#pragma omp taskwait' directive.
2546 ///
2547 /// \code
2548 /// #pragma omp taskwait
2549 /// \endcode
2550 ///
2552  friend class ASTStmtReader;
2554  /// Build directive with the given start and end location.
2555  ///
2556  /// \param StartLoc Starting location of the directive kind.
2557  /// \param EndLoc Ending location of the directive.
2558  ///
2560  : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
2561  llvm::omp::OMPD_taskwait, StartLoc, EndLoc) {}
2562 
2563  /// Build an empty directive.
2564  ///
2565  explicit OMPTaskwaitDirective()
2566  : OMPExecutableDirective(OMPTaskwaitDirectiveClass,
2567  llvm::omp::OMPD_taskwait, SourceLocation(),
2568  SourceLocation()) {}
2569 
2570 public:
2571  /// Creates directive.
2572  ///
2573  /// \param C AST context.
2574  /// \param StartLoc Starting location of the directive kind.
2575  /// \param EndLoc Ending Location of the directive.
2576  /// \param Clauses List of clauses.
2577  ///
2578  static OMPTaskwaitDirective *Create(const ASTContext &C,
2579  SourceLocation StartLoc,
2580  SourceLocation EndLoc,
2581  ArrayRef<OMPClause *> Clauses);
2582 
2583  /// Creates an empty directive.
2584  ///
2585  /// \param C AST context.
2586  /// \param NumClauses Number of clauses.
2587  ///
2588  static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C,
2589  unsigned NumClauses, EmptyShell);
2590 
2591  static bool classof(const Stmt *T) {
2592  return T->getStmtClass() == OMPTaskwaitDirectiveClass;
2593  }
2594 };
2595 
2596 /// This represents '#pragma omp taskgroup' directive.
2597 ///
2598 /// \code
2599 /// #pragma omp taskgroup
2600 /// \endcode
2601 ///
2603  friend class ASTStmtReader;
2605  /// Build directive with the given start and end location.
2606  ///
2607  /// \param StartLoc Starting location of the directive kind.
2608  /// \param EndLoc Ending location of the directive.
2609  ///
2611  : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
2612  llvm::omp::OMPD_taskgroup, StartLoc, EndLoc) {}
2613 
2614  /// Build an empty directive.
2615  ///
2616  explicit OMPTaskgroupDirective()
2617  : OMPExecutableDirective(OMPTaskgroupDirectiveClass,
2618  llvm::omp::OMPD_taskgroup, SourceLocation(),
2619  SourceLocation()) {}
2620 
2621  /// Sets the task_reduction return variable.
2622  void setReductionRef(Expr *RR) { Data->getChildren()[0] = RR; }
2623 
2624 public:
2625  /// Creates directive.
2626  ///
2627  /// \param C AST context.
2628  /// \param StartLoc Starting location of the directive kind.
2629  /// \param EndLoc Ending Location of the directive.
2630  /// \param Clauses List of clauses.
2631  /// \param AssociatedStmt Statement, associated with the directive.
2632  /// \param ReductionRef Reference to the task_reduction return variable.
2633  ///
2634  static OMPTaskgroupDirective *
2635  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2636  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
2637  Expr *ReductionRef);
2638 
2639  /// Creates an empty directive.
2640  ///
2641  /// \param C AST context.
2642  /// \param NumClauses Number of clauses.
2643  ///
2644  static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C,
2645  unsigned NumClauses, EmptyShell);
2646 
2647 
2648  /// Returns reference to the task_reduction return variable.
2649  const Expr *getReductionRef() const {
2650  return const_cast<OMPTaskgroupDirective *>(this)->getReductionRef();
2651  }
2652  Expr *getReductionRef() { return cast_or_null<Expr>(Data->getChildren()[0]); }
2653 
2654  static bool classof(const Stmt *T) {
2655  return T->getStmtClass() == OMPTaskgroupDirectiveClass;
2656  }
2657 };
2658 
2659 /// This represents '#pragma omp flush' directive.
2660 ///
2661 /// \code
2662 /// #pragma omp flush(a,b)
2663 /// \endcode
2664 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
2665 /// and 'b'.
2666 /// 'omp flush' directive does not have clauses but have an optional list of
2667 /// variables to flush. This list of variables is stored within some fake clause
2668 /// FlushClause.
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(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
2679  StartLoc, EndLoc) {}
2680 
2681  /// Build an empty directive.
2682  ///
2683  explicit OMPFlushDirective()
2684  : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush,
2686 
2687 public:
2688  /// Creates directive with a list of \a Clauses.
2689  ///
2690  /// \param C AST context.
2691  /// \param StartLoc Starting location of the directive kind.
2692  /// \param EndLoc Ending Location of the directive.
2693  /// \param Clauses List of clauses (only single OMPFlushClause clause is
2694  /// allowed).
2695  ///
2696  static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2697  SourceLocation EndLoc,
2698  ArrayRef<OMPClause *> Clauses);
2699 
2700  /// Creates an empty directive with the place for \a NumClauses
2701  /// clauses.
2702  ///
2703  /// \param C AST context.
2704  /// \param NumClauses Number of clauses.
2705  ///
2706  static OMPFlushDirective *CreateEmpty(const ASTContext &C,
2707  unsigned NumClauses, EmptyShell);
2708 
2709  static bool classof(const Stmt *T) {
2710  return T->getStmtClass() == OMPFlushDirectiveClass;
2711  }
2712 };
2713 
2714 /// This represents '#pragma omp depobj' directive.
2715 ///
2716 /// \code
2717 /// #pragma omp depobj(a) depend(in:x,y)
2718 /// \endcode
2719 /// In this example directive '#pragma omp depobj' initializes a depobj object
2720 /// 'a' with dependence type 'in' and a list with 'x' and 'y' locators.
2722  friend class ASTStmtReader;
2724 
2725  /// Build directive with the given start and end location.
2726  ///
2727  /// \param StartLoc Starting location of the directive kind.
2728  /// \param EndLoc Ending location of the directive.
2729  ///
2731  : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
2732  StartLoc, EndLoc) {}
2733 
2734  /// Build an empty directive.
2735  ///
2736  explicit OMPDepobjDirective()
2737  : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj,
2739 
2740 public:
2741  /// Creates directive with a list of \a Clauses.
2742  ///
2743  /// \param C AST context.
2744  /// \param StartLoc Starting location of the directive kind.
2745  /// \param EndLoc Ending Location of the directive.
2746  /// \param Clauses List of clauses.
2747  ///
2748  static OMPDepobjDirective *Create(const ASTContext &C,
2749  SourceLocation StartLoc,
2750  SourceLocation EndLoc,
2751  ArrayRef<OMPClause *> Clauses);
2752 
2753  /// Creates an empty directive with the place for \a NumClauses
2754  /// clauses.
2755  ///
2756  /// \param C AST context.
2757  /// \param NumClauses Number of clauses.
2758  ///
2759  static OMPDepobjDirective *CreateEmpty(const ASTContext &C,
2760  unsigned NumClauses, EmptyShell);
2761 
2762  static bool classof(const Stmt *T) {
2763  return T->getStmtClass() == OMPDepobjDirectiveClass;
2764  }
2765 };
2766 
2767 /// This represents '#pragma omp ordered' directive.
2768 ///
2769 /// \code
2770 /// #pragma omp ordered
2771 /// \endcode
2772 ///
2774  friend class ASTStmtReader;
2776  /// Build directive with the given start and end location.
2777  ///
2778  /// \param StartLoc Starting location of the directive kind.
2779  /// \param EndLoc Ending location of the directive.
2780  ///
2782  : OMPExecutableDirective(OMPOrderedDirectiveClass,
2783  llvm::omp::OMPD_ordered, StartLoc, EndLoc) {}
2784 
2785  /// Build an empty directive.
2786  ///
2787  explicit OMPOrderedDirective()
2788  : OMPExecutableDirective(OMPOrderedDirectiveClass,
2789  llvm::omp::OMPD_ordered, SourceLocation(),
2790  SourceLocation()) {}
2791 
2792 public:
2793  /// Creates directive.
2794  ///
2795  /// \param C AST context.
2796  /// \param StartLoc Starting location of the directive kind.
2797  /// \param EndLoc Ending Location of the directive.
2798  /// \param Clauses List of clauses.
2799  /// \param AssociatedStmt Statement, associated with the directive.
2800  ///
2801  static OMPOrderedDirective *
2802  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2803  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2804 
2805  /// Creates an empty directive.
2806  ///
2807  /// \param C AST context.
2808  /// \param NumClauses Number of clauses.
2809  /// \param IsStandalone true, if the the standalone directive is created.
2810  ///
2811  static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
2812  unsigned NumClauses,
2813  bool IsStandalone, EmptyShell);
2814 
2815  static bool classof(const Stmt *T) {
2816  return T->getStmtClass() == OMPOrderedDirectiveClass;
2817  }
2818 };
2819 
2820 /// This represents '#pragma omp atomic' directive.
2821 ///
2822 /// \code
2823 /// #pragma omp atomic capture
2824 /// \endcode
2825 /// In this example directive '#pragma omp atomic' has clause 'capture'.
2826 ///
2828  friend class ASTStmtReader;
2830 
2831  struct FlagTy {
2832  /// Used for 'atomic update' or 'atomic capture' constructs. They may
2833  /// have atomic expressions of forms:
2834  /// \code
2835  /// x = x binop expr;
2836  /// x = expr binop x;
2837  /// \endcode
2838  /// This field is 1 for the first form of the expression and 0 for the
2839  /// second. Required for correct codegen of non-associative operations (like
2840  /// << or >>).
2841  uint8_t IsXLHSInRHSPart : 1;
2842  /// Used for 'atomic update' or 'atomic capture' constructs. They may
2843  /// have atomic expressions of forms:
2844  /// \code
2845  /// v = x; <update x>;
2846  /// <update x>; v = x;
2847  /// \endcode
2848  /// This field is 1 for the first(postfix) form of the expression and 0
2849  /// otherwise.
2850  uint8_t IsPostfixUpdate : 1;
2851  } Flags;
2852 
2853  /// Build directive with the given start and end location.
2854  ///
2855  /// \param StartLoc Starting location of the directive kind.
2856  /// \param EndLoc Ending location of the directive.
2857  ///
2859  : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
2860  StartLoc, EndLoc) {}
2861 
2862  /// Build an empty directive.
2863  ///
2864  explicit OMPAtomicDirective()
2865  : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic,
2866  SourceLocation(), SourceLocation()) {}
2867 
2868  enum DataPositionTy : size_t {
2869  POS_X = 0,
2870  POS_V,
2871  POS_E,
2872  POS_UpdateExpr,
2873  POS_D,
2874  POS_Cond,
2875  };
2876 
2877  /// Set 'x' part of the associated expression/statement.
2878  void setX(Expr *X) { Data->getChildren()[DataPositionTy::POS_X] = X; }
2879  /// Set helper expression of the form
2880  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
2881  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2882  void setUpdateExpr(Expr *UE) {
2883  Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE;
2884  }
2885  /// Set 'v' part of the associated expression/statement.
2886  void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; }
2887  /// Set 'expr' part of the associated expression/statement.
2888  void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; }
2889  /// Set 'd' part of the associated expression/statement.
2890  void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; }
2891  /// Set conditional expression in `atomic compare`.
2892  void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; }
2893 
2894 public:
2895  struct Expressions {
2896  /// 'x' part of the associated expression/statement.
2897  Expr *X = nullptr;
2898  /// 'v' part of the associated expression/statement.
2899  Expr *V = nullptr;
2900  /// 'expr' part of the associated expression/statement.
2901  Expr *E = nullptr;
2902  /// UE Helper expression of the form:
2903  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
2904  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2905  Expr *UE = nullptr;
2906  /// 'd' part of the associated expression/statement.
2907  Expr *D = nullptr;
2908  /// Conditional expression in `atomic compare` construct.
2909  Expr *Cond = nullptr;
2910  /// True if UE has the first form and false if the second.
2912  /// True if original value of 'x' must be stored in 'v', not an updated one.
2914  };
2915 
2916  /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
2917  /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
2918  /// detailed description of 'x', 'v' and 'expr').
2919  ///
2920  /// \param C AST context.
2921  /// \param StartLoc Starting location of the directive kind.
2922  /// \param EndLoc Ending Location of the directive.
2923  /// \param Clauses List of clauses.
2924  /// \param AssociatedStmt Statement, associated with the directive.
2925  /// \param Exprs Associated expressions or statements.
2926  static OMPAtomicDirective *Create(const ASTContext &C,
2927  SourceLocation StartLoc,
2928  SourceLocation EndLoc,
2929  ArrayRef<OMPClause *> Clauses,
2930  Stmt *AssociatedStmt, Expressions Exprs);
2931 
2932  /// Creates an empty directive with the place for \a NumClauses
2933  /// clauses.
2934  ///
2935  /// \param C AST context.
2936  /// \param NumClauses Number of clauses.
2937  ///
2938  static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
2939  unsigned NumClauses, EmptyShell);
2940 
2941  /// Get 'x' part of the associated expression/statement.
2942  Expr *getX() {
2943  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
2944  }
2945  const Expr *getX() const {
2946  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]);
2947  }
2948  /// Get helper expression of the form
2949  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
2950  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2952  return cast_or_null<Expr>(
2953  Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
2954  }
2955  const Expr *getUpdateExpr() const {
2956  return cast_or_null<Expr>(
2957  Data->getChildren()[DataPositionTy::POS_UpdateExpr]);
2958  }
2959  /// Return true if helper update expression has form
2960  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
2961  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2962  bool isXLHSInRHSPart() const { return Flags.IsXLHSInRHSPart; }
2963  /// Return true if 'v' expression must be updated to original value of
2964  /// 'x', false if 'v' must be updated to the new value of 'x'.
2965  bool isPostfixUpdate() const { return Flags.IsPostfixUpdate; }
2966  /// Get 'v' part of the associated expression/statement.
2967  Expr *getV() {
2968  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
2969  }
2970  const Expr *getV() const {
2971  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]);
2972  }
2973  /// Get 'expr' part of the associated expression/statement.
2975  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
2976  }
2977  const Expr *getExpr() const {
2978  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]);
2979  }
2980  /// Get 'd' part of the associated expression/statement.
2981  Expr *getD() {
2982  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
2983  }
2984  Expr *getD() const {
2985  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]);
2986  }
2987  /// Get the 'cond' part of the source atomic expression.
2989  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
2990  }
2991  Expr *getCondExpr() const {
2992  return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]);
2993  }
2994 
2995  static bool classof(const Stmt *T) {
2996  return T->getStmtClass() == OMPAtomicDirectiveClass;
2997  }
2998 };
2999 
3000 /// This represents '#pragma omp target' directive.
3001 ///
3002 /// \code
3003 /// #pragma omp target if(a)
3004 /// \endcode
3005 /// In this example directive '#pragma omp target' has clause 'if' with
3006 /// condition 'a'.
3007 ///
3009  friend class ASTStmtReader;
3011  /// Build directive with the given start and end location.
3012  ///
3013  /// \param StartLoc Starting location of the directive kind.
3014  /// \param EndLoc Ending location of the directive.
3015  ///
3017  : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
3018  StartLoc, EndLoc) {}
3019 
3020  /// Build an empty directive.
3021  ///
3022  explicit OMPTargetDirective()
3023  : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target,
3025 
3026 public:
3027  /// Creates directive with a list of \a Clauses.
3028  ///
3029  /// \param C AST context.
3030  /// \param StartLoc Starting location of the directive kind.
3031  /// \param EndLoc Ending Location of the directive.
3032  /// \param Clauses List of clauses.
3033  /// \param AssociatedStmt Statement, associated with the directive.
3034  ///
3035  static OMPTargetDirective *
3036  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3037  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3038 
3039  /// Creates an empty directive with the place for \a NumClauses
3040  /// clauses.
3041  ///
3042  /// \param C AST context.
3043  /// \param NumClauses Number of clauses.
3044  ///
3045  static OMPTargetDirective *CreateEmpty(const ASTContext &C,
3046  unsigned NumClauses, EmptyShell);
3047 
3048  static bool classof(const Stmt *T) {
3049  return T->getStmtClass() == OMPTargetDirectiveClass;
3050  }
3051 };
3052 
3053 /// This represents '#pragma omp target data' directive.
3054 ///
3055 /// \code
3056 /// #pragma omp target data device(0) if(a) map(b[:])
3057 /// \endcode
3058 /// In this example directive '#pragma omp target data' has clauses 'device'
3059 /// with the value '0', 'if' with condition 'a' and 'map' with array
3060 /// section 'b[:]'.
3061 ///
3063  friend class ASTStmtReader;
3065  /// Build directive with the given start and end location.
3066  ///
3067  /// \param StartLoc Starting location of the directive kind.
3068  /// \param EndLoc Ending Location of the directive.
3069  ///
3071  : OMPExecutableDirective(OMPTargetDataDirectiveClass,
3072  llvm::omp::OMPD_target_data, StartLoc, EndLoc) {}
3073 
3074  /// Build an empty directive.
3075  ///
3076  explicit OMPTargetDataDirective()
3077  : OMPExecutableDirective(OMPTargetDataDirectiveClass,
3078  llvm::omp::OMPD_target_data, SourceLocation(),
3079  SourceLocation()) {}
3080 
3081 public:
3082  /// Creates directive with a list of \a Clauses.
3083  ///
3084  /// \param C AST context.
3085  /// \param StartLoc Starting location of the directive kind.
3086  /// \param EndLoc Ending Location of the directive.
3087  /// \param Clauses List of clauses.
3088  /// \param AssociatedStmt Statement, associated with the directive.
3089  ///
3090  static OMPTargetDataDirective *
3091  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3092  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3093 
3094  /// Creates an empty directive with the place for \a N clauses.
3095  ///
3096  /// \param C AST context.
3097  /// \param N The number of clauses.
3098  ///
3099  static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
3100  EmptyShell);
3101 
3102  static bool classof(const Stmt *T) {
3103  return T->getStmtClass() == OMPTargetDataDirectiveClass;
3104  }
3105 };
3106 
3107 /// This represents '#pragma omp target enter data' directive.
3108 ///
3109 /// \code
3110 /// #pragma omp target enter data device(0) if(a) map(b[:])
3111 /// \endcode
3112 /// In this example directive '#pragma omp target enter data' has clauses
3113 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
3114 /// section 'b[:]'.
3115 ///
3117  friend class ASTStmtReader;
3119  /// Build directive with the given start and end location.
3120  ///
3121  /// \param StartLoc Starting location of the directive kind.
3122  /// \param EndLoc Ending Location of the directive.
3123  ///
3125  : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3126  llvm::omp::OMPD_target_enter_data, StartLoc,
3127  EndLoc) {}
3128 
3129  /// Build an empty directive.
3130  ///
3131  explicit OMPTargetEnterDataDirective()
3132  : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass,
3133  llvm::omp::OMPD_target_enter_data,
3135 
3136 public:
3137  /// Creates directive with a list of \a Clauses.
3138  ///
3139  /// \param C AST context.
3140  /// \param StartLoc Starting location of the directive kind.
3141  /// \param EndLoc Ending Location of the directive.
3142  /// \param Clauses List of clauses.
3143  /// \param AssociatedStmt Statement, associated with the directive.
3144  ///
3145  static OMPTargetEnterDataDirective *
3146  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3147  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3148 
3149  /// Creates an empty directive with the place for \a N clauses.
3150  ///
3151  /// \param C AST context.
3152  /// \param N The number of clauses.
3153  ///
3154  static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C,
3155  unsigned N, EmptyShell);
3156 
3157  static bool classof(const Stmt *T) {
3158  return T->getStmtClass() == OMPTargetEnterDataDirectiveClass;
3159  }
3160 };
3161 
3162 /// This represents '#pragma omp target exit data' directive.
3163 ///
3164 /// \code
3165 /// #pragma omp target exit data device(0) if(a) map(b[:])
3166 /// \endcode
3167 /// In this example directive '#pragma omp target exit data' has clauses
3168 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
3169 /// section 'b[:]'.
3170 ///
3172  friend class ASTStmtReader;
3174  /// Build directive with the given start and end location.
3175  ///
3176  /// \param StartLoc Starting location of the directive kind.
3177  /// \param EndLoc Ending Location of the directive.
3178  ///
3180  : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3181  llvm::omp::OMPD_target_exit_data, StartLoc,
3182  EndLoc) {}
3183 
3184  /// Build an empty directive.
3185  ///
3186  explicit OMPTargetExitDataDirective()
3187  : OMPExecutableDirective(OMPTargetExitDataDirectiveClass,
3188  llvm::omp::OMPD_target_exit_data,
3190 
3191 public:
3192  /// Creates directive with a list of \a Clauses.
3193  ///
3194  /// \param C AST context.
3195  /// \param StartLoc Starting location of the directive kind.
3196  /// \param EndLoc Ending Location of the directive.
3197  /// \param Clauses List of clauses.
3198  /// \param AssociatedStmt Statement, associated with the directive.
3199  ///
3200  static OMPTargetExitDataDirective *
3201  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3202  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3203 
3204  /// Creates an empty directive with the place for \a N clauses.
3205  ///
3206  /// \param C AST context.
3207  /// \param N The number of clauses.
3208  ///
3209  static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
3210  unsigned N, EmptyShell);
3211 
3212  static bool classof(const Stmt *T) {
3213  return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
3214  }
3215 };
3216 
3217 /// This represents '#pragma omp target parallel' directive.
3218 ///
3219 /// \code
3220 /// #pragma omp target parallel if(a)
3221 /// \endcode
3222 /// In this example directive '#pragma omp target parallel' has clause 'if' with
3223 /// condition 'a'.
3224 ///
3226  friend class ASTStmtReader;
3228  /// true if the construct has inner cancel directive.
3229  bool HasCancel = false;
3230 
3231  /// Build directive with the given start and end location.
3232  ///
3233  /// \param StartLoc Starting location of the directive kind.
3234  /// \param EndLoc Ending location of the directive.
3235  ///
3237  : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3238  llvm::omp::OMPD_target_parallel, StartLoc,
3239  EndLoc) {}
3240 
3241  /// Build an empty directive.
3242  ///
3243  explicit OMPTargetParallelDirective()
3244  : OMPExecutableDirective(OMPTargetParallelDirectiveClass,
3245  llvm::omp::OMPD_target_parallel,
3247 
3248  /// Sets special task reduction descriptor.
3249  void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; }
3250  /// Set cancel state.
3251  void setHasCancel(bool Has) { HasCancel = Has; }
3252 
3253 public:
3254  /// Creates directive with a list of \a Clauses.
3255  ///
3256  /// \param C AST context.
3257  /// \param StartLoc Starting location of the directive kind.
3258  /// \param EndLoc Ending Location of the directive.
3259  /// \param Clauses List of clauses.
3260  /// \param AssociatedStmt Statement, associated with the directive.
3261  /// \param TaskRedRef Task reduction special reference expression to handle
3262  /// taskgroup descriptor.
3263  /// \param HasCancel true if this directive has inner cancel directive.
3264  ///
3265  static OMPTargetParallelDirective *
3266  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3267  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef,
3268  bool HasCancel);
3269 
3270  /// Creates an empty directive with the place for \a NumClauses
3271  /// clauses.
3272  ///
3273  /// \param C AST context.
3274  /// \param NumClauses Number of clauses.
3275  ///
3276  static OMPTargetParallelDirective *
3277  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
3278 
3279  /// Returns special task reduction reference expression.
3281  return cast_or_null<Expr>(Data->getChildren()[0]);
3282  }
3284  return const_cast<OMPTargetParallelDirective *>(this)
3286  }
3287 
3288  /// Return true if current directive has inner cancel directive.
3289  bool hasCancel() const { return HasCancel; }
3290 
3291  static bool classof(const Stmt *T) {
3292  return T->getStmtClass() == OMPTargetParallelDirectiveClass;
3293  }
3294 };
3295 
3296 /// This represents '#pragma omp target parallel for' directive.
3297 ///
3298 /// \code
3299 /// #pragma omp target parallel for private(a,b) reduction(+:c,d)
3300 /// \endcode
3301 /// In this example directive '#pragma omp target parallel for' has clauses
3302 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
3303 /// and variables 'c' and 'd'.
3304 ///
3306  friend class ASTStmtReader;
3308 
3309  /// true if current region has inner cancel directive.
3310  bool HasCancel = false;
3311 
3312  /// Build directive with the given start and end location.
3313  ///
3314  /// \param StartLoc Starting location of the directive kind.
3315  /// \param EndLoc Ending location of the directive.
3316  /// \param CollapsedNum Number of collapsed nested loops.
3317  ///
3319  unsigned CollapsedNum)
3320  : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3321  llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc,
3322  CollapsedNum) {}
3323 
3324  /// Build an empty directive.
3325  ///
3326  /// \param CollapsedNum Number of collapsed nested loops.
3327  ///
3328  explicit OMPTargetParallelForDirective(unsigned CollapsedNum)
3329  : OMPLoopDirective(OMPTargetParallelForDirectiveClass,
3330  llvm::omp::OMPD_target_parallel_for, SourceLocation(),
3331  SourceLocation(), CollapsedNum) {}
3332 
3333  /// Sets special task reduction descriptor.
3334  void setTaskReductionRefExpr(Expr *E) {
3336  getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E;
3337  }
3338 
3339  /// Set cancel state.
3340  void setHasCancel(bool Has) { HasCancel = Has; }
3341 
3342 public:
3343  /// Creates directive with a list of \a Clauses.
3344  ///
3345  /// \param C AST context.
3346  /// \param StartLoc Starting location of the directive kind.
3347  /// \param EndLoc Ending Location of the directive.
3348  /// \param CollapsedNum Number of collapsed loops.
3349  /// \param Clauses List of clauses.
3350  /// \param AssociatedStmt Statement, associated with the directive.
3351  /// \param Exprs Helper expressions for CodeGen.
3352  /// \param TaskRedRef Task reduction special reference expression to handle
3353  /// taskgroup descriptor.
3354  /// \param HasCancel true if current directive has inner cancel directive.
3355  ///
3356  static OMPTargetParallelForDirective *
3357  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3358  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3359  Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
3360  bool HasCancel);
3361 
3362  /// Creates an empty directive with the place
3363  /// for \a NumClauses clauses.
3364  ///
3365  /// \param C AST context.
3366  /// \param CollapsedNum Number of collapsed nested loops.
3367  /// \param NumClauses Number of clauses.
3368  ///
3369  static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C,
3370  unsigned NumClauses,
3371  unsigned CollapsedNum,
3372  EmptyShell);
3373 
3374  /// Returns special task reduction reference expression.
3376  return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
3377  getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]);
3378  }
3380  return const_cast<OMPTargetParallelForDirective *>(this)
3382  }
3383 
3384  /// Return true if current directive has inner cancel directive.
3385  bool hasCancel() const { return HasCancel; }
3386 
3387  static bool classof(const Stmt *T) {
3388  return T->getStmtClass() == OMPTargetParallelForDirectiveClass;
3389  }
3390 };
3391 
3392 /// This represents '#pragma omp teams' directive.
3393 ///
3394 /// \code
3395 /// #pragma omp teams if(a)
3396 /// \endcode
3397 /// In this example directive '#pragma omp teams' has clause 'if' with
3398 /// condition 'a'.
3399 ///
3401  friend class ASTStmtReader;
3403  /// Build directive with the given start and end location.
3404  ///
3405  /// \param StartLoc Starting location of the directive kind.
3406  /// \param EndLoc Ending location of the directive.
3407  ///
3409  : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3410  StartLoc, EndLoc) {}
3411 
3412  /// Build an empty directive.
3413  ///
3414  explicit OMPTeamsDirective()
3415  : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams,
3417 
3418 public:
3419  /// Creates directive with a list of \a Clauses.
3420  ///
3421  /// \param C AST context.
3422  /// \param StartLoc Starting location of the directive kind.
3423  /// \param EndLoc Ending Location of the directive.
3424  /// \param Clauses List of clauses.
3425  /// \param AssociatedStmt Statement, associated with the directive.
3426  ///
3427  static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
3428  SourceLocation EndLoc,
3429  ArrayRef<OMPClause *> Clauses,
3430  Stmt *AssociatedStmt);
3431 
3432  /// Creates an empty directive with the place for \a NumClauses
3433  /// clauses.
3434  ///
3435  /// \param C AST context.
3436  /// \param NumClauses Number of clauses.
3437  ///
3438  static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
3439  unsigned NumClauses, EmptyShell);
3440 
3441  static bool classof(const Stmt *T) {
3442  return T->getStmtClass() == OMPTeamsDirectiveClass;
3443  }
3444 };
3445 
3446 /// This represents '#pragma omp cancellation point' directive.
3447 ///
3448 /// \code
3449 /// #pragma omp cancellation point for
3450 /// \endcode
3451 ///
3452 /// In this example a cancellation point is created for innermost 'for' region.
3454  friend class ASTStmtReader;
3456  OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
3457  /// Build directive with the given start and end location.
3458  ///
3459  /// \param StartLoc Starting location of the directive kind.
3460  /// \param EndLoc Ending location of the directive.
3461  /// statements and child expressions.
3462  ///
3464  : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3465  llvm::omp::OMPD_cancellation_point, StartLoc,
3466  EndLoc) {}
3467 
3468  /// Build an empty directive.
3470  : OMPExecutableDirective(OMPCancellationPointDirectiveClass,
3471  llvm::omp::OMPD_cancellation_point,
3473 
3474  /// Set cancel region for current cancellation point.
3475  /// \param CR Cancellation region.
3476  void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
3477 
3478 public:
3479  /// Creates directive.
3480  ///
3481  /// \param C AST context.
3482  /// \param StartLoc Starting location of the directive kind.
3483  /// \param EndLoc Ending Location of the directive.
3484  ///
3485  static OMPCancellationPointDirective *
3486  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3487  OpenMPDirectiveKind CancelRegion);
3488 
3489  /// Creates an empty directive.
3490  ///
3491  /// \param C AST context.
3492  ///
3493  static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
3494  EmptyShell);
3495 
3496  /// Get cancellation region for the current cancellation point.
3497  OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
3498 
3499  static bool classof(const Stmt *T) {
3500  return T->getStmtClass() == OMPCancellationPointDirectiveClass;
3501  }
3502 };
3503 
3504 /// This represents '#pragma omp cancel' directive.
3505 ///
3506 /// \code
3507 /// #pragma omp cancel for
3508 /// \endcode
3509 ///
3510 /// In this example a cancel is created for innermost 'for' region.
3512  friend class ASTStmtReader;
3514  OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown;
3515  /// Build directive with the given start and end location.
3516  ///
3517  /// \param StartLoc Starting location of the directive kind.
3518  /// \param EndLoc Ending location of the directive.
3519  ///
3521  : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3522  StartLoc, EndLoc) {}
3523 
3524  /// Build an empty directive.
3525  ///
3526  explicit OMPCancelDirective()
3527  : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel,
3529 
3530  /// Set cancel region for current cancellation point.
3531  /// \param CR Cancellation region.
3532  void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
3533 
3534 public:
3535  /// Creates directive.
3536  ///
3537  /// \param C AST context.
3538  /// \param StartLoc Starting location of the directive kind.
3539  /// \param EndLoc Ending Location of the directive.
3540  /// \param Clauses List of clauses.
3541  ///
3542  static OMPCancelDirective *
3543  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3544  ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
3545 
3546  /// Creates an empty directive.
3547  ///
3548  /// \param C AST context.
3549  /// \param NumClauses Number of clauses.
3550  ///
3551  static OMPCancelDirective *CreateEmpty(const ASTContext &C,
3552  unsigned NumClauses, EmptyShell);
3553 
3554  /// Get cancellation region for the current cancellation point.
3555  OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
3556 
3557  static bool classof(const Stmt *T) {
3558  return T->getStmtClass() == OMPCancelDirectiveClass;
3559  }
3560 };
3561 
3562 /// This represents '#pragma omp taskloop' directive.
3563 ///
3564 /// \code
3565 /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
3566 /// \endcode
3567 /// In this example directive '#pragma omp taskloop' has clauses 'private'
3568 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
3569 /// 'num_tasks' with expression 'num'.
3570 ///
3572  friend class ASTStmtReader;
3574  /// true if the construct has inner cancel directive.
3575  bool HasCancel = false;
3576 
3577  /// Build directive with the given start and end location.
3578  ///
3579  /// \param StartLoc Starting location of the directive kind.
3580  /// \param EndLoc Ending location of the directive.
3581  /// \param CollapsedNum Number of collapsed nested loops.
3582  ///
3584  unsigned CollapsedNum)
3585  : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3586  StartLoc, EndLoc, CollapsedNum) {}
3587 
3588  /// Build an empty directive.
3589  ///
3590  /// \param CollapsedNum Number of collapsed nested loops.
3591  ///
3592  explicit OMPTaskLoopDirective(unsigned CollapsedNum)
3593  : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop,
3594  SourceLocation(), SourceLocation(), CollapsedNum) {}
3595 
3596  /// Set cancel state.
3597  void setHasCancel(bool Has) { HasCancel = Has; }
3598 
3599 public:
3600  /// Creates directive with a list of \a Clauses.
3601  ///
3602  /// \param C AST context.
3603  /// \param StartLoc Starting location of the directive kind.
3604  /// \param EndLoc Ending Location of the directive.
3605  /// \param CollapsedNum Number of collapsed loops.
3606  /// \param Clauses List of clauses.
3607  /// \param AssociatedStmt Statement, associated with the directive.
3608  /// \param Exprs Helper expressions for CodeGen.
3609  /// \param HasCancel true if this directive has inner cancel directive.
3610  ///
3611  static OMPTaskLoopDirective *
3612  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3613  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3614  Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3615 
3616  /// Creates an empty directive with the place
3617  /// for \a NumClauses clauses.
3618  ///
3619  /// \param C AST context.
3620  /// \param CollapsedNum Number of collapsed nested loops.
3621  /// \param NumClauses Number of clauses.
3622  ///
3623  static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
3624  unsigned NumClauses,
3625  unsigned CollapsedNum, EmptyShell);
3626 
3627  /// Return true if current directive has inner cancel directive.
3628  bool hasCancel() const { return HasCancel; }
3629 
3630  static bool classof(const Stmt *T) {
3631  return T->getStmtClass() == OMPTaskLoopDirectiveClass;
3632  }
3633 };
3634 
3635 /// This represents '#pragma omp taskloop simd' directive.
3636 ///
3637 /// \code
3638 /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
3639 /// \endcode
3640 /// In this example directive '#pragma omp taskloop simd' has clauses 'private'
3641 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
3642 /// 'num_tasks' with expression 'num'.
3643 ///
3645  friend class ASTStmtReader;
3647  /// Build directive with the given start and end location.
3648  ///
3649  /// \param StartLoc Starting location of the directive kind.
3650  /// \param EndLoc Ending location of the directive.
3651  /// \param CollapsedNum Number of collapsed nested loops.
3652  ///
3654  unsigned CollapsedNum)
3655  : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3656  llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc,
3657  CollapsedNum) {}
3658 
3659  /// Build an empty directive.
3660  ///
3661  /// \param CollapsedNum Number of collapsed nested loops.
3662  ///
3663  explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum)
3664  : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass,
3665  llvm::omp::OMPD_taskloop_simd, SourceLocation(),
3666  SourceLocation(), CollapsedNum) {}
3667 
3668 public:
3669  /// Creates directive with a list of \a Clauses.
3670  ///
3671  /// \param C AST context.
3672  /// \param StartLoc Starting location of the directive kind.
3673  /// \param EndLoc Ending Location of the directive.
3674  /// \param CollapsedNum Number of collapsed loops.
3675  /// \param Clauses List of clauses.
3676  /// \param AssociatedStmt Statement, associated with the directive.
3677  /// \param Exprs Helper expressions for CodeGen.
3678  ///
3679  static OMPTaskLoopSimdDirective *
3680  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3681  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3682  Stmt *AssociatedStmt, const HelperExprs &Exprs);
3683 
3684  /// Creates an empty directive with the place
3685  /// for \a NumClauses clauses.
3686  ///
3687  /// \param C AST context.
3688  /// \param CollapsedNum Number of collapsed nested loops.
3689  /// \param NumClauses Number of clauses.
3690  ///
3691  static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
3692  unsigned NumClauses,
3693  unsigned CollapsedNum,
3694  EmptyShell);
3695 
3696  static bool classof(const Stmt *T) {
3697  return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
3698  }
3699 };
3700 
3701 /// This represents '#pragma omp master taskloop' directive.
3702 ///
3703 /// \code
3704 /// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num)
3705 /// \endcode
3706 /// In this example directive '#pragma omp master taskloop' has clauses
3707 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3708 /// and 'num_tasks' with expression 'num'.
3709 ///
3711  friend class ASTStmtReader;
3713  /// true if the construct has inner cancel directive.
3714  bool HasCancel = false;
3715 
3716  /// Build directive with the given start and end location.
3717  ///
3718  /// \param StartLoc Starting location of the directive kind.
3719  /// \param EndLoc Ending location of the directive.
3720  /// \param CollapsedNum Number of collapsed nested loops.
3721  ///
3723  unsigned CollapsedNum)
3724  : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3725  llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc,
3726  CollapsedNum) {}
3727 
3728  /// Build an empty directive.
3729  ///
3730  /// \param CollapsedNum Number of collapsed nested loops.
3731  ///
3732  explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum)
3733  : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass,
3734  llvm::omp::OMPD_master_taskloop, SourceLocation(),
3735  SourceLocation(), CollapsedNum) {}
3736 
3737  /// Set cancel state.
3738  void setHasCancel(bool Has) { HasCancel = Has; }
3739 
3740 public:
3741  /// Creates directive with a list of \a Clauses.
3742  ///
3743  /// \param C AST context.
3744  /// \param StartLoc Starting location of the directive kind.
3745  /// \param EndLoc Ending Location of the directive.
3746  /// \param CollapsedNum Number of collapsed loops.
3747  /// \param Clauses List of clauses.
3748  /// \param AssociatedStmt Statement, associated with the directive.
3749  /// \param Exprs Helper expressions for CodeGen.
3750  /// \param HasCancel true if this directive has inner cancel directive.
3751  ///
3752  static OMPMasterTaskLoopDirective *
3753  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3754  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3755  Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3756 
3757  /// Creates an empty directive with the place
3758  /// for \a NumClauses clauses.
3759  ///
3760  /// \param C AST context.
3761  /// \param CollapsedNum Number of collapsed nested loops.
3762  /// \param NumClauses Number of clauses.
3763  ///
3764  static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
3765  unsigned NumClauses,
3766  unsigned CollapsedNum,
3767  EmptyShell);
3768 
3769  /// Return true if current directive has inner cancel directive.
3770  bool hasCancel() const { return HasCancel; }
3771 
3772  static bool classof(const Stmt *T) {
3773  return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass;
3774  }
3775 };
3776 
3777 /// This represents '#pragma omp master taskloop simd' directive.
3778 ///
3779 /// \code
3780 /// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num)
3781 /// \endcode
3782 /// In this example directive '#pragma omp master taskloop simd' has clauses
3783 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3784 /// and 'num_tasks' with expression 'num'.
3785 ///
3787  friend class ASTStmtReader;
3789  /// Build directive with the given start and end location.
3790  ///
3791  /// \param StartLoc Starting location of the directive kind.
3792  /// \param EndLoc Ending location of the directive.
3793  /// \param CollapsedNum Number of collapsed nested loops.
3794  ///
3796  unsigned CollapsedNum)
3797  : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
3798  llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc,
3799  CollapsedNum) {}
3800 
3801  /// Build an empty directive.
3802  ///
3803  /// \param CollapsedNum Number of collapsed nested loops.
3804  ///
3805  explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum)
3806  : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass,
3807  llvm::omp::OMPD_master_taskloop_simd, SourceLocation(),
3808  SourceLocation(), CollapsedNum) {}
3809 
3810 public:
3811  /// Creates directive with a list of \p Clauses.
3812  ///
3813  /// \param C AST context.
3814  /// \param StartLoc Starting location of the directive kind.
3815  /// \param EndLoc Ending Location of the directive.
3816  /// \param CollapsedNum Number of collapsed loops.
3817  /// \param Clauses List of clauses.
3818  /// \param AssociatedStmt Statement, associated with the directive.
3819  /// \param Exprs Helper expressions for CodeGen.
3820  ///
3821  static OMPMasterTaskLoopSimdDirective *
3822  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3823  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3824  Stmt *AssociatedStmt, const HelperExprs &Exprs);
3825 
3826  /// Creates an empty directive with the place for \p NumClauses clauses.
3827  ///
3828  /// \param C AST context.
3829  /// \param CollapsedNum Number of collapsed nested loops.
3830  /// \param NumClauses Number of clauses.
3831  ///
3832  static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
3833  unsigned NumClauses,
3834  unsigned CollapsedNum,
3835  EmptyShell);
3836 
3837  static bool classof(const Stmt *T) {
3838  return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass;
3839  }
3840 };
3841 
3842 /// This represents '#pragma omp parallel master taskloop' directive.
3843 ///
3844 /// \code
3845 /// #pragma omp parallel master taskloop private(a,b) grainsize(val)
3846 /// num_tasks(num)
3847 /// \endcode
3848 /// In this example directive '#pragma omp parallel master taskloop' has clauses
3849 /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val'
3850 /// and 'num_tasks' with expression 'num'.
3851 ///
3853  friend class ASTStmtReader;
3855  /// true if the construct has inner cancel directive.
3856  bool HasCancel = false;
3857 
3858  /// Build directive with the given start and end location.
3859  ///
3860  /// \param StartLoc Starting location of the directive kind.
3861  /// \param EndLoc Ending location of the directive.
3862  /// \param CollapsedNum Number of collapsed nested loops.
3863  ///
3865  SourceLocation EndLoc,
3866  unsigned CollapsedNum)
3867  : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
3868  llvm::omp::OMPD_parallel_master_taskloop, StartLoc,
3869  EndLoc, CollapsedNum) {}
3870 
3871  /// Build an empty directive.
3872  ///
3873  /// \param CollapsedNum Number of collapsed nested loops.
3874  ///
3875  explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum)
3876  : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass,
3877  llvm::omp::OMPD_parallel_master_taskloop,
3878  SourceLocation(), SourceLocation(), CollapsedNum) {}
3879 
3880  /// Set cancel state.
3881  void setHasCancel(bool Has) { HasCancel = Has; }
3882 
3883 public:
3884  /// Creates directive with a list of \a Clauses.
3885  ///
3886  /// \param C AST context.
3887  /// \param StartLoc Starting location of the directive kind.
3888  /// \param EndLoc Ending Location of the directive.
3889  /// \param CollapsedNum Number of collapsed loops.
3890  /// \param Clauses List of clauses.
3891  /// \param AssociatedStmt Statement, associated with the directive.
3892  /// \param Exprs Helper expressions for CodeGen.
3893  /// \param HasCancel true if this directive has inner cancel directive.
3894  ///
3895  static OMPParallelMasterTaskLoopDirective *
3896  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3897  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3898  Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3899 
3900  /// Creates an empty directive with the place
3901  /// for \a NumClauses clauses.
3902  ///
3903  /// \param C AST context.
3904  /// \param CollapsedNum Number of collapsed nested loops.
3905  /// \param NumClauses Number of clauses.
3906  ///
3907  static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C,
3908  unsigned NumClauses,
3909  unsigned CollapsedNum,
3910  EmptyShell);
3911 
3912  /// Return true if current directive has inner cancel directive.
3913  bool hasCancel() const { return HasCancel; }
3914 
3915  static bool classof(const Stmt *T) {
3916  return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass;
3917  }
3918 };
3919 
3920 /// This represents '#pragma omp parallel master taskloop simd' directive.
3921 ///
3922 /// \code
3923 /// #pragma omp parallel master taskloop simd private(a,b) grainsize(val)
3924 /// num_tasks(num)
3925 /// \endcode
3926 /// In this example directive '#pragma omp parallel master taskloop simd' has
3927 /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with
3928 /// expression 'val' and 'num_tasks' with expression 'num'.
3929 ///
3931  friend class ASTStmtReader;
3933  /// Build directive with the given start and end location.
3934  ///
3935  /// \param StartLoc Starting location of the directive kind.
3936  /// \param EndLoc Ending location of the directive.
3937  /// \param CollapsedNum Number of collapsed nested loops.
3938  ///
3940  SourceLocation EndLoc,
3941  unsigned CollapsedNum)
3942  : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
3943  llvm::omp::OMPD_parallel_master_taskloop_simd,
3944  StartLoc, EndLoc, CollapsedNum) {}
3945 
3946  /// Build an empty directive.
3947  ///
3948  /// \param CollapsedNum Number of collapsed nested loops.
3949  ///
3950  explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum)
3951  : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass,
3952  llvm::omp::OMPD_parallel_master_taskloop_simd,
3953  SourceLocation(), SourceLocation(), CollapsedNum) {}
3954 
3955 public:
3956  /// Creates directive with a list of \p Clauses.
3957  ///
3958  /// \param C AST context.
3959  /// \param StartLoc Starting location of the directive kind.
3960  /// \param EndLoc Ending Location of the directive.
3961  /// \param CollapsedNum Number of collapsed loops.
3962  /// \param Clauses List of clauses.
3963  /// \param AssociatedStmt Statement, associated with the directive.
3964  /// \param Exprs Helper expressions for CodeGen.
3965  ///
3966  static OMPParallelMasterTaskLoopSimdDirective *
3967  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3968  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3969  Stmt *AssociatedStmt, const HelperExprs &Exprs);
3970 
3971  /// Creates an empty directive with the place
3972  /// for \a NumClauses clauses.
3973  ///
3974  /// \param C AST context.
3975  /// \param CollapsedNum Number of collapsed nested loops.
3976  /// \param NumClauses Number of clauses.
3977  ///
3978  static OMPParallelMasterTaskLoopSimdDirective *
3979  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
3980  EmptyShell);
3981 
3982  static bool classof(const Stmt *T) {
3983  return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass;
3984  }
3985 };
3986 
3987 /// This represents '#pragma omp distribute' directive.
3988 ///
3989 /// \code
3990 /// #pragma omp distribute private(a,b)
3991 /// \endcode
3992 /// In this example directive '#pragma omp distribute' has clauses 'private'
3993 /// with the variables 'a' and 'b'
3994 ///
3996  friend class ASTStmtReader;
3998 
3999  /// Build directive with the given start and end location.
4000  ///
4001  /// \param StartLoc Starting location of the directive kind.
4002  /// \param EndLoc Ending location of the directive.
4003  /// \param CollapsedNum Number of collapsed nested loops.
4004  ///
4006  unsigned CollapsedNum)
4007  : OMPLoopDirective(OMPDistributeDirectiveClass,
4008  llvm::omp::OMPD_distribute, StartLoc, EndLoc,
4009  CollapsedNum) {}
4010 
4011  /// Build an empty directive.
4012  ///
4013  /// \param CollapsedNum Number of collapsed nested loops.
4014  ///
4015  explicit OMPDistributeDirective(unsigned CollapsedNum)
4016  : OMPLoopDirective(OMPDistributeDirectiveClass,
4017  llvm::omp::OMPD_distribute, SourceLocation(),
4018  SourceLocation(), CollapsedNum) {}
4019 
4020 public:
4021  /// Creates directive with a list of \a Clauses.
4022  ///
4023  /// \param C AST context.
4024  /// \param StartLoc Starting location of the directive kind.
4025  /// \param EndLoc Ending Location of the directive.
4026  /// \param CollapsedNum Number of collapsed loops.
4027  /// \param Clauses List of clauses.
4028  /// \param AssociatedStmt Statement, associated with the directive.
4029  /// \param Exprs Helper expressions for CodeGen.
4030  ///
4031  static OMPDistributeDirective *
4032  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4033  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4034  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4035 
4036  /// Creates an empty directive with the place
4037  /// for \a NumClauses clauses.
4038  ///
4039  /// \param C AST context.
4040  /// \param CollapsedNum Number of collapsed nested loops.
4041  /// \param NumClauses Number of clauses.
4042  ///
4043  static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
4044  unsigned NumClauses,
4045  unsigned CollapsedNum, EmptyShell);
4046 
4047  static bool classof(const Stmt *T) {
4048  return T->getStmtClass() == OMPDistributeDirectiveClass;
4049  }
4050 };
4051 
4052 /// This represents '#pragma omp target update' directive.
4053 ///
4054 /// \code
4055 /// #pragma omp target update to(a) from(b) device(1)
4056 /// \endcode
4057 /// In this example directive '#pragma omp target update' has clause 'to' with
4058 /// argument 'a', clause 'from' with argument 'b' and clause 'device' with
4059 /// argument '1'.
4060 ///
4062  friend class ASTStmtReader;
4064  /// Build directive with the given start and end location.
4065  ///
4066  /// \param StartLoc Starting location of the directive kind.
4067  /// \param EndLoc Ending Location of the directive.
4068  ///
4070  : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
4071  llvm::omp::OMPD_target_update, StartLoc,
4072  EndLoc) {}
4073 
4074  /// Build an empty directive.
4075  ///
4076  explicit OMPTargetUpdateDirective()
4077  : OMPExecutableDirective(OMPTargetUpdateDirectiveClass,
4078  llvm::omp::OMPD_target_update, SourceLocation(),
4079  SourceLocation()) {}
4080 
4081 public:
4082  /// Creates directive with a list of \a Clauses.
4083  ///
4084  /// \param C AST context.
4085  /// \param StartLoc Starting location of the directive kind.
4086  /// \param EndLoc Ending Location of the directive.
4087  /// \param Clauses List of clauses.
4088  /// \param AssociatedStmt Statement, associated with the directive.
4089  ///
4090  static OMPTargetUpdateDirective *
4091  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4092  ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
4093 
4094  /// Creates an empty directive with the place for \a NumClauses
4095  /// clauses.
4096  ///
4097  /// \param C AST context.
4098  /// \param NumClauses The number of clauses.
4099  ///
4100  static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C,
4101  unsigned NumClauses, EmptyShell);
4102 
4103  static bool classof(const Stmt *T) {
4104  return T->getStmtClass() == OMPTargetUpdateDirectiveClass;
4105  }
4106 };
4107 
4108 /// This represents '#pragma omp distribute parallel for' composite
4109 /// directive.
4110 ///
4111 /// \code
4112 /// #pragma omp distribute parallel for private(a,b)
4113 /// \endcode
4114 /// In this example directive '#pragma omp distribute parallel for' has clause
4115 /// 'private' with the variables 'a' and 'b'
4116 ///
4118  friend class ASTStmtReader;
4120  /// true if the construct has inner cancel directive.
4121  bool HasCancel = false;
4122 
4123  /// Build directive with the given start and end location.
4124  ///
4125  /// \param StartLoc Starting location of the directive kind.
4126  /// \param EndLoc Ending location of the directive.
4127  /// \param CollapsedNum Number of collapsed nested loops.
4128  ///
4130  SourceLocation EndLoc,
4131  unsigned CollapsedNum)
4132  : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4133  llvm::omp::OMPD_distribute_parallel_for, StartLoc,
4134  EndLoc, CollapsedNum) {}
4135 
4136  /// Build an empty directive.
4137  ///
4138  /// \param CollapsedNum Number of collapsed nested loops.
4139  ///
4140  explicit OMPDistributeParallelForDirective(unsigned CollapsedNum)
4141  : OMPLoopDirective(OMPDistributeParallelForDirectiveClass,
4142  llvm::omp::OMPD_distribute_parallel_for,
4143  SourceLocation(), SourceLocation(), CollapsedNum) {}
4144 
4145  /// Sets special task reduction descriptor.
4146  void setTaskReductionRefExpr(Expr *E) {
4148  getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E;
4149  }
4150 
4151  /// Set cancel state.
4152  void setHasCancel(bool Has) { HasCancel = Has; }
4153 
4154 public:
4155  /// Creates directive with a list of \a Clauses.
4156  ///
4157  /// \param C AST context.
4158  /// \param StartLoc Starting location of the directive kind.
4159  /// \param EndLoc Ending Location of the directive.
4160  /// \param CollapsedNum Number of collapsed loops.
4161  /// \param Clauses List of clauses.
4162  /// \param AssociatedStmt Statement, associated with the directive.
4163  /// \param Exprs Helper expressions for CodeGen.
4164  /// \param TaskRedRef Task reduction special reference expression to handle
4165  /// taskgroup descriptor.
4166  /// \param HasCancel true if this directive has inner cancel directive.
4167  ///
4168  static OMPDistributeParallelForDirective *
4169  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4170  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4171  Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
4172  bool HasCancel);
4173 
4174  /// Creates an empty directive with the place
4175  /// for \a NumClauses clauses.
4176  ///
4177  /// \param C AST context.
4178  /// \param CollapsedNum Number of collapsed nested loops.
4179  /// \param NumClauses Number of clauses.
4180  ///
4181  static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C,
4182  unsigned NumClauses,
4183  unsigned CollapsedNum,
4184  EmptyShell);
4185 
4186  /// Returns special task reduction reference expression.
4188  return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
4189  getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]);
4190  }
4192  return const_cast<OMPDistributeParallelForDirective *>(this)
4194  }
4195 
4196  /// Return true if current directive has inner cancel directive.
4197  bool hasCancel() const { return HasCancel; }
4198 
4199  static bool classof(const Stmt *T) {
4200  return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
4201  }
4202 };
4203 
4204 /// This represents '#pragma omp distribute parallel for simd' composite
4205 /// directive.
4206 ///
4207 /// \code
4208 /// #pragma omp distribute parallel for simd private(x)
4209 /// \endcode
4210 /// In this example directive '#pragma omp distribute parallel for simd' has
4211 /// clause 'private' with the variables 'x'
4212 ///
4214  friend class ASTStmtReader;
4216 
4217  /// Build directive with the given start and end location.
4218  ///
4219  /// \param StartLoc Starting location of the directive kind.
4220  /// \param EndLoc Ending location of the directive.
4221  /// \param CollapsedNum Number of collapsed nested loops.
4222  ///
4224  SourceLocation EndLoc,
4225  unsigned CollapsedNum)
4226  : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4227  llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc,
4228  EndLoc, CollapsedNum) {}
4229 
4230  /// Build an empty directive.
4231  ///
4232  /// \param CollapsedNum Number of collapsed nested loops.
4233  ///
4234  explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum)
4235  : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass,
4236  llvm::omp::OMPD_distribute_parallel_for_simd,
4237  SourceLocation(), SourceLocation(), CollapsedNum) {}
4238 
4239 public:
4240  /// Creates directive with a list of \a Clauses.
4241  ///
4242  /// \param C AST context.
4243  /// \param StartLoc Starting location of the directive kind.
4244  /// \param EndLoc Ending Location of the directive.
4245  /// \param CollapsedNum Number of collapsed loops.
4246  /// \param Clauses List of clauses.
4247  /// \param AssociatedStmt Statement, associated with the directive.
4248  /// \param Exprs Helper expressions for CodeGen.
4249  ///
4250  static OMPDistributeParallelForSimdDirective *Create(
4251  const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4252  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4253  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4254 
4255  /// Creates an empty directive with the place for \a NumClauses clauses.
4256  ///
4257  /// \param C AST context.
4258  /// \param CollapsedNum Number of collapsed nested loops.
4259  /// \param NumClauses Number of clauses.
4260  ///
4261  static OMPDistributeParallelForSimdDirective *CreateEmpty(
4262  const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4263  EmptyShell);
4264 
4265  static bool classof(const Stmt *T) {
4266  return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass;
4267  }
4268 };
4269 
4270 /// This represents '#pragma omp distribute simd' composite directive.
4271 ///
4272 /// \code
4273 /// #pragma omp distribute simd private(x)
4274 /// \endcode
4275 /// In this example directive '#pragma omp distribute simd' has clause
4276 /// 'private' with the variables 'x'
4277 ///
4279  friend class ASTStmtReader;
4281 
4282  /// Build directive with the given start and end location.
4283  ///
4284  /// \param StartLoc Starting location of the directive kind.
4285  /// \param EndLoc Ending location of the directive.
4286  /// \param CollapsedNum Number of collapsed nested loops.
4287  ///
4289  unsigned CollapsedNum)
4290  : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4291  llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc,
4292  CollapsedNum) {}
4293 
4294  /// Build an empty directive.
4295  ///
4296  /// \param CollapsedNum Number of collapsed nested loops.
4297  ///
4298  explicit OMPDistributeSimdDirective(unsigned CollapsedNum)
4299  : OMPLoopDirective(OMPDistributeSimdDirectiveClass,
4300  llvm::omp::OMPD_distribute_simd, SourceLocation(),
4301  SourceLocation(), CollapsedNum) {}
4302 
4303 public:
4304  /// Creates directive with a list of \a Clauses.
4305  ///
4306  /// \param C AST context.
4307  /// \param StartLoc Starting location of the directive kind.
4308  /// \param EndLoc Ending Location of the directive.
4309  /// \param CollapsedNum Number of collapsed loops.
4310  /// \param Clauses List of clauses.
4311  /// \param AssociatedStmt Statement, associated with the directive.
4312  /// \param Exprs Helper expressions for CodeGen.
4313  ///
4314  static OMPDistributeSimdDirective *
4315  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4316  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4317  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4318 
4319  /// Creates an empty directive with the place for \a NumClauses clauses.
4320  ///
4321  /// \param C AST context.
4322  /// \param CollapsedNum Number of collapsed nested loops.
4323  /// \param NumClauses Number of clauses.
4324  ///
4325  static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C,
4326  unsigned NumClauses,
4327  unsigned CollapsedNum,
4328  EmptyShell);
4329 
4330  static bool classof(const Stmt *T) {
4331  return T->getStmtClass() == OMPDistributeSimdDirectiveClass;
4332  }
4333 };
4334 
4335 /// This represents '#pragma omp target parallel for simd' directive.
4336 ///
4337 /// \code
4338 /// #pragma omp target parallel for simd private(a) map(b) safelen(c)
4339 /// \endcode
4340 /// In this example directive '#pragma omp target parallel for simd' has clauses
4341 /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen'
4342 /// with the variable 'c'.
4343 ///
4345  friend class ASTStmtReader;
4347 
4348  /// Build directive with the given start and end location.
4349  ///
4350  /// \param StartLoc Starting location of the directive kind.
4351  /// \param EndLoc Ending location of the directive.
4352  /// \param CollapsedNum Number of collapsed nested loops.
4353  ///
4355  SourceLocation EndLoc,
4356  unsigned CollapsedNum)
4357  : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4358  llvm::omp::OMPD_target_parallel_for_simd, StartLoc,
4359  EndLoc, CollapsedNum) {}
4360 
4361  /// Build an empty directive.
4362  ///
4363  /// \param CollapsedNum Number of collapsed nested loops.
4364  ///
4365  explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum)
4366  : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass,
4367  llvm::omp::OMPD_target_parallel_for_simd,
4368  SourceLocation(), SourceLocation(), CollapsedNum) {}
4369 
4370 public:
4371  /// Creates directive with a list of \a Clauses.
4372  ///
4373  /// \param C AST context.
4374  /// \param StartLoc Starting location of the directive kind.
4375  /// \param EndLoc Ending Location of the directive.
4376  /// \param CollapsedNum Number of collapsed loops.
4377  /// \param Clauses List of clauses.
4378  /// \param AssociatedStmt Statement, associated with the directive.
4379  /// \param Exprs Helper expressions for CodeGen.
4380  ///
4381  static OMPTargetParallelForSimdDirective *
4382  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4383  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4384  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4385 
4386  /// Creates an empty directive with the place for \a NumClauses clauses.
4387  ///
4388  /// \param C AST context.
4389  /// \param CollapsedNum Number of collapsed nested loops.
4390  /// \param NumClauses Number of clauses.
4391  ///
4392  static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C,
4393  unsigned NumClauses,
4394  unsigned CollapsedNum,
4395  EmptyShell);
4396 
4397  static bool classof(const Stmt *T) {
4398  return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
4399  }
4400 };
4401 
4402 /// This represents '#pragma omp target simd' directive.
4403 ///
4404 /// \code
4405 /// #pragma omp target simd private(a) map(b) safelen(c)
4406 /// \endcode
4407 /// In this example directive '#pragma omp target simd' has clauses 'private'
4408 /// with the variable 'a', 'map' with the variable 'b' and 'safelen' with
4409 /// the variable 'c'.
4410 ///
4412  friend class ASTStmtReader;
4414 
4415  /// Build directive with the given start and end location.
4416  ///
4417  /// \param StartLoc Starting location of the directive kind.
4418  /// \param EndLoc Ending location of the directive.
4419  /// \param CollapsedNum Number of collapsed nested loops.
4420  ///
4422  unsigned CollapsedNum)
4423  : OMPLoopDirective(OMPTargetSimdDirectiveClass,
4424  llvm::omp::OMPD_target_simd, StartLoc, EndLoc,
4425  CollapsedNum) {}
4426 
4427  /// Build an empty directive.
4428  ///
4429  /// \param CollapsedNum Number of collapsed nested loops.
4430  ///
4431  explicit OMPTargetSimdDirective(unsigned CollapsedNum)
4432  : OMPLoopDirective(OMPTargetSimdDirectiveClass,
4433  llvm::omp::OMPD_target_simd, SourceLocation(),
4434  SourceLocation(), CollapsedNum) {}
4435 
4436 public:
4437  /// Creates directive with a list of \a Clauses.
4438  ///
4439  /// \param C AST context.
4440  /// \param StartLoc Starting location of the directive kind.
4441  /// \param EndLoc Ending Location of the directive.
4442  /// \param CollapsedNum Number of collapsed loops.
4443  /// \param Clauses List of clauses.
4444  /// \param AssociatedStmt Statement, associated with the directive.
4445  /// \param Exprs Helper expressions for CodeGen.
4446  ///
4447  static OMPTargetSimdDirective *
4448  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4449  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4450  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4451 
4452  /// Creates an empty directive with the place for \a NumClauses clauses.
4453  ///
4454  /// \param C AST context.
4455  /// \param CollapsedNum Number of collapsed nested loops.
4456  /// \param NumClauses Number of clauses.
4457  ///
4458  static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C,
4459  unsigned NumClauses,
4460  unsigned CollapsedNum,
4461  EmptyShell);
4462 
4463  static bool classof(const Stmt *T) {
4464  return T->getStmtClass() == OMPTargetSimdDirectiveClass;
4465  }
4466 };
4467 
4468 /// This represents '#pragma omp teams distribute' directive.
4469 ///
4470 /// \code
4471 /// #pragma omp teams distribute private(a,b)
4472 /// \endcode
4473 /// In this example directive '#pragma omp teams distribute' has clauses
4474 /// 'private' with the variables 'a' and 'b'
4475 ///
4477  friend class ASTStmtReader;
4479 
4480  /// Build directive with the given start and end location.
4481  ///
4482  /// \param StartLoc Starting location of the directive kind.
4483  /// \param EndLoc Ending location of the directive.
4484  /// \param CollapsedNum Number of collapsed nested loops.
4485  ///
4487  unsigned CollapsedNum)
4488  : OMPLoopDirective(OMPTeamsDistributeDirectiveClass,
4489  llvm::omp::OMPD_teams_distribute, StartLoc, EndLoc,
4490  CollapsedNum) {}
4491 
4492  /// Build an empty directive.
4493  ///
4494  /// \param CollapsedNum Number of collapsed nested loops.
4495  ///
4496  explicit OMPTeamsDistributeDirective(unsigned CollapsedNum)
4497  : OMPLoopDirective(OMPTeamsDistributeDirectiveClass,
4498  llvm::omp::OMPD_teams_distribute, SourceLocation(),
4499  SourceLocation(), CollapsedNum) {}
4500 
4501 public:
4502  /// Creates directive with a list of \a Clauses.
4503  ///
4504  /// \param C AST context.
4505  /// \param StartLoc Starting location of the directive kind.
4506  /// \param EndLoc Ending Location of the directive.
4507  /// \param CollapsedNum Number of collapsed loops.
4508  /// \param Clauses List of clauses.
4509  /// \param AssociatedStmt Statement, associated with the directive.
4510  /// \param Exprs Helper expressions for CodeGen.
4511  ///
4512  static OMPTeamsDistributeDirective *
4513  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4514  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4515  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4516 
4517  /// Creates an empty directive with the place for \a NumClauses clauses.
4518  ///
4519  /// \param C AST context.
4520  /// \param CollapsedNum Number of collapsed nested loops.
4521  /// \param NumClauses Number of clauses.
4522  ///
4523  static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C,
4524  unsigned NumClauses,
4525  unsigned CollapsedNum,
4526  EmptyShell);
4527 
4528  static bool classof(const Stmt *T) {
4529  return T->getStmtClass() == OMPTeamsDistributeDirectiveClass;
4530  }
4531 };
4532 
4533 /// This represents '#pragma omp teams distribute simd'
4534 /// combined directive.
4535 ///
4536 /// \code
4537 /// #pragma omp teams distribute simd private(a,b)
4538 /// \endcode
4539 /// In this example directive '#pragma omp teams distribute simd'
4540 /// has clause 'private' with the variables 'a' and 'b'
4541 ///
4543  friend class ASTStmtReader;
4545 
4546  /// Build directive with the given start and end location.
4547  ///
4548  /// \param StartLoc Starting location of the directive kind.
4549  /// \param EndLoc Ending location of the directive.
4550  /// \param CollapsedNum Number of collapsed nested loops.
4551  ///
4553  SourceLocation EndLoc, unsigned CollapsedNum)
4554  : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass,
4555  llvm::omp::OMPD_teams_distribute_simd, StartLoc,
4556  EndLoc, CollapsedNum) {}
4557 
4558  /// Build an empty directive.
4559  ///
4560  /// \param CollapsedNum Number of collapsed nested loops.
4561  ///
4562  explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum)
4563  : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass,
4564  llvm::omp::OMPD_teams_distribute_simd,
4565  SourceLocation(), SourceLocation(), CollapsedNum) {}
4566 
4567 public:
4568  /// Creates directive with a list of \a Clauses.
4569  ///
4570  /// \param C AST context.
4571  /// \param StartLoc Starting location of the directive kind.
4572  /// \param EndLoc Ending Location of the directive.
4573  /// \param CollapsedNum Number of collapsed loops.
4574  /// \param Clauses List of clauses.
4575  /// \param AssociatedStmt Statement, associated with the directive.
4576  /// \param Exprs Helper expressions for CodeGen.
4577  ///
4578  static OMPTeamsDistributeSimdDirective *
4579  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4580  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4581  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4582 
4583  /// Creates an empty directive with the place
4584  /// for \a NumClauses clauses.
4585  ///
4586  /// \param C AST context.
4587  /// \param CollapsedNum Number of collapsed nested loops.
4588  /// \param NumClauses Number of clauses.
4589  ///
4590  static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C,
4591  unsigned NumClauses,
4592  unsigned CollapsedNum,
4593  EmptyShell);
4594 
4595  static bool classof(const Stmt *T) {
4596  return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass;
4597  }
4598 };
4599 
4600 /// This represents '#pragma omp teams distribute parallel for simd' composite
4601 /// directive.
4602 ///
4603 /// \code
4604 /// #pragma omp teams distribute parallel for simd private(x)
4605 /// \endcode
4606 /// In this example directive '#pragma omp teams distribute parallel for simd'
4607 /// has clause 'private' with the variables 'x'
4608 ///
4610  : public OMPLoopDirective {
4611  friend class ASTStmtReader;
4613 
4614  /// Build directive with the given start and end location.
4615  ///
4616  /// \param StartLoc Starting location of the directive kind.
4617  /// \param EndLoc Ending location of the directive.
4618  /// \param CollapsedNum Number of collapsed nested loops.
4619  ///
4621  SourceLocation EndLoc,
4622  unsigned CollapsedNum)
4623  : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass,
4624  llvm::omp::OMPD_teams_distribute_parallel_for_simd,
4625  StartLoc, EndLoc, CollapsedNum) {}
4626 
4627  /// Build an empty directive.
4628  ///
4629  /// \param CollapsedNum Number of collapsed nested loops.
4630  ///
4631  explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum)
4632  : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass,
4633  llvm::omp::OMPD_teams_distribute_parallel_for_simd,
4634  SourceLocation(), SourceLocation(), CollapsedNum) {}
4635 
4636 public:
4637  /// Creates directive with a list of \a Clauses.
4638  ///
4639  /// \param C AST context.
4640  /// \param StartLoc Starting location of the directive kind.
4641  /// \param EndLoc Ending Location of the directive.
4642  /// \param CollapsedNum Number of collapsed loops.
4643  /// \param Clauses List of clauses.
4644  /// \param AssociatedStmt Statement, associated with the directive.
4645  /// \param Exprs Helper expressions for CodeGen.
4646  ///
4647  static OMPTeamsDistributeParallelForSimdDirective *
4648  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4649  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4650  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4651 
4652  /// Creates an empty directive with the place for \a NumClauses clauses.
4653  ///
4654  /// \param C AST context.
4655  /// \param CollapsedNum Number of collapsed nested loops.
4656  /// \param NumClauses Number of clauses.
4657  ///
4658  static OMPTeamsDistributeParallelForSimdDirective *
4659  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4660  EmptyShell);
4661 
4662  static bool classof(const Stmt *T) {
4663  return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass;
4664  }
4665 };
4666 
4667 /// This represents '#pragma omp teams distribute parallel for' composite
4668 /// directive.
4669 ///
4670 /// \code
4671 /// #pragma omp teams distribute parallel for private(x)
4672 /// \endcode
4673 /// In this example directive '#pragma omp teams distribute parallel for'
4674 /// has clause 'private' with the variables 'x'
4675 ///
4677  friend class ASTStmtReader;
4679  /// true if the construct has inner cancel directive.
4680  bool HasCancel = false;
4681 
4682  /// Build directive with the given start and end location.
4683  ///
4684  /// \param StartLoc Starting location of the directive kind.
4685  /// \param EndLoc Ending location of the directive.
4686  /// \param CollapsedNum Number of collapsed nested loops.
4687  ///
4689  SourceLocation EndLoc,
4690  unsigned CollapsedNum)
4691  : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass,
4692  llvm::omp::OMPD_teams_distribute_parallel_for,
4693  StartLoc, EndLoc, CollapsedNum) {}
4694 
4695  /// Build an empty directive.
4696  ///
4697  /// \param CollapsedNum Number of collapsed nested loops.
4698  ///
4699  explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum)
4700  : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass,
4701  llvm::omp::OMPD_teams_distribute_parallel_for,
4702  SourceLocation(), SourceLocation(), CollapsedNum) {}
4703 
4704  /// Sets special task reduction descriptor.
4705  void setTaskReductionRefExpr(Expr *E) {
4707  getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)] = E;
4708  }
4709 
4710  /// Set cancel state.
4711  void setHasCancel(bool Has) { HasCancel = Has; }
4712 
4713 public:
4714  /// Creates directive with a list of \a Clauses.
4715  ///
4716  /// \param C AST context.
4717  /// \param StartLoc Starting location of the directive kind.
4718  /// \param EndLoc Ending Location of the directive.
4719  /// \param CollapsedNum Number of collapsed loops.
4720  /// \param Clauses List of clauses.
4721  /// \param AssociatedStmt Statement, associated with the directive.
4722  /// \param Exprs Helper expressions for CodeGen.
4723  /// \param TaskRedRef Task reduction special reference expression to handle
4724  /// taskgroup descriptor.
4725  /// \param HasCancel true if this directive has inner cancel directive.
4726  ///
4727  static OMPTeamsDistributeParallelForDirective *
4728  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4729  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4730  Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
4731  bool HasCancel);
4732 
4733  /// Creates an empty directive with the place for \a NumClauses clauses.
4734  ///
4735  /// \param C AST context.
4736  /// \param CollapsedNum Number of collapsed nested loops.
4737  /// \param NumClauses Number of clauses.
4738  ///
4739  static OMPTeamsDistributeParallelForDirective *
4740  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4741  EmptyShell);
4742 
4743  /// Returns special task reduction reference expression.
4745  return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
4746  getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)]);
4747  }
4749  return const_cast<OMPTeamsDistributeParallelForDirective *>(this)
4751  }
4752 
4753  /// Return true if current directive has inner cancel directive.
4754  bool hasCancel() const { return HasCancel; }
4755 
4756  static bool classof(const Stmt *T) {
4757  return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass;
4758  }
4759 };
4760 
4761 /// This represents '#pragma omp target teams' directive.
4762 ///
4763 /// \code
4764 /// #pragma omp target teams if(a>0)
4765 /// \endcode
4766 /// In this example directive '#pragma omp target teams' has clause 'if' with
4767 /// condition 'a>0'.
4768 ///
4770  friend class ASTStmtReader;
4772  /// Build directive with the given start and end location.
4773  ///
4774  /// \param StartLoc Starting location of the directive kind.
4775  /// \param EndLoc Ending location of the directive.
4776  ///
4778  : OMPExecutableDirective(OMPTargetTeamsDirectiveClass,
4779  llvm::omp::OMPD_target_teams, StartLoc, EndLoc) {
4780  }
4781 
4782  /// Build an empty directive.
4783  ///
4784  explicit OMPTargetTeamsDirective()
4785  : OMPExecutableDirective(OMPTargetTeamsDirectiveClass,
4786  llvm::omp::OMPD_target_teams, SourceLocation(),
4787  SourceLocation()) {}
4788 
4789 public:
4790  /// Creates directive with a list of \a Clauses.
4791  ///
4792  /// \param C AST context.
4793  /// \param StartLoc Starting location of the directive kind.
4794  /// \param EndLoc Ending Location of the directive.
4795  /// \param Clauses List of clauses.
4796  /// \param AssociatedStmt Statement, associated with the directive.
4797  ///
4798  static OMPTargetTeamsDirective *Create(const ASTContext &C,
4799  SourceLocation StartLoc,
4800  SourceLocation EndLoc,
4801  ArrayRef<OMPClause *> Clauses,
4802  Stmt *AssociatedStmt);
4803 
4804  /// Creates an empty directive with the place for \a NumClauses clauses.
4805  ///
4806  /// \param C AST context.
4807  /// \param NumClauses Number of clauses.
4808  ///
4809  static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C,
4810  unsigned NumClauses, EmptyShell);
4811 
4812  static bool classof(const Stmt *T) {
4813  return T->getStmtClass() == OMPTargetTeamsDirectiveClass;
4814  }
4815 };
4816 
4817 /// This represents '#pragma omp target teams distribute' combined directive.
4818 ///
4819 /// \code
4820 /// #pragma omp target teams distribute private(x)
4821 /// \endcode
4822 /// In this example directive '#pragma omp target teams distribute' has clause
4823 /// 'private' with the variables 'x'
4824 ///
4826  friend class ASTStmtReader;
4828 
4829  /// Build directive with the given start and end location.
4830  ///
4831  /// \param StartLoc Starting location of the directive kind.
4832  /// \param EndLoc Ending location of the directive.
4833  /// \param CollapsedNum Number of collapsed nested loops.
4834  ///
4836  SourceLocation EndLoc,
4837  unsigned CollapsedNum)
4838  : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass,
4839  llvm::omp::OMPD_target_teams_distribute, StartLoc,
4840  EndLoc, CollapsedNum) {}
4841 
4842  /// Build an empty directive.
4843  ///
4844  /// \param CollapsedNum Number of collapsed nested loops.
4845  ///
4846  explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum)
4847  : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass,
4848  llvm::omp::OMPD_target_teams_distribute,
4849  SourceLocation(), SourceLocation(), CollapsedNum) {}
4850 
4851 public:
4852  /// Creates directive with a list of \a Clauses.
4853  ///
4854  /// \param C AST context.
4855  /// \param StartLoc Starting location of the directive kind.
4856  /// \param EndLoc Ending Location of the directive.
4857  /// \param CollapsedNum Number of collapsed loops.
4858  /// \param Clauses List of clauses.
4859  /// \param AssociatedStmt Statement, associated with the directive.
4860  /// \param Exprs Helper expressions for CodeGen.
4861  ///
4862  static OMPTargetTeamsDistributeDirective *
4863  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4864  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4865  Stmt *AssociatedStmt, const HelperExprs &Exprs);
4866 
4867  /// Creates an empty directive with the place for \a NumClauses clauses.
4868  ///
4869  /// \param C AST context.
4870  /// \param CollapsedNum Number of collapsed nested loops.
4871  /// \param NumClauses Number of clauses.
4872  ///
4873  static OMPTargetTeamsDistributeDirective *
4874  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4875  EmptyShell);
4876 
4877  static bool classof(const Stmt *T) {
4878  return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass;
4879  }
4880 };
4881 
4882 /// This represents '#pragma omp target teams distribute parallel for' combined
4883 /// directive.
4884 ///
4885 /// \code
4886 /// #pragma omp target teams distribute parallel for private(x)
4887 /// \endcode
4888 /// In this example directive '#pragma omp target teams distribute parallel
4889 /// for' has clause 'private' with the variables 'x'
4890 ///
4892  : public OMPLoopDirective {
4893  friend class ASTStmtReader;
4895  /// true if the construct has inner cancel directive.
4896  bool HasCancel = false;
4897 
4898  /// Build directive with the given start and end location.
4899  ///
4900  /// \param StartLoc Starting location of the directive kind.
4901  /// \param EndLoc Ending location of the directive.
4902  /// \param CollapsedNum Number of collapsed nested loops.
4903  ///
4905  SourceLocation EndLoc,
4906  unsigned CollapsedNum)
4907  : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass,
4908  llvm::omp::OMPD_target_teams_distribute_parallel_for,
4909  StartLoc, EndLoc, CollapsedNum) {}
4910 
4911  /// Build an empty directive.
4912  ///
4913  /// \param CollapsedNum Number of collapsed nested loops.
4914  ///
4915  explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum)
4916  : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass,
4917  llvm::omp::OMPD_target_teams_distribute_parallel_for,
4918  SourceLocation(), SourceLocation(), CollapsedNum) {}
4919 
4920  /// Sets special task reduction descriptor.
4921  void setTaskReductionRefExpr(Expr *E) {
4923  getLoopsNumber(),
4924  llvm::omp::OMPD_target_teams_distribute_parallel_for)] = E;
4925  }
4926 
4927  /// Set cancel state.
4928  void setHasCancel(bool Has) { HasCancel = Has; }
4929 
4930 public:
4931  /// Creates directive with a list of \a Clauses.
4932  ///
4933  /// \param C AST context.
4934  /// \param StartLoc Starting location of the directive kind.
4935  /// \param EndLoc Ending Location of the directive.
4936  /// \param CollapsedNum Number of collapsed loops.
4937  /// \param Clauses List of clauses.
4938  /// \param AssociatedStmt Statement, associated with the directive.
4939  /// \param Exprs Helper expressions for CodeGen.
4940  /// \param TaskRedRef Task reduction special reference expression to handle
4941  /// taskgroup descriptor.
4942  /// \param HasCancel true if this directive has inner cancel directive.
4943  ///
4944  static OMPTargetTeamsDistributeParallelForDirective *
4945  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4946  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4947  Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef,
4948  bool HasCancel);
4949 
4950  /// Creates an empty directive with the place for \a NumClauses clauses.
4951  ///
4952  /// \param C AST context.
4953  /// \param CollapsedNum Number of collapsed nested loops.
4954  /// \param NumClauses Number of clauses.
4955  ///
4956  static OMPTargetTeamsDistributeParallelForDirective *
4957  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4958  EmptyShell);
4959 
4960  /// Returns special task reduction reference expression.
4962  return cast_or_null<Expr>(Data->getChildren()[numLoopChildren(
4963  getLoopsNumber(),
4964  llvm::omp::OMPD_target_teams_distribute_parallel_for)]);
4965  }
4967  return const_cast<OMPTargetTeamsDistributeParallelForDirective *>(this)
4969  }
4970 
4971  /// Return true if current directive has inner cancel directive.
4972  bool hasCancel() const { return HasCancel; }
4973 
4974  static bool classof(const Stmt *T) {
4975  return T->getStmtClass() ==
4976  OMPTargetTeamsDistributeParallelForDirectiveClass;
4977  }
4978 };
4979 
4980 /// This represents '#pragma omp target teams distribute parallel for simd'
4981 /// combined directive.
4982 ///
4983 /// \code
4984 /// #pragma omp target teams distribute parallel for simd private(x)
4985 /// \endcode
4986 /// In this example directive '#pragma omp target teams distribute parallel
4987 /// for simd' has clause 'private' with the variables 'x'
4988 ///
4990  : public OMPLoopDirective {
4991  friend class ASTStmtReader;
4993 
4994  /// Build directive with the given start and end location.
4995  ///
4996  /// \param StartLoc Starting location of the directive kind.
4997  /// \param EndLoc Ending location of the directive.
4998  /// \param CollapsedNum Number of collapsed nested loops.
4999  ///
5001  SourceLocation EndLoc,
5002  unsigned CollapsedNum)
5003  : OMPLoopDirective(
5004  OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
5005  llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, StartLoc,
5006  EndLoc, CollapsedNum) {}
5007 
5008  /// Build an empty directive.
5009  ///
5010  /// \param CollapsedNum Number of collapsed nested loops.
5011  ///
5013  unsigned CollapsedNum)
5014  : OMPLoopDirective(
5015  OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
5016  llvm::omp::OMPD_target_teams_distribute_parallel_for_simd,
5017  SourceLocation(), SourceLocation(), CollapsedNum) {}
5018 
5019 public:
5020  /// Creates directive with a list of \a Clauses.
5021  ///
5022  /// \param C AST context.
5023  /// \param StartLoc Starting location of the directive kind.
5024  /// \param EndLoc Ending Location of the directive.
5025  /// \param CollapsedNum Number of collapsed loops.
5026  /// \param Clauses List of clauses.
5027  /// \param AssociatedStmt Statement, associated with the directive.
5028  /// \param Exprs Helper expressions for CodeGen.
5029  ///
5030  static OMPTargetTeamsDistributeParallelForSimdDirective *
5031  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5032  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5033  Stmt *AssociatedStmt, const HelperExprs &Exprs);
5034 
5035  /// Creates an empty directive with the place for \a NumClauses clauses.
5036  ///
5037  /// \param C AST context.
5038  /// \param CollapsedNum Number of collapsed nested loops.
5039  /// \param NumClauses Number of clauses.
5040  ///
5041  static OMPTargetTeamsDistributeParallelForSimdDirective *
5042  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5043  EmptyShell);
5044 
5045  static bool classof(const Stmt *T) {
5046  return T->getStmtClass() ==
5047  OMPTargetTeamsDistributeParallelForSimdDirectiveClass;
5048  }
5049 };
5050 
5051 /// This represents '#pragma omp target teams distribute simd' combined
5052 /// directive.
5053 ///
5054 /// \code
5055 /// #pragma omp target teams distribute simd private(x)
5056 /// \endcode
5057 /// In this example directive '#pragma omp target teams distribute simd'
5058 /// has clause 'private' with the variables 'x'
5059 ///
5061  friend class ASTStmtReader;
5063 
5064  /// Build directive with the given start and end location.
5065  ///
5066  /// \param StartLoc Starting location of the directive kind.
5067  /// \param EndLoc Ending location of the directive.
5068  /// \param CollapsedNum Number of collapsed nested loops.
5069  ///
5071  SourceLocation EndLoc,
5072  unsigned CollapsedNum)
5073  : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass,
5074  llvm::omp::OMPD_target_teams_distribute_simd, StartLoc,
5075  EndLoc, CollapsedNum) {}
5076 
5077  /// Build an empty directive.
5078  ///
5079  /// \param CollapsedNum Number of collapsed nested loops.
5080  ///
5081  explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum)
5082  : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass,
5083  llvm::omp::OMPD_target_teams_distribute_simd,
5084  SourceLocation(), SourceLocation(), CollapsedNum) {}
5085 
5086 public:
5087  /// Creates directive with a list of \a Clauses.
5088  ///
5089  /// \param C AST context.
5090  /// \param StartLoc Starting location of the directive kind.
5091  /// \param EndLoc Ending Location of the directive.
5092  /// \param CollapsedNum Number of collapsed loops.
5093  /// \param Clauses List of clauses.
5094  /// \param AssociatedStmt Statement, associated with the directive.
5095  /// \param Exprs Helper expressions for CodeGen.
5096  ///
5097  static OMPTargetTeamsDistributeSimdDirective *
5098  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
5099  unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
5100  Stmt *AssociatedStmt, const HelperExprs &Exprs);
5101 
5102  /// Creates an empty directive with the place for \a NumClauses clauses.
5103  ///
5104  /// \param C AST context.
5105  /// \param CollapsedNum Number of collapsed nested loops.
5106  /// \param NumClauses Number of clauses.
5107  ///
5108  static OMPTargetTeamsDistributeSimdDirective *
5109  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
5110  EmptyShell);
5111 
5112  static bool classof(const Stmt *T) {
5113  return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
5114  }
5115 };
5116 
5117 /// This represents the '#pragma omp tile' loop transformation directive.
5119  friend class ASTStmtReader;
5121 
5122  /// Default list of offsets.
5123  enum {
5124  PreInitsOffset = 0,
5125  TransformedStmtOffset,
5126  };
5127 
5128  explicit OMPTileDirective(SourceLocation StartLoc, SourceLocation EndLoc,
5129  unsigned NumLoops)
5130  : OMPLoopTransformationDirective(OMPTileDirectiveClass,
5131  llvm::omp::OMPD_tile, StartLoc, EndLoc,
5132  NumLoops) {
5133  setNumGeneratedLoops(3 * NumLoops);
5134  }
5135 
5136  void setPreInits(Stmt *PreInits) {
5137  Data->getChildren()[PreInitsOffset] = PreInits;
5138  }
5139 
5140  void setTransformedStmt(