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