StmtOpenMP.h revision 327952
1//===- StmtOpenMP.h - Classes for OpenMP directives  ------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9/// \file
10/// \brief This file defines OpenMP AST classes for executable directives and
11/// clauses.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_AST_STMTOPENMP_H
16#define LLVM_CLANG_AST_STMTOPENMP_H
17
18#include "clang/AST/Expr.h"
19#include "clang/AST/OpenMPClause.h"
20#include "clang/AST/Stmt.h"
21#include "clang/Basic/OpenMPKinds.h"
22#include "clang/Basic/SourceLocation.h"
23
24namespace clang {
25
26//===----------------------------------------------------------------------===//
27// AST classes for directives.
28//===----------------------------------------------------------------------===//
29
30/// \brief This is a basic class for representing single OpenMP executable
31/// directive.
32///
33class OMPExecutableDirective : public Stmt {
34  friend class ASTStmtReader;
35  /// \brief Kind of the directive.
36  OpenMPDirectiveKind Kind;
37  /// \brief Starting location of the directive (directive keyword).
38  SourceLocation StartLoc;
39  /// \brief Ending location of the directive.
40  SourceLocation EndLoc;
41  /// \brief Numbers of clauses.
42  const unsigned NumClauses;
43  /// \brief Number of child expressions/stmts.
44  const unsigned NumChildren;
45  /// \brief Offset from this to the start of clauses.
46  /// There are NumClauses pointers to clauses, they are followed by
47  /// NumChildren pointers to child stmts/exprs (if the directive type
48  /// requires an associated stmt, then it has to be the first of them).
49  const unsigned ClausesOffset;
50
51  /// \brief Get the clauses storage.
52  MutableArrayRef<OMPClause *> getClauses() {
53    OMPClause **ClauseStorage = reinterpret_cast<OMPClause **>(
54        reinterpret_cast<char *>(this) + ClausesOffset);
55    return MutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);
56  }
57
58protected:
59  /// \brief Build instance of directive of class \a K.
60  ///
61  /// \param SC Statement class.
62  /// \param K Kind of OpenMP directive.
63  /// \param StartLoc Starting location of the directive (directive keyword).
64  /// \param EndLoc Ending location of the directive.
65  ///
66  template <typename T>
67  OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K,
68                         SourceLocation StartLoc, SourceLocation EndLoc,
69                         unsigned NumClauses, unsigned NumChildren)
70      : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
71        EndLoc(std::move(EndLoc)), NumClauses(NumClauses),
72        NumChildren(NumChildren),
73        ClausesOffset(llvm::alignTo(sizeof(T), alignof(OMPClause *))) {}
74
75  /// \brief Sets the list of variables for this clause.
76  ///
77  /// \param Clauses The list of clauses for the directive.
78  ///
79  void setClauses(ArrayRef<OMPClause *> Clauses);
80
81  /// \brief Set the associated statement for the directive.
82  ///
83  /// /param S Associated statement.
84  ///
85  void setAssociatedStmt(Stmt *S) {
86    assert(hasAssociatedStmt() && "no associated statement.");
87    *child_begin() = S;
88  }
89
90public:
91  /// \brief Iterates over a filtered subrange of clauses applied to a
92  /// directive.
93  ///
94  /// This iterator visits only clauses of type SpecificClause.
95  template <typename SpecificClause>
96  class specific_clause_iterator
97      : public llvm::iterator_adaptor_base<
98            specific_clause_iterator<SpecificClause>,
99            ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag,
100            const SpecificClause *, ptrdiff_t, const SpecificClause *,
101            const SpecificClause *> {
102    ArrayRef<OMPClause *>::const_iterator End;
103
104    void SkipToNextClause() {
105      while (this->I != End && !isa<SpecificClause>(*this->I))
106        ++this->I;
107    }
108
109  public:
110    explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses)
111        : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()),
112          End(Clauses.end()) {
113      SkipToNextClause();
114    }
115
116    const SpecificClause *operator*() const {
117      return cast<SpecificClause>(*this->I);
118    }
119    const SpecificClause *operator->() const { return **this; }
120
121    specific_clause_iterator &operator++() {
122      ++this->I;
123      SkipToNextClause();
124      return *this;
125    }
126  };
127
128  template <typename SpecificClause>
129  static llvm::iterator_range<specific_clause_iterator<SpecificClause>>
130  getClausesOfKind(ArrayRef<OMPClause *> Clauses) {
131    return {specific_clause_iterator<SpecificClause>(Clauses),
132            specific_clause_iterator<SpecificClause>(
133                llvm::makeArrayRef(Clauses.end(), 0))};
134  }
135
136  template <typename SpecificClause>
137  llvm::iterator_range<specific_clause_iterator<SpecificClause>>
138  getClausesOfKind() const {
139    return getClausesOfKind<SpecificClause>(clauses());
140  }
141
142  /// Gets a single clause of the specified kind associated with the
143  /// current directive iff there is only one clause of this kind (and assertion
144  /// is fired if there is more than one clause is associated with the
145  /// directive). Returns nullptr if no clause of this kind is associated with
146  /// the directive.
147  template <typename SpecificClause>
148  const SpecificClause *getSingleClause() const {
149    auto Clauses = getClausesOfKind<SpecificClause>();
150
151    if (Clauses.begin() != Clauses.end()) {
152      assert(std::next(Clauses.begin()) == Clauses.end() &&
153             "There are at least 2 clauses of the specified kind");
154      return *Clauses.begin();
155    }
156    return nullptr;
157  }
158
159  /// Returns true if the current directive has one or more clauses of a
160  /// specific kind.
161  template <typename SpecificClause>
162  bool hasClausesOfKind() const {
163    auto Clauses = getClausesOfKind<SpecificClause>();
164    return Clauses.begin() != Clauses.end();
165  }
166
167  /// \brief Returns starting location of directive kind.
168  SourceLocation getLocStart() const { return StartLoc; }
169  /// \brief Returns ending location of directive.
170  SourceLocation getLocEnd() const { return EndLoc; }
171
172  /// \brief Set starting location of directive kind.
173  ///
174  /// \param Loc New starting location of directive.
175  ///
176  void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
177  /// \brief Set ending location of directive.
178  ///
179  /// \param Loc New ending location of directive.
180  ///
181  void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
182
183  /// \brief Get number of clauses.
184  unsigned getNumClauses() const { return NumClauses; }
185
186  /// \brief Returns specified clause.
187  ///
188  /// \param i Number of clause.
189  ///
190  OMPClause *getClause(unsigned i) const { return clauses()[i]; }
191
192  /// \brief Returns true if directive has associated statement.
193  bool hasAssociatedStmt() const { return NumChildren > 0; }
194
195  /// \brief Returns statement associated with the directive.
196  const Stmt *getAssociatedStmt() const {
197    assert(hasAssociatedStmt() && "no associated statement.");
198    return *child_begin();
199  }
200  Stmt *getAssociatedStmt() {
201    assert(hasAssociatedStmt() && "no associated statement.");
202    return *child_begin();
203  }
204
205  /// \brief Returns the captured statement associated with the
206  /// component region within the (combined) directive.
207  //
208  // \param RegionKind Component region kind.
209  const CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const {
210    SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
211    getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
212    assert(std::any_of(
213               CaptureRegions.begin(), CaptureRegions.end(),
214               [=](const OpenMPDirectiveKind K) { return K == RegionKind; }) &&
215           "RegionKind not found in OpenMP CaptureRegions.");
216    auto *CS = cast<CapturedStmt>(getAssociatedStmt());
217    for (auto ThisCaptureRegion : CaptureRegions) {
218      if (ThisCaptureRegion == RegionKind)
219        return CS;
220      CS = cast<CapturedStmt>(CS->getCapturedStmt());
221    }
222    llvm_unreachable("Incorrect RegionKind specified for directive.");
223  }
224
225  OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
226
227  static bool classof(const Stmt *S) {
228    return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
229           S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
230  }
231
232  child_range children() {
233    if (!hasAssociatedStmt())
234      return child_range(child_iterator(), child_iterator());
235    Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
236    return child_range(ChildStorage, ChildStorage + NumChildren);
237  }
238
239  ArrayRef<OMPClause *> clauses() { return getClauses(); }
240
241  ArrayRef<OMPClause *> clauses() const {
242    return const_cast<OMPExecutableDirective *>(this)->getClauses();
243  }
244};
245
246/// \brief This represents '#pragma omp parallel' directive.
247///
248/// \code
249/// #pragma omp parallel private(a,b) reduction(+: c,d)
250/// \endcode
251/// In this example directive '#pragma omp parallel' has clauses 'private'
252/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
253/// variables 'c' and 'd'.
254///
255class OMPParallelDirective : public OMPExecutableDirective {
256  friend class ASTStmtReader;
257  /// \brief true if the construct has inner cancel directive.
258  bool HasCancel;
259
260  /// \brief Build directive with the given start and end location.
261  ///
262  /// \param StartLoc Starting location of the directive (directive keyword).
263  /// \param EndLoc Ending Location of the directive.
264  ///
265  OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
266                       unsigned NumClauses)
267      : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
268                               StartLoc, EndLoc, NumClauses, 1),
269        HasCancel(false) {}
270
271  /// \brief Build an empty directive.
272  ///
273  /// \param NumClauses Number of clauses.
274  ///
275  explicit OMPParallelDirective(unsigned NumClauses)
276      : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
277                               SourceLocation(), SourceLocation(), NumClauses,
278                               1),
279        HasCancel(false) {}
280
281  /// \brief Set cancel state.
282  void setHasCancel(bool Has) { HasCancel = Has; }
283
284public:
285  /// \brief Creates directive with a list of \a Clauses.
286  ///
287  /// \param C AST context.
288  /// \param StartLoc Starting location of the directive kind.
289  /// \param EndLoc Ending Location of the directive.
290  /// \param Clauses List of clauses.
291  /// \param AssociatedStmt Statement associated with the directive.
292  /// \param HasCancel true if this directive has inner cancel directive.
293  ///
294  static OMPParallelDirective *
295  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
296         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
297
298  /// \brief Creates an empty directive with the place for \a N clauses.
299  ///
300  /// \param C AST context.
301  /// \param NumClauses Number of clauses.
302  ///
303  static OMPParallelDirective *CreateEmpty(const ASTContext &C,
304                                           unsigned NumClauses, EmptyShell);
305
306  /// \brief Return true if current directive has inner cancel directive.
307  bool hasCancel() const { return HasCancel; }
308
309  static bool classof(const Stmt *T) {
310    return T->getStmtClass() == OMPParallelDirectiveClass;
311  }
312};
313
314/// \brief This is a common base class for loop directives ('omp simd', 'omp
315/// for', 'omp for simd' etc.). It is responsible for the loop code generation.
316///
317class OMPLoopDirective : public OMPExecutableDirective {
318  friend class ASTStmtReader;
319  /// \brief Number of collapsed loops as specified by 'collapse' clause.
320  unsigned CollapsedNum;
321
322  /// \brief Offsets to the stored exprs.
323  /// This enumeration contains offsets to all the pointers to children
324  /// expressions stored in OMPLoopDirective.
325  /// The first 9 children are necessary for all the loop directives,
326  /// the next 8 are specific to the worksharing ones, and the next 11 are
327  /// used for combined constructs containing two pragmas associated to loops.
328  /// After the fixed children, three arrays of length CollapsedNum are
329  /// allocated: loop counters, their updates and final values.
330  /// PrevLowerBound and PrevUpperBound are used to communicate blocking
331  /// information in composite constructs which require loop blocking
332  /// DistInc is used to generate the increment expression for the distribute
333  /// loop when combined with a further nested loop
334  /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the
335  /// for loop when combined with a previous distribute loop in the same pragma
336  /// (e.g. 'distribute parallel for')
337  ///
338  enum {
339    AssociatedStmtOffset = 0,
340    IterationVariableOffset = 1,
341    LastIterationOffset = 2,
342    CalcLastIterationOffset = 3,
343    PreConditionOffset = 4,
344    CondOffset = 5,
345    InitOffset = 6,
346    IncOffset = 7,
347    PreInitsOffset = 8,
348    // The '...End' enumerators do not correspond to child expressions - they
349    // specify the offset to the end (and start of the following counters/
350    // updates/finals arrays).
351    DefaultEnd = 9,
352    // The following 8 exprs are used by worksharing and distribute loops only.
353    IsLastIterVariableOffset = 9,
354    LowerBoundVariableOffset = 10,
355    UpperBoundVariableOffset = 11,
356    StrideVariableOffset = 12,
357    EnsureUpperBoundOffset = 13,
358    NextLowerBoundOffset = 14,
359    NextUpperBoundOffset = 15,
360    NumIterationsOffset = 16,
361    // Offset to the end for worksharing loop directives.
362    WorksharingEnd = 17,
363    PrevLowerBoundVariableOffset = 17,
364    PrevUpperBoundVariableOffset = 18,
365    DistIncOffset = 19,
366    PrevEnsureUpperBoundOffset = 20,
367    CombinedLowerBoundVariableOffset = 21,
368    CombinedUpperBoundVariableOffset = 22,
369    CombinedEnsureUpperBoundOffset = 23,
370    CombinedInitOffset = 24,
371    CombinedConditionOffset = 25,
372    CombinedNextLowerBoundOffset = 26,
373    CombinedNextUpperBoundOffset = 27,
374    // Offset to the end (and start of the following counters/updates/finals
375    // arrays) for combined distribute loop directives.
376    CombinedDistributeEnd = 28,
377  };
378
379  /// \brief Get the counters storage.
380  MutableArrayRef<Expr *> getCounters() {
381    Expr **Storage = reinterpret_cast<Expr **>(
382        &(*(std::next(child_begin(), getArraysOffset(getDirectiveKind())))));
383    return MutableArrayRef<Expr *>(Storage, CollapsedNum);
384  }
385
386  /// \brief Get the private counters storage.
387  MutableArrayRef<Expr *> getPrivateCounters() {
388    Expr **Storage = reinterpret_cast<Expr **>(&*std::next(
389        child_begin(), getArraysOffset(getDirectiveKind()) + CollapsedNum));
390    return MutableArrayRef<Expr *>(Storage, CollapsedNum);
391  }
392
393  /// \brief Get the updates storage.
394  MutableArrayRef<Expr *> getInits() {
395    Expr **Storage = reinterpret_cast<Expr **>(
396        &*std::next(child_begin(),
397                    getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum));
398    return MutableArrayRef<Expr *>(Storage, CollapsedNum);
399  }
400
401  /// \brief Get the updates storage.
402  MutableArrayRef<Expr *> getUpdates() {
403    Expr **Storage = reinterpret_cast<Expr **>(
404        &*std::next(child_begin(),
405                    getArraysOffset(getDirectiveKind()) + 3 * CollapsedNum));
406    return MutableArrayRef<Expr *>(Storage, CollapsedNum);
407  }
408
409  /// \brief Get the final counter updates storage.
410  MutableArrayRef<Expr *> getFinals() {
411    Expr **Storage = reinterpret_cast<Expr **>(
412        &*std::next(child_begin(),
413                    getArraysOffset(getDirectiveKind()) + 4 * CollapsedNum));
414    return MutableArrayRef<Expr *>(Storage, CollapsedNum);
415  }
416
417protected:
418  /// \brief Build instance of loop directive of class \a Kind.
419  ///
420  /// \param SC Statement class.
421  /// \param Kind Kind of OpenMP directive.
422  /// \param StartLoc Starting location of the directive (directive keyword).
423  /// \param EndLoc Ending location of the directive.
424  /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
425  /// \param NumClauses Number of clauses.
426  /// \param NumSpecialChildren Number of additional directive-specific stmts.
427  ///
428  template <typename T>
429  OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind,
430                   SourceLocation StartLoc, SourceLocation EndLoc,
431                   unsigned CollapsedNum, unsigned NumClauses,
432                   unsigned NumSpecialChildren = 0)
433      : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses,
434                               numLoopChildren(CollapsedNum, Kind) +
435                                   NumSpecialChildren),
436        CollapsedNum(CollapsedNum) {}
437
438  /// \brief Offset to the start of children expression arrays.
439  static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
440    if (isOpenMPLoopBoundSharingDirective(Kind))
441      return CombinedDistributeEnd;
442    if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) ||
443        isOpenMPDistributeDirective(Kind))
444      return WorksharingEnd;
445    return DefaultEnd;
446  }
447
448  /// \brief Children number.
449  static unsigned numLoopChildren(unsigned CollapsedNum,
450                                  OpenMPDirectiveKind Kind) {
451    return getArraysOffset(Kind) + 5 * CollapsedNum; // Counters,
452                                                     // PrivateCounters, Inits,
453                                                     // Updates and Finals
454  }
455
456  void setIterationVariable(Expr *IV) {
457    *std::next(child_begin(), IterationVariableOffset) = IV;
458  }
459  void setLastIteration(Expr *LI) {
460    *std::next(child_begin(), LastIterationOffset) = LI;
461  }
462  void setCalcLastIteration(Expr *CLI) {
463    *std::next(child_begin(), CalcLastIterationOffset) = CLI;
464  }
465  void setPreCond(Expr *PC) {
466    *std::next(child_begin(), PreConditionOffset) = PC;
467  }
468  void setCond(Expr *Cond) {
469    *std::next(child_begin(), CondOffset) = Cond;
470  }
471  void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; }
472  void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; }
473  void setPreInits(Stmt *PreInits) {
474    *std::next(child_begin(), PreInitsOffset) = PreInits;
475  }
476  void setIsLastIterVariable(Expr *IL) {
477    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
478            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
479            isOpenMPDistributeDirective(getDirectiveKind())) &&
480           "expected worksharing loop directive");
481    *std::next(child_begin(), IsLastIterVariableOffset) = IL;
482  }
483  void setLowerBoundVariable(Expr *LB) {
484    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
485            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
486            isOpenMPDistributeDirective(getDirectiveKind())) &&
487           "expected worksharing loop directive");
488    *std::next(child_begin(), LowerBoundVariableOffset) = LB;
489  }
490  void setUpperBoundVariable(Expr *UB) {
491    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
492            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
493            isOpenMPDistributeDirective(getDirectiveKind())) &&
494           "expected worksharing loop directive");
495    *std::next(child_begin(), UpperBoundVariableOffset) = UB;
496  }
497  void setStrideVariable(Expr *ST) {
498    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
499            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
500            isOpenMPDistributeDirective(getDirectiveKind())) &&
501           "expected worksharing loop directive");
502    *std::next(child_begin(), StrideVariableOffset) = ST;
503  }
504  void setEnsureUpperBound(Expr *EUB) {
505    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
506            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
507            isOpenMPDistributeDirective(getDirectiveKind())) &&
508           "expected worksharing loop directive");
509    *std::next(child_begin(), EnsureUpperBoundOffset) = EUB;
510  }
511  void setNextLowerBound(Expr *NLB) {
512    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
513            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
514            isOpenMPDistributeDirective(getDirectiveKind())) &&
515           "expected worksharing loop directive");
516    *std::next(child_begin(), NextLowerBoundOffset) = NLB;
517  }
518  void setNextUpperBound(Expr *NUB) {
519    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
520            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
521            isOpenMPDistributeDirective(getDirectiveKind())) &&
522           "expected worksharing loop directive");
523    *std::next(child_begin(), NextUpperBoundOffset) = NUB;
524  }
525  void setNumIterations(Expr *NI) {
526    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
527            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
528            isOpenMPDistributeDirective(getDirectiveKind())) &&
529           "expected worksharing loop directive");
530    *std::next(child_begin(), NumIterationsOffset) = NI;
531  }
532  void setPrevLowerBoundVariable(Expr *PrevLB) {
533    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
534           "expected loop bound sharing directive");
535    *std::next(child_begin(), PrevLowerBoundVariableOffset) = PrevLB;
536  }
537  void setPrevUpperBoundVariable(Expr *PrevUB) {
538    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
539           "expected loop bound sharing directive");
540    *std::next(child_begin(), PrevUpperBoundVariableOffset) = PrevUB;
541  }
542  void setDistInc(Expr *DistInc) {
543    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
544           "expected loop bound sharing directive");
545    *std::next(child_begin(), DistIncOffset) = DistInc;
546  }
547  void setPrevEnsureUpperBound(Expr *PrevEUB) {
548    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
549           "expected loop bound sharing directive");
550    *std::next(child_begin(), PrevEnsureUpperBoundOffset) = PrevEUB;
551  }
552  void setCombinedLowerBoundVariable(Expr *CombLB) {
553    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
554           "expected loop bound sharing directive");
555    *std::next(child_begin(), CombinedLowerBoundVariableOffset) = CombLB;
556  }
557  void setCombinedUpperBoundVariable(Expr *CombUB) {
558    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
559           "expected loop bound sharing directive");
560    *std::next(child_begin(), CombinedUpperBoundVariableOffset) = CombUB;
561  }
562  void setCombinedEnsureUpperBound(Expr *CombEUB) {
563    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
564           "expected loop bound sharing directive");
565    *std::next(child_begin(), CombinedEnsureUpperBoundOffset) = CombEUB;
566  }
567  void setCombinedInit(Expr *CombInit) {
568    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
569           "expected loop bound sharing directive");
570    *std::next(child_begin(), CombinedInitOffset) = CombInit;
571  }
572  void setCombinedCond(Expr *CombCond) {
573    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
574           "expected loop bound sharing directive");
575    *std::next(child_begin(), CombinedConditionOffset) = CombCond;
576  }
577  void setCombinedNextLowerBound(Expr *CombNLB) {
578    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
579           "expected loop bound sharing directive");
580    *std::next(child_begin(), CombinedNextLowerBoundOffset) = CombNLB;
581  }
582  void setCombinedNextUpperBound(Expr *CombNUB) {
583    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
584           "expected loop bound sharing directive");
585    *std::next(child_begin(), CombinedNextUpperBoundOffset) = CombNUB;
586  }
587  void setCounters(ArrayRef<Expr *> A);
588  void setPrivateCounters(ArrayRef<Expr *> A);
589  void setInits(ArrayRef<Expr *> A);
590  void setUpdates(ArrayRef<Expr *> A);
591  void setFinals(ArrayRef<Expr *> A);
592
593public:
594  /// The expressions built to support OpenMP loops in combined/composite
595  /// pragmas (e.g. pragma omp distribute parallel for)
596  struct DistCombinedHelperExprs {
597    /// DistributeLowerBound - used when composing 'omp distribute' with
598    /// 'omp for' in a same construct.
599    Expr *LB;
600    /// DistributeUpperBound - used when composing 'omp distribute' with
601    /// 'omp for' in a same construct.
602    Expr *UB;
603    /// DistributeEnsureUpperBound - used when composing 'omp distribute'
604    ///  with 'omp for' in a same construct, EUB depends on DistUB
605    Expr *EUB;
606    /// Distribute loop iteration variable init used when composing 'omp
607    /// distribute'
608    ///  with 'omp for' in a same construct
609    Expr *Init;
610    /// Distribute Loop condition used when composing 'omp distribute'
611    ///  with 'omp for' in a same construct
612    Expr *Cond;
613    /// Update of LowerBound for statically sheduled omp loops for
614    /// outer loop in combined constructs (e.g. 'distribute parallel for')
615    Expr *NLB;
616    /// Update of UpperBound for statically sheduled omp loops for
617    /// outer loop in combined constructs (e.g. 'distribute parallel for')
618    Expr *NUB;
619  };
620
621  /// \brief The expressions built for the OpenMP loop CodeGen for the
622  /// whole collapsed loop nest.
623  struct HelperExprs {
624    /// \brief Loop iteration variable.
625    Expr *IterationVarRef;
626    /// \brief Loop last iteration number.
627    Expr *LastIteration;
628    /// \brief Loop number of iterations.
629    Expr *NumIterations;
630    /// \brief Calculation of last iteration.
631    Expr *CalcLastIteration;
632    /// \brief Loop pre-condition.
633    Expr *PreCond;
634    /// \brief Loop condition.
635    Expr *Cond;
636    /// \brief Loop iteration variable init.
637    Expr *Init;
638    /// \brief Loop increment.
639    Expr *Inc;
640    /// \brief IsLastIteration - local flag variable passed to runtime.
641    Expr *IL;
642    /// \brief LowerBound - local variable passed to runtime.
643    Expr *LB;
644    /// \brief UpperBound - local variable passed to runtime.
645    Expr *UB;
646    /// \brief Stride - local variable passed to runtime.
647    Expr *ST;
648    /// \brief EnsureUpperBound -- expression UB = min(UB, NumIterations).
649    Expr *EUB;
650    /// \brief Update of LowerBound for statically sheduled 'omp for' loops.
651    Expr *NLB;
652    /// \brief Update of UpperBound for statically sheduled 'omp for' loops.
653    Expr *NUB;
654    /// \brief PreviousLowerBound - local variable passed to runtime in the
655    /// enclosing schedule or null if that does not apply.
656    Expr *PrevLB;
657    /// \brief PreviousUpperBound - local variable passed to runtime in the
658    /// enclosing schedule or null if that does not apply.
659    Expr *PrevUB;
660    /// \brief DistInc - increment expression for distribute loop when found
661    /// combined with a further loop level (e.g. in 'distribute parallel for')
662    /// expression IV = IV + ST
663    Expr *DistInc;
664    /// \brief PrevEUB - expression similar to EUB but to be used when loop
665    /// scheduling uses PrevLB and PrevUB (e.g.  in 'distribute parallel for'
666    /// when ensuring that the UB is either the calculated UB by the runtime or
667    /// the end of the assigned distribute chunk)
668    /// expression UB = min (UB, PrevUB)
669    Expr *PrevEUB;
670    /// \brief Counters Loop counters.
671    SmallVector<Expr *, 4> Counters;
672    /// \brief PrivateCounters Loop counters.
673    SmallVector<Expr *, 4> PrivateCounters;
674    /// \brief Expressions for loop counters inits for CodeGen.
675    SmallVector<Expr *, 4> Inits;
676    /// \brief Expressions for loop counters update for CodeGen.
677    SmallVector<Expr *, 4> Updates;
678    /// \brief Final loop counter values for GodeGen.
679    SmallVector<Expr *, 4> Finals;
680    /// Init statement for all captured expressions.
681    Stmt *PreInits;
682
683    /// Expressions used when combining OpenMP loop pragmas
684    DistCombinedHelperExprs DistCombinedFields;
685
686    /// \brief Check if all the expressions are built (does not check the
687    /// worksharing ones).
688    bool builtAll() {
689      return IterationVarRef != nullptr && LastIteration != nullptr &&
690             NumIterations != nullptr && PreCond != nullptr &&
691             Cond != nullptr && Init != nullptr && Inc != nullptr;
692    }
693
694    /// \brief Initialize all the fields to null.
695    /// \param Size Number of elements in the counters/finals/updates arrays.
696    void clear(unsigned Size) {
697      IterationVarRef = nullptr;
698      LastIteration = nullptr;
699      CalcLastIteration = nullptr;
700      PreCond = nullptr;
701      Cond = nullptr;
702      Init = nullptr;
703      Inc = nullptr;
704      IL = nullptr;
705      LB = nullptr;
706      UB = nullptr;
707      ST = nullptr;
708      EUB = nullptr;
709      NLB = nullptr;
710      NUB = nullptr;
711      NumIterations = nullptr;
712      PrevLB = nullptr;
713      PrevUB = nullptr;
714      DistInc = nullptr;
715      PrevEUB = nullptr;
716      Counters.resize(Size);
717      PrivateCounters.resize(Size);
718      Inits.resize(Size);
719      Updates.resize(Size);
720      Finals.resize(Size);
721      for (unsigned i = 0; i < Size; ++i) {
722        Counters[i] = nullptr;
723        PrivateCounters[i] = nullptr;
724        Inits[i] = nullptr;
725        Updates[i] = nullptr;
726        Finals[i] = nullptr;
727      }
728      PreInits = nullptr;
729      DistCombinedFields.LB = nullptr;
730      DistCombinedFields.UB = nullptr;
731      DistCombinedFields.EUB = nullptr;
732      DistCombinedFields.Init = nullptr;
733      DistCombinedFields.Cond = nullptr;
734      DistCombinedFields.NLB = nullptr;
735      DistCombinedFields.NUB = nullptr;
736    }
737  };
738
739  /// \brief Get number of collapsed loops.
740  unsigned getCollapsedNumber() const { return CollapsedNum; }
741
742  Expr *getIterationVariable() const {
743    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
744        *std::next(child_begin(), IterationVariableOffset)));
745  }
746  Expr *getLastIteration() const {
747    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
748        *std::next(child_begin(), LastIterationOffset)));
749  }
750  Expr *getCalcLastIteration() const {
751    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
752        *std::next(child_begin(), CalcLastIterationOffset)));
753  }
754  Expr *getPreCond() const {
755    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
756        *std::next(child_begin(), PreConditionOffset)));
757  }
758  Expr *getCond() const {
759    return const_cast<Expr *>(
760        reinterpret_cast<const Expr *>(*std::next(child_begin(), CondOffset)));
761  }
762  Expr *getInit() const {
763    return const_cast<Expr *>(
764        reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset)));
765  }
766  Expr *getInc() const {
767    return const_cast<Expr *>(
768        reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset)));
769  }
770  const Stmt *getPreInits() const {
771    return *std::next(child_begin(), PreInitsOffset);
772  }
773  Stmt *getPreInits() { return *std::next(child_begin(), PreInitsOffset); }
774  Expr *getIsLastIterVariable() const {
775    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
776            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
777            isOpenMPDistributeDirective(getDirectiveKind())) &&
778           "expected worksharing loop directive");
779    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
780        *std::next(child_begin(), IsLastIterVariableOffset)));
781  }
782  Expr *getLowerBoundVariable() const {
783    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
784            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
785            isOpenMPDistributeDirective(getDirectiveKind())) &&
786           "expected worksharing loop directive");
787    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
788        *std::next(child_begin(), LowerBoundVariableOffset)));
789  }
790  Expr *getUpperBoundVariable() const {
791    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
792            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
793            isOpenMPDistributeDirective(getDirectiveKind())) &&
794           "expected worksharing loop directive");
795    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
796        *std::next(child_begin(), UpperBoundVariableOffset)));
797  }
798  Expr *getStrideVariable() const {
799    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
800            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
801            isOpenMPDistributeDirective(getDirectiveKind())) &&
802           "expected worksharing loop directive");
803    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
804        *std::next(child_begin(), StrideVariableOffset)));
805  }
806  Expr *getEnsureUpperBound() const {
807    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
808            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
809            isOpenMPDistributeDirective(getDirectiveKind())) &&
810           "expected worksharing loop directive");
811    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
812        *std::next(child_begin(), EnsureUpperBoundOffset)));
813  }
814  Expr *getNextLowerBound() const {
815    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
816            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
817            isOpenMPDistributeDirective(getDirectiveKind())) &&
818           "expected worksharing loop directive");
819    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
820        *std::next(child_begin(), NextLowerBoundOffset)));
821  }
822  Expr *getNextUpperBound() const {
823    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
824            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
825            isOpenMPDistributeDirective(getDirectiveKind())) &&
826           "expected worksharing loop directive");
827    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
828        *std::next(child_begin(), NextUpperBoundOffset)));
829  }
830  Expr *getNumIterations() const {
831    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
832            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
833            isOpenMPDistributeDirective(getDirectiveKind())) &&
834           "expected worksharing loop directive");
835    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
836        *std::next(child_begin(), NumIterationsOffset)));
837  }
838  Expr *getPrevLowerBoundVariable() const {
839    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
840           "expected loop bound sharing directive");
841    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
842        *std::next(child_begin(), PrevLowerBoundVariableOffset)));
843  }
844  Expr *getPrevUpperBoundVariable() const {
845    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
846           "expected loop bound sharing directive");
847    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
848        *std::next(child_begin(), PrevUpperBoundVariableOffset)));
849  }
850  Expr *getDistInc() const {
851    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
852           "expected loop bound sharing directive");
853    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
854        *std::next(child_begin(), DistIncOffset)));
855  }
856  Expr *getPrevEnsureUpperBound() const {
857    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
858           "expected loop bound sharing directive");
859    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
860        *std::next(child_begin(), PrevEnsureUpperBoundOffset)));
861  }
862  Expr *getCombinedLowerBoundVariable() const {
863    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
864           "expected loop bound sharing directive");
865    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
866        *std::next(child_begin(), CombinedLowerBoundVariableOffset)));
867  }
868  Expr *getCombinedUpperBoundVariable() const {
869    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
870           "expected loop bound sharing directive");
871    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
872        *std::next(child_begin(), CombinedUpperBoundVariableOffset)));
873  }
874  Expr *getCombinedEnsureUpperBound() const {
875    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
876           "expected loop bound sharing directive");
877    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
878        *std::next(child_begin(), CombinedEnsureUpperBoundOffset)));
879  }
880  Expr *getCombinedInit() const {
881    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
882           "expected loop bound sharing directive");
883    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
884        *std::next(child_begin(), CombinedInitOffset)));
885  }
886  Expr *getCombinedCond() const {
887    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
888           "expected loop bound sharing directive");
889    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
890        *std::next(child_begin(), CombinedConditionOffset)));
891  }
892  Expr *getCombinedNextLowerBound() const {
893    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
894           "expected loop bound sharing directive");
895    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
896        *std::next(child_begin(), CombinedNextLowerBoundOffset)));
897  }
898  Expr *getCombinedNextUpperBound() const {
899    assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
900           "expected loop bound sharing directive");
901    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
902        *std::next(child_begin(), CombinedNextUpperBoundOffset)));
903  }
904  const Stmt *getBody() const {
905    // This relies on the loop form is already checked by Sema.
906    const Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
907    while(const auto *CS = dyn_cast<CapturedStmt>(Body))
908      Body = CS->getCapturedStmt();
909    Body = cast<ForStmt>(Body)->getBody();
910    for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
911      Body = Body->IgnoreContainers();
912      Body = cast<ForStmt>(Body)->getBody();
913    }
914    return Body;
915  }
916
917  ArrayRef<Expr *> counters() { return getCounters(); }
918
919  ArrayRef<Expr *> counters() const {
920    return const_cast<OMPLoopDirective *>(this)->getCounters();
921  }
922
923  ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
924
925  ArrayRef<Expr *> private_counters() const {
926    return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
927  }
928
929  ArrayRef<Expr *> inits() { return getInits(); }
930
931  ArrayRef<Expr *> inits() const {
932    return const_cast<OMPLoopDirective *>(this)->getInits();
933  }
934
935  ArrayRef<Expr *> updates() { return getUpdates(); }
936
937  ArrayRef<Expr *> updates() const {
938    return const_cast<OMPLoopDirective *>(this)->getUpdates();
939  }
940
941  ArrayRef<Expr *> finals() { return getFinals(); }
942
943  ArrayRef<Expr *> finals() const {
944    return const_cast<OMPLoopDirective *>(this)->getFinals();
945  }
946
947  static bool classof(const Stmt *T) {
948    return T->getStmtClass() == OMPSimdDirectiveClass ||
949           T->getStmtClass() == OMPForDirectiveClass ||
950           T->getStmtClass() == OMPForSimdDirectiveClass ||
951           T->getStmtClass() == OMPParallelForDirectiveClass ||
952           T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
953           T->getStmtClass() == OMPTaskLoopDirectiveClass ||
954           T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
955           T->getStmtClass() == OMPDistributeDirectiveClass ||
956           T->getStmtClass() == OMPTargetParallelForDirectiveClass ||
957           T->getStmtClass() == OMPDistributeParallelForDirectiveClass ||
958           T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass ||
959           T->getStmtClass() == OMPDistributeSimdDirectiveClass ||
960           T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass ||
961           T->getStmtClass() == OMPTargetSimdDirectiveClass ||
962           T->getStmtClass() == OMPTeamsDistributeDirectiveClass ||
963           T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass ||
964           T->getStmtClass() ==
965               OMPTeamsDistributeParallelForSimdDirectiveClass ||
966           T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass ||
967           T->getStmtClass() ==
968               OMPTargetTeamsDistributeParallelForDirectiveClass ||
969           T->getStmtClass() ==
970               OMPTargetTeamsDistributeParallelForSimdDirectiveClass ||
971           T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass ||
972           T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
973  }
974};
975
976/// \brief This represents '#pragma omp simd' directive.
977///
978/// \code
979/// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
980/// \endcode
981/// In this example directive '#pragma omp simd' has clauses 'private'
982/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
983/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
984///
985class OMPSimdDirective : public OMPLoopDirective {
986  friend class ASTStmtReader;
987  /// \brief Build directive with the given start and end location.
988  ///
989  /// \param StartLoc Starting location of the directive kind.
990  /// \param EndLoc Ending location of the directive.
991  /// \param CollapsedNum Number of collapsed nested loops.
992  /// \param NumClauses Number of clauses.
993  ///
994  OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
995                   unsigned CollapsedNum, unsigned NumClauses)
996      : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
997                         EndLoc, CollapsedNum, NumClauses) {}
998
999  /// \brief Build an empty directive.
1000  ///
1001  /// \param CollapsedNum Number of collapsed nested loops.
1002  /// \param NumClauses Number of clauses.
1003  ///
1004  explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
1005      : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd,
1006                         SourceLocation(), SourceLocation(), CollapsedNum,
1007                         NumClauses) {}
1008
1009public:
1010  /// \brief Creates directive with a list of \a Clauses.
1011  ///
1012  /// \param C AST context.
1013  /// \param StartLoc Starting location of the directive kind.
1014  /// \param EndLoc Ending Location of the directive.
1015  /// \param CollapsedNum Number of collapsed loops.
1016  /// \param Clauses List of clauses.
1017  /// \param AssociatedStmt Statement, associated with the directive.
1018  /// \param Exprs Helper expressions for CodeGen.
1019  ///
1020  static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1021                                  SourceLocation EndLoc, unsigned CollapsedNum,
1022                                  ArrayRef<OMPClause *> Clauses,
1023                                  Stmt *AssociatedStmt,
1024                                  const HelperExprs &Exprs);
1025
1026  /// \brief Creates an empty directive with the place
1027  /// for \a NumClauses clauses.
1028  ///
1029  /// \param C AST context.
1030  /// \param CollapsedNum Number of collapsed nested loops.
1031  /// \param NumClauses Number of clauses.
1032  ///
1033  static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1034                                       unsigned CollapsedNum, EmptyShell);
1035
1036  static bool classof(const Stmt *T) {
1037    return T->getStmtClass() == OMPSimdDirectiveClass;
1038  }
1039};
1040
1041/// \brief This represents '#pragma omp for' directive.
1042///
1043/// \code
1044/// #pragma omp for private(a,b) reduction(+:c,d)
1045/// \endcode
1046/// In this example directive '#pragma omp for' has clauses 'private' with the
1047/// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
1048/// and 'd'.
1049///
1050class OMPForDirective : public OMPLoopDirective {
1051  friend class ASTStmtReader;
1052
1053  /// \brief true if current directive has inner cancel directive.
1054  bool HasCancel;
1055
1056  /// \brief Build directive with the given start and end location.
1057  ///
1058  /// \param StartLoc Starting location of the directive kind.
1059  /// \param EndLoc Ending location of the directive.
1060  /// \param CollapsedNum Number of collapsed nested loops.
1061  /// \param NumClauses Number of clauses.
1062  ///
1063  OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1064                  unsigned CollapsedNum, unsigned NumClauses)
1065      : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc,
1066                         CollapsedNum, NumClauses),
1067        HasCancel(false) {}
1068
1069  /// \brief Build an empty directive.
1070  ///
1071  /// \param CollapsedNum Number of collapsed nested loops.
1072  /// \param NumClauses Number of clauses.
1073  ///
1074  explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
1075      : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(),
1076                         SourceLocation(), CollapsedNum, NumClauses),
1077        HasCancel(false) {}
1078
1079  /// \brief Set cancel state.
1080  void setHasCancel(bool Has) { HasCancel = Has; }
1081
1082public:
1083  /// \brief Creates directive with a list of \a Clauses.
1084  ///
1085  /// \param C AST context.
1086  /// \param StartLoc Starting location of the directive kind.
1087  /// \param EndLoc Ending Location of the directive.
1088  /// \param CollapsedNum Number of collapsed loops.
1089  /// \param Clauses List of clauses.
1090  /// \param AssociatedStmt Statement, associated with the directive.
1091  /// \param Exprs Helper expressions for CodeGen.
1092  /// \param HasCancel true if current directive has inner cancel directive.
1093  ///
1094  static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1095                                 SourceLocation EndLoc, unsigned CollapsedNum,
1096                                 ArrayRef<OMPClause *> Clauses,
1097                                 Stmt *AssociatedStmt, const HelperExprs &Exprs,
1098                                 bool HasCancel);
1099
1100  /// \brief Creates an empty directive with the place
1101  /// for \a NumClauses clauses.
1102  ///
1103  /// \param C AST context.
1104  /// \param CollapsedNum Number of collapsed nested loops.
1105  /// \param NumClauses Number of clauses.
1106  ///
1107  static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1108                                      unsigned CollapsedNum, EmptyShell);
1109
1110  /// \brief Return true if current directive has inner cancel directive.
1111  bool hasCancel() const { return HasCancel; }
1112
1113  static bool classof(const Stmt *T) {
1114    return T->getStmtClass() == OMPForDirectiveClass;
1115  }
1116};
1117
1118/// \brief This represents '#pragma omp for simd' directive.
1119///
1120/// \code
1121/// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
1122/// \endcode
1123/// In this example directive '#pragma omp for simd' has clauses 'private'
1124/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
1125/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
1126///
1127class OMPForSimdDirective : public OMPLoopDirective {
1128  friend class ASTStmtReader;
1129  /// \brief Build directive with the given start and end location.
1130  ///
1131  /// \param StartLoc Starting location of the directive kind.
1132  /// \param EndLoc Ending location of the directive.
1133  /// \param CollapsedNum Number of collapsed nested loops.
1134  /// \param NumClauses Number of clauses.
1135  ///
1136  OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1137                      unsigned CollapsedNum, unsigned NumClauses)
1138      : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
1139                         StartLoc, EndLoc, CollapsedNum, NumClauses) {}
1140
1141  /// \brief Build an empty directive.
1142  ///
1143  /// \param CollapsedNum Number of collapsed nested loops.
1144  /// \param NumClauses Number of clauses.
1145  ///
1146  explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
1147      : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
1148                         SourceLocation(), SourceLocation(), CollapsedNum,
1149                         NumClauses) {}
1150
1151public:
1152  /// \brief Creates directive with a list of \a Clauses.
1153  ///
1154  /// \param C AST context.
1155  /// \param StartLoc Starting location of the directive kind.
1156  /// \param EndLoc Ending Location of the directive.
1157  /// \param CollapsedNum Number of collapsed loops.
1158  /// \param Clauses List of clauses.
1159  /// \param AssociatedStmt Statement, associated with the directive.
1160  /// \param Exprs Helper expressions for CodeGen.
1161  ///
1162  static OMPForSimdDirective *
1163  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1164         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1165         Stmt *AssociatedStmt, const HelperExprs &Exprs);
1166
1167  /// \brief Creates an empty directive with the place
1168  /// for \a NumClauses clauses.
1169  ///
1170  /// \param C AST context.
1171  /// \param CollapsedNum Number of collapsed nested loops.
1172  /// \param NumClauses Number of clauses.
1173  ///
1174  static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
1175                                          unsigned NumClauses,
1176                                          unsigned CollapsedNum, EmptyShell);
1177
1178  static bool classof(const Stmt *T) {
1179    return T->getStmtClass() == OMPForSimdDirectiveClass;
1180  }
1181};
1182
1183/// \brief This represents '#pragma omp sections' directive.
1184///
1185/// \code
1186/// #pragma omp sections private(a,b) reduction(+:c,d)
1187/// \endcode
1188/// In this example directive '#pragma omp sections' has clauses 'private' with
1189/// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
1190/// 'c' and 'd'.
1191///
1192class OMPSectionsDirective : public OMPExecutableDirective {
1193  friend class ASTStmtReader;
1194
1195  /// \brief true if current directive has inner cancel directive.
1196  bool HasCancel;
1197
1198  /// \brief Build directive with the given start and end location.
1199  ///
1200  /// \param StartLoc Starting location of the directive kind.
1201  /// \param EndLoc Ending location of the directive.
1202  /// \param NumClauses Number of clauses.
1203  ///
1204  OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1205                       unsigned NumClauses)
1206      : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
1207                               StartLoc, EndLoc, NumClauses, 1),
1208        HasCancel(false) {}
1209
1210  /// \brief Build an empty directive.
1211  ///
1212  /// \param NumClauses Number of clauses.
1213  ///
1214  explicit OMPSectionsDirective(unsigned NumClauses)
1215      : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
1216                               SourceLocation(), SourceLocation(), NumClauses,
1217                               1),
1218        HasCancel(false) {}
1219
1220  /// \brief Set cancel state.
1221  void setHasCancel(bool Has) { HasCancel = Has; }
1222
1223public:
1224  /// \brief Creates directive with a list of \a Clauses.
1225  ///
1226  /// \param C AST context.
1227  /// \param StartLoc Starting location of the directive kind.
1228  /// \param EndLoc Ending Location of the directive.
1229  /// \param Clauses List of clauses.
1230  /// \param AssociatedStmt Statement, associated with the directive.
1231  /// \param HasCancel true if current directive has inner directive.
1232  ///
1233  static OMPSectionsDirective *
1234  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1235         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
1236
1237  /// \brief Creates an empty directive with the place for \a NumClauses
1238  /// clauses.
1239  ///
1240  /// \param C AST context.
1241  /// \param NumClauses Number of clauses.
1242  ///
1243  static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
1244                                           unsigned NumClauses, EmptyShell);
1245
1246  /// \brief Return true if current directive has inner cancel directive.
1247  bool hasCancel() const { return HasCancel; }
1248
1249  static bool classof(const Stmt *T) {
1250    return T->getStmtClass() == OMPSectionsDirectiveClass;
1251  }
1252};
1253
1254/// \brief This represents '#pragma omp section' directive.
1255///
1256/// \code
1257/// #pragma omp section
1258/// \endcode
1259///
1260class OMPSectionDirective : public OMPExecutableDirective {
1261  friend class ASTStmtReader;
1262
1263  /// \brief true if current directive has inner cancel directive.
1264  bool HasCancel;
1265
1266  /// \brief Build directive with the given start and end location.
1267  ///
1268  /// \param StartLoc Starting location of the directive kind.
1269  /// \param EndLoc Ending location of the directive.
1270  ///
1271  OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1272      : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
1273                               StartLoc, EndLoc, 0, 1),
1274        HasCancel(false) {}
1275
1276  /// \brief Build an empty directive.
1277  ///
1278  explicit OMPSectionDirective()
1279      : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
1280                               SourceLocation(), SourceLocation(), 0, 1),
1281        HasCancel(false) {}
1282
1283public:
1284  /// \brief Creates directive.
1285  ///
1286  /// \param C AST context.
1287  /// \param StartLoc Starting location of the directive kind.
1288  /// \param EndLoc Ending Location of the directive.
1289  /// \param AssociatedStmt Statement, associated with the directive.
1290  /// \param HasCancel true if current directive has inner directive.
1291  ///
1292  static OMPSectionDirective *Create(const ASTContext &C,
1293                                     SourceLocation StartLoc,
1294                                     SourceLocation EndLoc,
1295                                     Stmt *AssociatedStmt, bool HasCancel);
1296
1297  /// \brief Creates an empty directive.
1298  ///
1299  /// \param C AST context.
1300  ///
1301  static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1302
1303  /// \brief Set cancel state.
1304  void setHasCancel(bool Has) { HasCancel = Has; }
1305
1306  /// \brief Return true if current directive has inner cancel directive.
1307  bool hasCancel() const { return HasCancel; }
1308
1309  static bool classof(const Stmt *T) {
1310    return T->getStmtClass() == OMPSectionDirectiveClass;
1311  }
1312};
1313
1314/// \brief This represents '#pragma omp single' directive.
1315///
1316/// \code
1317/// #pragma omp single private(a,b) copyprivate(c,d)
1318/// \endcode
1319/// In this example directive '#pragma omp single' has clauses 'private' with
1320/// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
1321///
1322class OMPSingleDirective : public OMPExecutableDirective {
1323  friend class ASTStmtReader;
1324  /// \brief Build directive with the given start and end location.
1325  ///
1326  /// \param StartLoc Starting location of the directive kind.
1327  /// \param EndLoc Ending location of the directive.
1328  /// \param NumClauses Number of clauses.
1329  ///
1330  OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1331                     unsigned NumClauses)
1332      : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
1333                               StartLoc, EndLoc, NumClauses, 1) {}
1334
1335  /// \brief Build an empty directive.
1336  ///
1337  /// \param NumClauses Number of clauses.
1338  ///
1339  explicit OMPSingleDirective(unsigned NumClauses)
1340      : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
1341                               SourceLocation(), SourceLocation(), NumClauses,
1342                               1) {}
1343
1344public:
1345  /// \brief Creates directive with a list of \a Clauses.
1346  ///
1347  /// \param C AST context.
1348  /// \param StartLoc Starting location of the directive kind.
1349  /// \param EndLoc Ending Location of the directive.
1350  /// \param Clauses List of clauses.
1351  /// \param AssociatedStmt Statement, associated with the directive.
1352  ///
1353  static OMPSingleDirective *
1354  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1355         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1356
1357  /// \brief Creates an empty directive with the place for \a NumClauses
1358  /// clauses.
1359  ///
1360  /// \param C AST context.
1361  /// \param NumClauses Number of clauses.
1362  ///
1363  static OMPSingleDirective *CreateEmpty(const ASTContext &C,
1364                                         unsigned NumClauses, EmptyShell);
1365
1366  static bool classof(const Stmt *T) {
1367    return T->getStmtClass() == OMPSingleDirectiveClass;
1368  }
1369};
1370
1371/// \brief This represents '#pragma omp master' directive.
1372///
1373/// \code
1374/// #pragma omp master
1375/// \endcode
1376///
1377class OMPMasterDirective : public OMPExecutableDirective {
1378  friend class ASTStmtReader;
1379  /// \brief Build directive with the given start and end location.
1380  ///
1381  /// \param StartLoc Starting location of the directive kind.
1382  /// \param EndLoc Ending location of the directive.
1383  ///
1384  OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1385      : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
1386                               StartLoc, EndLoc, 0, 1) {}
1387
1388  /// \brief Build an empty directive.
1389  ///
1390  explicit OMPMasterDirective()
1391      : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
1392                               SourceLocation(), SourceLocation(), 0, 1) {}
1393
1394public:
1395  /// \brief Creates directive.
1396  ///
1397  /// \param C AST context.
1398  /// \param StartLoc Starting location of the directive kind.
1399  /// \param EndLoc Ending Location of the directive.
1400  /// \param AssociatedStmt Statement, associated with the directive.
1401  ///
1402  static OMPMasterDirective *Create(const ASTContext &C,
1403                                    SourceLocation StartLoc,
1404                                    SourceLocation EndLoc,
1405                                    Stmt *AssociatedStmt);
1406
1407  /// \brief Creates an empty directive.
1408  ///
1409  /// \param C AST context.
1410  ///
1411  static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1412
1413  static bool classof(const Stmt *T) {
1414    return T->getStmtClass() == OMPMasterDirectiveClass;
1415  }
1416};
1417
1418/// \brief This represents '#pragma omp critical' directive.
1419///
1420/// \code
1421/// #pragma omp critical
1422/// \endcode
1423///
1424class OMPCriticalDirective : public OMPExecutableDirective {
1425  friend class ASTStmtReader;
1426  /// \brief Name of the directive.
1427  DeclarationNameInfo DirName;
1428  /// \brief Build directive with the given start and end location.
1429  ///
1430  /// \param Name Name of the directive.
1431  /// \param StartLoc Starting location of the directive kind.
1432  /// \param EndLoc Ending location of the directive.
1433  /// \param NumClauses Number of clauses.
1434  ///
1435  OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
1436                       SourceLocation EndLoc, unsigned NumClauses)
1437      : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
1438                               StartLoc, EndLoc, NumClauses, 1),
1439        DirName(Name) {}
1440
1441  /// \brief Build an empty directive.
1442  ///
1443  /// \param NumClauses Number of clauses.
1444  ///
1445  explicit OMPCriticalDirective(unsigned NumClauses)
1446      : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
1447                               SourceLocation(), SourceLocation(), NumClauses,
1448                               1),
1449        DirName() {}
1450
1451  /// \brief Set name of the directive.
1452  ///
1453  /// \param Name Name of the directive.
1454  ///
1455  void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
1456
1457public:
1458  /// \brief Creates directive.
1459  ///
1460  /// \param C AST context.
1461  /// \param Name Name of the directive.
1462  /// \param StartLoc Starting location of the directive kind.
1463  /// \param EndLoc Ending Location of the directive.
1464  /// \param Clauses List of clauses.
1465  /// \param AssociatedStmt Statement, associated with the directive.
1466  ///
1467  static OMPCriticalDirective *
1468  Create(const ASTContext &C, const DeclarationNameInfo &Name,
1469         SourceLocation StartLoc, SourceLocation EndLoc,
1470         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1471
1472  /// \brief Creates an empty directive.
1473  ///
1474  /// \param C AST context.
1475  /// \param NumClauses Number of clauses.
1476  ///
1477  static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
1478                                           unsigned NumClauses, EmptyShell);
1479
1480  /// \brief Return name of the directive.
1481  ///
1482  DeclarationNameInfo getDirectiveName() const { return DirName; }
1483
1484  static bool classof(const Stmt *T) {
1485    return T->getStmtClass() == OMPCriticalDirectiveClass;
1486  }
1487};
1488
1489/// \brief This represents '#pragma omp parallel for' directive.
1490///
1491/// \code
1492/// #pragma omp parallel for private(a,b) reduction(+:c,d)
1493/// \endcode
1494/// In this example directive '#pragma omp parallel for' has clauses 'private'
1495/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
1496/// variables 'c' and 'd'.
1497///
1498class OMPParallelForDirective : public OMPLoopDirective {
1499  friend class ASTStmtReader;
1500
1501  /// \brief true if current region has inner cancel directive.
1502  bool HasCancel;
1503
1504  /// \brief Build directive with the given start and end location.
1505  ///
1506  /// \param StartLoc Starting location of the directive kind.
1507  /// \param EndLoc Ending location of the directive.
1508  /// \param CollapsedNum Number of collapsed nested loops.
1509  /// \param NumClauses Number of clauses.
1510  ///
1511  OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1512                          unsigned CollapsedNum, unsigned NumClauses)
1513      : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
1514                         StartLoc, EndLoc, CollapsedNum, NumClauses),
1515        HasCancel(false) {}
1516
1517  /// \brief Build an empty directive.
1518  ///
1519  /// \param CollapsedNum Number of collapsed nested loops.
1520  /// \param NumClauses Number of clauses.
1521  ///
1522  explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
1523      : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
1524                         SourceLocation(), SourceLocation(), CollapsedNum,
1525                         NumClauses),
1526        HasCancel(false) {}
1527
1528  /// \brief Set cancel state.
1529  void setHasCancel(bool Has) { HasCancel = Has; }
1530
1531public:
1532  /// \brief Creates directive with a list of \a Clauses.
1533  ///
1534  /// \param C AST context.
1535  /// \param StartLoc Starting location of the directive kind.
1536  /// \param EndLoc Ending Location of the directive.
1537  /// \param CollapsedNum Number of collapsed loops.
1538  /// \param Clauses List of clauses.
1539  /// \param AssociatedStmt Statement, associated with the directive.
1540  /// \param Exprs Helper expressions for CodeGen.
1541  /// \param HasCancel true if current directive has inner cancel directive.
1542  ///
1543  static OMPParallelForDirective *
1544  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1545         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1546         Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
1547
1548  /// \brief Creates an empty directive with the place
1549  /// for \a NumClauses clauses.
1550  ///
1551  /// \param C AST context.
1552  /// \param CollapsedNum Number of collapsed nested loops.
1553  /// \param NumClauses Number of clauses.
1554  ///
1555  static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
1556                                              unsigned NumClauses,
1557                                              unsigned CollapsedNum,
1558                                              EmptyShell);
1559
1560  /// \brief Return true if current directive has inner cancel directive.
1561  bool hasCancel() const { return HasCancel; }
1562
1563  static bool classof(const Stmt *T) {
1564    return T->getStmtClass() == OMPParallelForDirectiveClass;
1565  }
1566};
1567
1568/// \brief This represents '#pragma omp parallel for simd' directive.
1569///
1570/// \code
1571/// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
1572/// \endcode
1573/// In this example directive '#pragma omp parallel for simd' has clauses
1574/// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
1575/// and linear step 's', 'reduction' with operator '+' and variables 'c' and
1576/// 'd'.
1577///
1578class OMPParallelForSimdDirective : public OMPLoopDirective {
1579  friend class ASTStmtReader;
1580  /// \brief Build directive with the given start and end location.
1581  ///
1582  /// \param StartLoc Starting location of the directive kind.
1583  /// \param EndLoc Ending location of the directive.
1584  /// \param CollapsedNum Number of collapsed nested loops.
1585  /// \param NumClauses Number of clauses.
1586  ///
1587  OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1588                              unsigned CollapsedNum, unsigned NumClauses)
1589      : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
1590                         OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum,
1591                         NumClauses) {}
1592
1593  /// \brief Build an empty directive.
1594  ///
1595  /// \param CollapsedNum Number of collapsed nested loops.
1596  /// \param NumClauses Number of clauses.
1597  ///
1598  explicit OMPParallelForSimdDirective(unsigned CollapsedNum,
1599                                       unsigned NumClauses)
1600      : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
1601                         OMPD_parallel_for_simd, SourceLocation(),
1602                         SourceLocation(), CollapsedNum, NumClauses) {}
1603
1604public:
1605  /// \brief Creates directive with a list of \a Clauses.
1606  ///
1607  /// \param C AST context.
1608  /// \param StartLoc Starting location of the directive kind.
1609  /// \param EndLoc Ending Location of the directive.
1610  /// \param CollapsedNum Number of collapsed loops.
1611  /// \param Clauses List of clauses.
1612  /// \param AssociatedStmt Statement, associated with the directive.
1613  /// \param Exprs Helper expressions for CodeGen.
1614  ///
1615  static OMPParallelForSimdDirective *
1616  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1617         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1618         Stmt *AssociatedStmt, const HelperExprs &Exprs);
1619
1620  /// \brief Creates an empty directive with the place
1621  /// for \a NumClauses clauses.
1622  ///
1623  /// \param C AST context.
1624  /// \param CollapsedNum Number of collapsed nested loops.
1625  /// \param NumClauses Number of clauses.
1626  ///
1627  static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
1628                                                  unsigned NumClauses,
1629                                                  unsigned CollapsedNum,
1630                                                  EmptyShell);
1631
1632  static bool classof(const Stmt *T) {
1633    return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
1634  }
1635};
1636
1637/// \brief This represents '#pragma omp parallel sections' directive.
1638///
1639/// \code
1640/// #pragma omp parallel sections private(a,b) reduction(+:c,d)
1641/// \endcode
1642/// In this example directive '#pragma omp parallel sections' has clauses
1643/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
1644/// and variables 'c' and 'd'.
1645///
1646class OMPParallelSectionsDirective : public OMPExecutableDirective {
1647  friend class ASTStmtReader;
1648
1649  /// \brief true if current directive has inner cancel directive.
1650  bool HasCancel;
1651
1652  /// \brief Build directive with the given start and end location.
1653  ///
1654  /// \param StartLoc Starting location of the directive kind.
1655  /// \param EndLoc Ending location of the directive.
1656  /// \param NumClauses Number of clauses.
1657  ///
1658  OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1659                               unsigned NumClauses)
1660      : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
1661                               OMPD_parallel_sections, StartLoc, EndLoc,
1662                               NumClauses, 1),
1663        HasCancel(false) {}
1664
1665  /// \brief Build an empty directive.
1666  ///
1667  /// \param NumClauses Number of clauses.
1668  ///
1669  explicit OMPParallelSectionsDirective(unsigned NumClauses)
1670      : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
1671                               OMPD_parallel_sections, SourceLocation(),
1672                               SourceLocation(), NumClauses, 1),
1673        HasCancel(false) {}
1674
1675  /// \brief Set cancel state.
1676  void setHasCancel(bool Has) { HasCancel = Has; }
1677
1678public:
1679  /// \brief Creates directive with a list of \a Clauses.
1680  ///
1681  /// \param C AST context.
1682  /// \param StartLoc Starting location of the directive kind.
1683  /// \param EndLoc Ending Location of the directive.
1684  /// \param Clauses List of clauses.
1685  /// \param AssociatedStmt Statement, associated with the directive.
1686  /// \param HasCancel true if current directive has inner cancel directive.
1687  ///
1688  static OMPParallelSectionsDirective *
1689  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1690         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
1691
1692  /// \brief Creates an empty directive with the place for \a NumClauses
1693  /// clauses.
1694  ///
1695  /// \param C AST context.
1696  /// \param NumClauses Number of clauses.
1697  ///
1698  static OMPParallelSectionsDirective *
1699  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
1700
1701  /// \brief Return true if current directive has inner cancel directive.
1702  bool hasCancel() const { return HasCancel; }
1703
1704  static bool classof(const Stmt *T) {
1705    return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
1706  }
1707};
1708
1709/// \brief This represents '#pragma omp task' directive.
1710///
1711/// \code
1712/// #pragma omp task private(a,b) final(d)
1713/// \endcode
1714/// In this example directive '#pragma omp task' has clauses 'private' with the
1715/// variables 'a' and 'b' and 'final' with condition 'd'.
1716///
1717class OMPTaskDirective : public OMPExecutableDirective {
1718  friend class ASTStmtReader;
1719  /// \brief true if this directive has inner cancel directive.
1720  bool HasCancel;
1721
1722  /// \brief Build directive with the given start and end location.
1723  ///
1724  /// \param StartLoc Starting location of the directive kind.
1725  /// \param EndLoc Ending location of the directive.
1726  /// \param NumClauses Number of clauses.
1727  ///
1728  OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1729                   unsigned NumClauses)
1730      : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
1731                               EndLoc, NumClauses, 1),
1732        HasCancel(false) {}
1733
1734  /// \brief Build an empty directive.
1735  ///
1736  /// \param NumClauses Number of clauses.
1737  ///
1738  explicit OMPTaskDirective(unsigned NumClauses)
1739      : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
1740                               SourceLocation(), SourceLocation(), NumClauses,
1741                               1),
1742        HasCancel(false) {}
1743
1744  /// \brief Set cancel state.
1745  void setHasCancel(bool Has) { HasCancel = Has; }
1746
1747public:
1748  /// \brief Creates directive with a list of \a Clauses.
1749  ///
1750  /// \param C AST context.
1751  /// \param StartLoc Starting location of the directive kind.
1752  /// \param EndLoc Ending Location of the directive.
1753  /// \param Clauses List of clauses.
1754  /// \param AssociatedStmt Statement, associated with the directive.
1755  /// \param HasCancel true, if current directive has inner cancel directive.
1756  ///
1757  static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1758                                  SourceLocation EndLoc,
1759                                  ArrayRef<OMPClause *> Clauses,
1760                                  Stmt *AssociatedStmt, bool HasCancel);
1761
1762  /// \brief Creates an empty directive with the place for \a NumClauses
1763  /// clauses.
1764  ///
1765  /// \param C AST context.
1766  /// \param NumClauses Number of clauses.
1767  ///
1768  static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1769                                       EmptyShell);
1770
1771  /// \brief Return true if current directive has inner cancel directive.
1772  bool hasCancel() const { return HasCancel; }
1773
1774  static bool classof(const Stmt *T) {
1775    return T->getStmtClass() == OMPTaskDirectiveClass;
1776  }
1777};
1778
1779/// \brief This represents '#pragma omp taskyield' directive.
1780///
1781/// \code
1782/// #pragma omp taskyield
1783/// \endcode
1784///
1785class OMPTaskyieldDirective : public OMPExecutableDirective {
1786  friend class ASTStmtReader;
1787  /// \brief Build directive with the given start and end location.
1788  ///
1789  /// \param StartLoc Starting location of the directive kind.
1790  /// \param EndLoc Ending location of the directive.
1791  ///
1792  OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1793      : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
1794                               StartLoc, EndLoc, 0, 0) {}
1795
1796  /// \brief Build an empty directive.
1797  ///
1798  explicit OMPTaskyieldDirective()
1799      : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
1800                               SourceLocation(), SourceLocation(), 0, 0) {}
1801
1802public:
1803  /// \brief Creates directive.
1804  ///
1805  /// \param C AST context.
1806  /// \param StartLoc Starting location of the directive kind.
1807  /// \param EndLoc Ending Location of the directive.
1808  ///
1809  static OMPTaskyieldDirective *
1810  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1811
1812  /// \brief Creates an empty directive.
1813  ///
1814  /// \param C AST context.
1815  ///
1816  static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1817
1818  static bool classof(const Stmt *T) {
1819    return T->getStmtClass() == OMPTaskyieldDirectiveClass;
1820  }
1821};
1822
1823/// \brief This represents '#pragma omp barrier' directive.
1824///
1825/// \code
1826/// #pragma omp barrier
1827/// \endcode
1828///
1829class OMPBarrierDirective : public OMPExecutableDirective {
1830  friend class ASTStmtReader;
1831  /// \brief Build directive with the given start and end location.
1832  ///
1833  /// \param StartLoc Starting location of the directive kind.
1834  /// \param EndLoc Ending location of the directive.
1835  ///
1836  OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1837      : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
1838                               StartLoc, EndLoc, 0, 0) {}
1839
1840  /// \brief Build an empty directive.
1841  ///
1842  explicit OMPBarrierDirective()
1843      : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
1844                               SourceLocation(), SourceLocation(), 0, 0) {}
1845
1846public:
1847  /// \brief Creates directive.
1848  ///
1849  /// \param C AST context.
1850  /// \param StartLoc Starting location of the directive kind.
1851  /// \param EndLoc Ending Location of the directive.
1852  ///
1853  static OMPBarrierDirective *
1854  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1855
1856  /// \brief Creates an empty directive.
1857  ///
1858  /// \param C AST context.
1859  ///
1860  static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1861
1862  static bool classof(const Stmt *T) {
1863    return T->getStmtClass() == OMPBarrierDirectiveClass;
1864  }
1865};
1866
1867/// \brief This represents '#pragma omp taskwait' directive.
1868///
1869/// \code
1870/// #pragma omp taskwait
1871/// \endcode
1872///
1873class OMPTaskwaitDirective : public OMPExecutableDirective {
1874  friend class ASTStmtReader;
1875  /// \brief Build directive with the given start and end location.
1876  ///
1877  /// \param StartLoc Starting location of the directive kind.
1878  /// \param EndLoc Ending location of the directive.
1879  ///
1880  OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1881      : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
1882                               StartLoc, EndLoc, 0, 0) {}
1883
1884  /// \brief Build an empty directive.
1885  ///
1886  explicit OMPTaskwaitDirective()
1887      : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
1888                               SourceLocation(), SourceLocation(), 0, 0) {}
1889
1890public:
1891  /// \brief Creates directive.
1892  ///
1893  /// \param C AST context.
1894  /// \param StartLoc Starting location of the directive kind.
1895  /// \param EndLoc Ending Location of the directive.
1896  ///
1897  static OMPTaskwaitDirective *
1898  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1899
1900  /// \brief Creates an empty directive.
1901  ///
1902  /// \param C AST context.
1903  ///
1904  static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1905
1906  static bool classof(const Stmt *T) {
1907    return T->getStmtClass() == OMPTaskwaitDirectiveClass;
1908  }
1909};
1910
1911/// This represents '#pragma omp taskgroup' directive.
1912///
1913/// \code
1914/// #pragma omp taskgroup
1915/// \endcode
1916///
1917class OMPTaskgroupDirective : public OMPExecutableDirective {
1918  friend class ASTStmtReader;
1919  /// Build directive with the given start and end location.
1920  ///
1921  /// \param StartLoc Starting location of the directive kind.
1922  /// \param EndLoc Ending location of the directive.
1923  /// \param NumClauses Number of clauses.
1924  ///
1925  OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1926                        unsigned NumClauses)
1927      : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
1928                               StartLoc, EndLoc, NumClauses, 2) {}
1929
1930  /// Build an empty directive.
1931  /// \param NumClauses Number of clauses.
1932  ///
1933  explicit OMPTaskgroupDirective(unsigned NumClauses)
1934      : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
1935                               SourceLocation(), SourceLocation(), NumClauses,
1936                               2) {}
1937
1938  /// Sets the task_reduction return variable.
1939  void setReductionRef(Expr *RR) {
1940    *std::next(child_begin(), 1) = RR;
1941  }
1942
1943public:
1944  /// Creates directive.
1945  ///
1946  /// \param C AST context.
1947  /// \param StartLoc Starting location of the directive kind.
1948  /// \param EndLoc Ending Location of the directive.
1949  /// \param Clauses List of clauses.
1950  /// \param AssociatedStmt Statement, associated with the directive.
1951  /// \param ReductionRef Reference to the task_reduction return variable.
1952  ///
1953  static OMPTaskgroupDirective *
1954  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1955         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
1956         Expr *ReductionRef);
1957
1958  /// Creates an empty directive.
1959  ///
1960  /// \param C AST context.
1961  /// \param NumClauses Number of clauses.
1962  ///
1963  static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C,
1964                                            unsigned NumClauses, EmptyShell);
1965
1966
1967  /// Returns reference to the task_reduction return variable.
1968  const Expr *getReductionRef() const {
1969    return static_cast<const Expr *>(*std::next(child_begin(), 1));
1970  }
1971  Expr *getReductionRef() {
1972    return static_cast<Expr *>(*std::next(child_begin(), 1));
1973  }
1974
1975  static bool classof(const Stmt *T) {
1976    return T->getStmtClass() == OMPTaskgroupDirectiveClass;
1977  }
1978};
1979
1980/// \brief This represents '#pragma omp flush' directive.
1981///
1982/// \code
1983/// #pragma omp flush(a,b)
1984/// \endcode
1985/// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
1986/// and 'b'.
1987/// 'omp flush' directive does not have clauses but have an optional list of
1988/// variables to flush. This list of variables is stored within some fake clause
1989/// FlushClause.
1990class OMPFlushDirective : public OMPExecutableDirective {
1991  friend class ASTStmtReader;
1992  /// \brief Build directive with the given start and end location.
1993  ///
1994  /// \param StartLoc Starting location of the directive kind.
1995  /// \param EndLoc Ending location of the directive.
1996  /// \param NumClauses Number of clauses.
1997  ///
1998  OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1999                    unsigned NumClauses)
2000      : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
2001                               StartLoc, EndLoc, NumClauses, 0) {}
2002
2003  /// \brief Build an empty directive.
2004  ///
2005  /// \param NumClauses Number of clauses.
2006  ///
2007  explicit OMPFlushDirective(unsigned NumClauses)
2008      : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
2009                               SourceLocation(), SourceLocation(), NumClauses,
2010                               0) {}
2011
2012public:
2013  /// \brief Creates directive with a list of \a Clauses.
2014  ///
2015  /// \param C AST context.
2016  /// \param StartLoc Starting location of the directive kind.
2017  /// \param EndLoc Ending Location of the directive.
2018  /// \param Clauses List of clauses (only single OMPFlushClause clause is
2019  /// allowed).
2020  ///
2021  static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2022                                   SourceLocation EndLoc,
2023                                   ArrayRef<OMPClause *> Clauses);
2024
2025  /// \brief Creates an empty directive with the place for \a NumClauses
2026  /// clauses.
2027  ///
2028  /// \param C AST context.
2029  /// \param NumClauses Number of clauses.
2030  ///
2031  static OMPFlushDirective *CreateEmpty(const ASTContext &C,
2032                                        unsigned NumClauses, EmptyShell);
2033
2034  static bool classof(const Stmt *T) {
2035    return T->getStmtClass() == OMPFlushDirectiveClass;
2036  }
2037};
2038
2039/// \brief This represents '#pragma omp ordered' directive.
2040///
2041/// \code
2042/// #pragma omp ordered
2043/// \endcode
2044///
2045class OMPOrderedDirective : public OMPExecutableDirective {
2046  friend class ASTStmtReader;
2047  /// \brief Build directive with the given start and end location.
2048  ///
2049  /// \param StartLoc Starting location of the directive kind.
2050  /// \param EndLoc Ending location of the directive.
2051  /// \param NumClauses Number of clauses.
2052  ///
2053  OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2054                      unsigned NumClauses)
2055      : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
2056                               StartLoc, EndLoc, NumClauses, 1) {}
2057
2058  /// \brief Build an empty directive.
2059  ///
2060  /// \param NumClauses Number of clauses.
2061  ///
2062  explicit OMPOrderedDirective(unsigned NumClauses)
2063      : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
2064                               SourceLocation(), SourceLocation(), NumClauses,
2065                               1) {}
2066
2067public:
2068  /// \brief Creates directive.
2069  ///
2070  /// \param C AST context.
2071  /// \param StartLoc Starting location of the directive kind.
2072  /// \param EndLoc Ending Location of the directive.
2073  /// \param Clauses List of clauses.
2074  /// \param AssociatedStmt Statement, associated with the directive.
2075  ///
2076  static OMPOrderedDirective *
2077  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2078         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2079
2080  /// \brief Creates an empty directive.
2081  ///
2082  /// \param C AST context.
2083  /// \param NumClauses Number of clauses.
2084  ///
2085  static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
2086                                          unsigned NumClauses, EmptyShell);
2087
2088  static bool classof(const Stmt *T) {
2089    return T->getStmtClass() == OMPOrderedDirectiveClass;
2090  }
2091};
2092
2093/// \brief This represents '#pragma omp atomic' directive.
2094///
2095/// \code
2096/// #pragma omp atomic capture
2097/// \endcode
2098/// In this example directive '#pragma omp atomic' has clause 'capture'.
2099///
2100class OMPAtomicDirective : public OMPExecutableDirective {
2101  friend class ASTStmtReader;
2102  /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
2103  /// have atomic expressions of forms
2104  /// \code
2105  /// x = x binop expr;
2106  /// x = expr binop x;
2107  /// \endcode
2108  /// This field is true for the first form of the expression and false for the
2109  /// second. Required for correct codegen of non-associative operations (like
2110  /// << or >>).
2111  bool IsXLHSInRHSPart;
2112  /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
2113  /// have atomic expressions of forms
2114  /// \code
2115  /// v = x; <update x>;
2116  /// <update x>; v = x;
2117  /// \endcode
2118  /// This field is true for the first(postfix) form of the expression and false
2119  /// otherwise.
2120  bool IsPostfixUpdate;
2121
2122  /// \brief Build directive with the given start and end location.
2123  ///
2124  /// \param StartLoc Starting location of the directive kind.
2125  /// \param EndLoc Ending location of the directive.
2126  /// \param NumClauses Number of clauses.
2127  ///
2128  OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2129                     unsigned NumClauses)
2130      : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
2131                               StartLoc, EndLoc, NumClauses, 5),
2132        IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
2133
2134  /// \brief Build an empty directive.
2135  ///
2136  /// \param NumClauses Number of clauses.
2137  ///
2138  explicit OMPAtomicDirective(unsigned NumClauses)
2139      : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
2140                               SourceLocation(), SourceLocation(), NumClauses,
2141                               5),
2142        IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
2143
2144  /// \brief Set 'x' part of the associated expression/statement.
2145  void setX(Expr *X) { *std::next(child_begin()) = X; }
2146  /// \brief Set helper expression of the form
2147  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
2148  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2149  void setUpdateExpr(Expr *UE) { *std::next(child_begin(), 2) = UE; }
2150  /// \brief Set 'v' part of the associated expression/statement.
2151  void setV(Expr *V) { *std::next(child_begin(), 3) = V; }
2152  /// \brief Set 'expr' part of the associated expression/statement.
2153  void setExpr(Expr *E) { *std::next(child_begin(), 4) = E; }
2154
2155public:
2156  /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
2157  /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
2158  /// detailed description of 'x', 'v' and 'expr').
2159  ///
2160  /// \param C AST context.
2161  /// \param StartLoc Starting location of the directive kind.
2162  /// \param EndLoc Ending Location of the directive.
2163  /// \param Clauses List of clauses.
2164  /// \param AssociatedStmt Statement, associated with the directive.
2165  /// \param X 'x' part of the associated expression/statement.
2166  /// \param V 'v' part of the associated expression/statement.
2167  /// \param E 'expr' part of the associated expression/statement.
2168  /// \param UE Helper expression of the form
2169  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
2170  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2171  /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the
2172  /// second.
2173  /// \param IsPostfixUpdate true if original value of 'x' must be stored in
2174  /// 'v', not an updated one.
2175  static OMPAtomicDirective *
2176  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2177         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
2178         Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate);
2179
2180  /// \brief Creates an empty directive with the place for \a NumClauses
2181  /// clauses.
2182  ///
2183  /// \param C AST context.
2184  /// \param NumClauses Number of clauses.
2185  ///
2186  static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
2187                                         unsigned NumClauses, EmptyShell);
2188
2189  /// \brief Get 'x' part of the associated expression/statement.
2190  Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); }
2191  const Expr *getX() const {
2192    return cast_or_null<Expr>(*std::next(child_begin()));
2193  }
2194  /// \brief Get helper expression of the form
2195  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
2196  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2197  Expr *getUpdateExpr() {
2198    return cast_or_null<Expr>(*std::next(child_begin(), 2));
2199  }
2200  const Expr *getUpdateExpr() const {
2201    return cast_or_null<Expr>(*std::next(child_begin(), 2));
2202  }
2203  /// \brief Return true if helper update expression has form
2204  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
2205  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
2206  bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
2207  /// \brief Return true if 'v' expression must be updated to original value of
2208  /// 'x', false if 'v' must be updated to the new value of 'x'.
2209  bool isPostfixUpdate() const { return IsPostfixUpdate; }
2210  /// \brief Get 'v' part of the associated expression/statement.
2211  Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); }
2212  const Expr *getV() const {
2213    return cast_or_null<Expr>(*std::next(child_begin(), 3));
2214  }
2215  /// \brief Get 'expr' part of the associated expression/statement.
2216  Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 4)); }
2217  const Expr *getExpr() const {
2218    return cast_or_null<Expr>(*std::next(child_begin(), 4));
2219  }
2220
2221  static bool classof(const Stmt *T) {
2222    return T->getStmtClass() == OMPAtomicDirectiveClass;
2223  }
2224};
2225
2226/// \brief This represents '#pragma omp target' directive.
2227///
2228/// \code
2229/// #pragma omp target if(a)
2230/// \endcode
2231/// In this example directive '#pragma omp target' has clause 'if' with
2232/// condition 'a'.
2233///
2234class OMPTargetDirective : public OMPExecutableDirective {
2235  friend class ASTStmtReader;
2236  /// \brief Build directive with the given start and end location.
2237  ///
2238  /// \param StartLoc Starting location of the directive kind.
2239  /// \param EndLoc Ending location of the directive.
2240  /// \param NumClauses Number of clauses.
2241  ///
2242  OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2243                     unsigned NumClauses)
2244      : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
2245                               StartLoc, EndLoc, NumClauses, 1) {}
2246
2247  /// \brief Build an empty directive.
2248  ///
2249  /// \param NumClauses Number of clauses.
2250  ///
2251  explicit OMPTargetDirective(unsigned NumClauses)
2252      : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
2253                               SourceLocation(), SourceLocation(), NumClauses,
2254                               1) {}
2255
2256public:
2257  /// \brief Creates directive with a list of \a Clauses.
2258  ///
2259  /// \param C AST context.
2260  /// \param StartLoc Starting location of the directive kind.
2261  /// \param EndLoc Ending Location of the directive.
2262  /// \param Clauses List of clauses.
2263  /// \param AssociatedStmt Statement, associated with the directive.
2264  ///
2265  static OMPTargetDirective *
2266  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2267         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2268
2269  /// \brief Creates an empty directive with the place for \a NumClauses
2270  /// clauses.
2271  ///
2272  /// \param C AST context.
2273  /// \param NumClauses Number of clauses.
2274  ///
2275  static OMPTargetDirective *CreateEmpty(const ASTContext &C,
2276                                         unsigned NumClauses, EmptyShell);
2277
2278  static bool classof(const Stmt *T) {
2279    return T->getStmtClass() == OMPTargetDirectiveClass;
2280  }
2281};
2282
2283/// \brief This represents '#pragma omp target data' directive.
2284///
2285/// \code
2286/// #pragma omp target data device(0) if(a) map(b[:])
2287/// \endcode
2288/// In this example directive '#pragma omp target data' has clauses 'device'
2289/// with the value '0', 'if' with condition 'a' and 'map' with array
2290/// section 'b[:]'.
2291///
2292class OMPTargetDataDirective : public OMPExecutableDirective {
2293  friend class ASTStmtReader;
2294  /// \brief Build directive with the given start and end location.
2295  ///
2296  /// \param StartLoc Starting location of the directive kind.
2297  /// \param EndLoc Ending Location of the directive.
2298  /// \param NumClauses The number of clauses.
2299  ///
2300  OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2301                         unsigned NumClauses)
2302      : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
2303                               OMPD_target_data, StartLoc, EndLoc, NumClauses,
2304                               1) {}
2305
2306  /// \brief Build an empty directive.
2307  ///
2308  /// \param NumClauses Number of clauses.
2309  ///
2310  explicit OMPTargetDataDirective(unsigned NumClauses)
2311      : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
2312                               OMPD_target_data, SourceLocation(),
2313                               SourceLocation(), NumClauses, 1) {}
2314
2315public:
2316  /// \brief Creates directive with a list of \a Clauses.
2317  ///
2318  /// \param C AST context.
2319  /// \param StartLoc Starting location of the directive kind.
2320  /// \param EndLoc Ending Location of the directive.
2321  /// \param Clauses List of clauses.
2322  /// \param AssociatedStmt Statement, associated with the directive.
2323  ///
2324  static OMPTargetDataDirective *
2325  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2326         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2327
2328  /// \brief Creates an empty directive with the place for \a N clauses.
2329  ///
2330  /// \param C AST context.
2331  /// \param N The number of clauses.
2332  ///
2333  static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
2334                                             EmptyShell);
2335
2336  static bool classof(const Stmt *T) {
2337    return T->getStmtClass() == OMPTargetDataDirectiveClass;
2338  }
2339};
2340
2341/// \brief This represents '#pragma omp target enter data' directive.
2342///
2343/// \code
2344/// #pragma omp target enter data device(0) if(a) map(b[:])
2345/// \endcode
2346/// In this example directive '#pragma omp target enter data' has clauses
2347/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
2348/// section 'b[:]'.
2349///
2350class OMPTargetEnterDataDirective : public OMPExecutableDirective {
2351  friend class ASTStmtReader;
2352  /// \brief Build directive with the given start and end location.
2353  ///
2354  /// \param StartLoc Starting location of the directive kind.
2355  /// \param EndLoc Ending Location of the directive.
2356  /// \param NumClauses The number of clauses.
2357  ///
2358  OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2359                              unsigned NumClauses)
2360      : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
2361                               OMPD_target_enter_data, StartLoc, EndLoc,
2362                               NumClauses, /*NumChildren=*/1) {}
2363
2364  /// \brief Build an empty directive.
2365  ///
2366  /// \param NumClauses Number of clauses.
2367  ///
2368  explicit OMPTargetEnterDataDirective(unsigned NumClauses)
2369      : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
2370                               OMPD_target_enter_data, SourceLocation(),
2371                               SourceLocation(), NumClauses,
2372                               /*NumChildren=*/1) {}
2373
2374public:
2375  /// \brief Creates directive with a list of \a Clauses.
2376  ///
2377  /// \param C AST context.
2378  /// \param StartLoc Starting location of the directive kind.
2379  /// \param EndLoc Ending Location of the directive.
2380  /// \param Clauses List of clauses.
2381  /// \param AssociatedStmt Statement, associated with the directive.
2382  ///
2383  static OMPTargetEnterDataDirective *
2384  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2385         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2386
2387  /// \brief Creates an empty directive with the place for \a N clauses.
2388  ///
2389  /// \param C AST context.
2390  /// \param N The number of clauses.
2391  ///
2392  static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C,
2393                                                  unsigned N, EmptyShell);
2394
2395  static bool classof(const Stmt *T) {
2396    return T->getStmtClass() == OMPTargetEnterDataDirectiveClass;
2397  }
2398};
2399
2400/// \brief This represents '#pragma omp target exit data' directive.
2401///
2402/// \code
2403/// #pragma omp target exit data device(0) if(a) map(b[:])
2404/// \endcode
2405/// In this example directive '#pragma omp target exit data' has clauses
2406/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
2407/// section 'b[:]'.
2408///
2409class OMPTargetExitDataDirective : public OMPExecutableDirective {
2410  friend class ASTStmtReader;
2411  /// \brief Build directive with the given start and end location.
2412  ///
2413  /// \param StartLoc Starting location of the directive kind.
2414  /// \param EndLoc Ending Location of the directive.
2415  /// \param NumClauses The number of clauses.
2416  ///
2417  OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2418                             unsigned NumClauses)
2419      : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
2420                               OMPD_target_exit_data, StartLoc, EndLoc,
2421                               NumClauses, /*NumChildren=*/1) {}
2422
2423  /// \brief Build an empty directive.
2424  ///
2425  /// \param NumClauses Number of clauses.
2426  ///
2427  explicit OMPTargetExitDataDirective(unsigned NumClauses)
2428      : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
2429                               OMPD_target_exit_data, SourceLocation(),
2430                               SourceLocation(), NumClauses,
2431                               /*NumChildren=*/1) {}
2432
2433public:
2434  /// \brief Creates directive with a list of \a Clauses.
2435  ///
2436  /// \param C AST context.
2437  /// \param StartLoc Starting location of the directive kind.
2438  /// \param EndLoc Ending Location of the directive.
2439  /// \param Clauses List of clauses.
2440  /// \param AssociatedStmt Statement, associated with the directive.
2441  ///
2442  static OMPTargetExitDataDirective *
2443  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2444         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2445
2446  /// \brief Creates an empty directive with the place for \a N clauses.
2447  ///
2448  /// \param C AST context.
2449  /// \param N The number of clauses.
2450  ///
2451  static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
2452                                                 unsigned N, EmptyShell);
2453
2454  static bool classof(const Stmt *T) {
2455    return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
2456  }
2457};
2458
2459/// \brief This represents '#pragma omp target parallel' directive.
2460///
2461/// \code
2462/// #pragma omp target parallel if(a)
2463/// \endcode
2464/// In this example directive '#pragma omp target parallel' has clause 'if' with
2465/// condition 'a'.
2466///
2467class OMPTargetParallelDirective : public OMPExecutableDirective {
2468  friend class ASTStmtReader;
2469  /// \brief Build directive with the given start and end location.
2470  ///
2471  /// \param StartLoc Starting location of the directive kind.
2472  /// \param EndLoc Ending location of the directive.
2473  /// \param NumClauses Number of clauses.
2474  ///
2475  OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2476                             unsigned NumClauses)
2477      : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass,
2478                               OMPD_target_parallel, StartLoc, EndLoc,
2479                               NumClauses, /*NumChildren=*/1) {}
2480
2481  /// \brief Build an empty directive.
2482  ///
2483  /// \param NumClauses Number of clauses.
2484  ///
2485  explicit OMPTargetParallelDirective(unsigned NumClauses)
2486      : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass,
2487                               OMPD_target_parallel, SourceLocation(),
2488                               SourceLocation(), NumClauses,
2489                               /*NumChildren=*/1) {}
2490
2491public:
2492  /// \brief Creates directive with a list of \a Clauses.
2493  ///
2494  /// \param C AST context.
2495  /// \param StartLoc Starting location of the directive kind.
2496  /// \param EndLoc Ending Location of the directive.
2497  /// \param Clauses List of clauses.
2498  /// \param AssociatedStmt Statement, associated with the directive.
2499  ///
2500  static OMPTargetParallelDirective *
2501  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2502         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2503
2504  /// \brief Creates an empty directive with the place for \a NumClauses
2505  /// clauses.
2506  ///
2507  /// \param C AST context.
2508  /// \param NumClauses Number of clauses.
2509  ///
2510  static OMPTargetParallelDirective *
2511  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2512
2513  static bool classof(const Stmt *T) {
2514    return T->getStmtClass() == OMPTargetParallelDirectiveClass;
2515  }
2516};
2517
2518/// \brief This represents '#pragma omp target parallel for' directive.
2519///
2520/// \code
2521/// #pragma omp target parallel for private(a,b) reduction(+:c,d)
2522/// \endcode
2523/// In this example directive '#pragma omp target parallel for' has clauses
2524/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
2525/// and variables 'c' and 'd'.
2526///
2527class OMPTargetParallelForDirective : public OMPLoopDirective {
2528  friend class ASTStmtReader;
2529
2530  /// \brief true if current region has inner cancel directive.
2531  bool HasCancel;
2532
2533  /// \brief 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  /// \param CollapsedNum Number of collapsed nested loops.
2538  /// \param NumClauses Number of clauses.
2539  ///
2540  OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2541                                unsigned CollapsedNum, unsigned NumClauses)
2542      : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass,
2543                         OMPD_target_parallel_for, StartLoc, EndLoc,
2544                         CollapsedNum, NumClauses),
2545        HasCancel(false) {}
2546
2547  /// \brief Build an empty directive.
2548  ///
2549  /// \param CollapsedNum Number of collapsed nested loops.
2550  /// \param NumClauses Number of clauses.
2551  ///
2552  explicit OMPTargetParallelForDirective(unsigned CollapsedNum,
2553                                         unsigned NumClauses)
2554      : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass,
2555                         OMPD_target_parallel_for, SourceLocation(),
2556                         SourceLocation(), CollapsedNum, NumClauses),
2557        HasCancel(false) {}
2558
2559  /// \brief Set cancel state.
2560  void setHasCancel(bool Has) { HasCancel = Has; }
2561
2562public:
2563  /// \brief Creates directive with a list of \a Clauses.
2564  ///
2565  /// \param C AST context.
2566  /// \param StartLoc Starting location of the directive kind.
2567  /// \param EndLoc Ending Location of the directive.
2568  /// \param CollapsedNum Number of collapsed loops.
2569  /// \param Clauses List of clauses.
2570  /// \param AssociatedStmt Statement, associated with the directive.
2571  /// \param Exprs Helper expressions for CodeGen.
2572  /// \param HasCancel true if current directive has inner cancel directive.
2573  ///
2574  static OMPTargetParallelForDirective *
2575  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2576         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2577         Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
2578
2579  /// \brief Creates an empty directive with the place
2580  /// for \a NumClauses clauses.
2581  ///
2582  /// \param C AST context.
2583  /// \param CollapsedNum Number of collapsed nested loops.
2584  /// \param NumClauses Number of clauses.
2585  ///
2586  static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C,
2587                                                    unsigned NumClauses,
2588                                                    unsigned CollapsedNum,
2589                                                    EmptyShell);
2590
2591  /// \brief Return true if current directive has inner cancel directive.
2592  bool hasCancel() const { return HasCancel; }
2593
2594  static bool classof(const Stmt *T) {
2595    return T->getStmtClass() == OMPTargetParallelForDirectiveClass;
2596  }
2597};
2598
2599/// \brief This represents '#pragma omp teams' directive.
2600///
2601/// \code
2602/// #pragma omp teams if(a)
2603/// \endcode
2604/// In this example directive '#pragma omp teams' has clause 'if' with
2605/// condition 'a'.
2606///
2607class OMPTeamsDirective : public OMPExecutableDirective {
2608  friend class ASTStmtReader;
2609  /// \brief Build directive with the given start and end location.
2610  ///
2611  /// \param StartLoc Starting location of the directive kind.
2612  /// \param EndLoc Ending location of the directive.
2613  /// \param NumClauses Number of clauses.
2614  ///
2615  OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2616                    unsigned NumClauses)
2617      : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
2618                               StartLoc, EndLoc, NumClauses, 1) {}
2619
2620  /// \brief Build an empty directive.
2621  ///
2622  /// \param NumClauses Number of clauses.
2623  ///
2624  explicit OMPTeamsDirective(unsigned NumClauses)
2625      : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
2626                               SourceLocation(), SourceLocation(), NumClauses,
2627                               1) {}
2628
2629public:
2630  /// \brief Creates directive with a list of \a Clauses.
2631  ///
2632  /// \param C AST context.
2633  /// \param StartLoc Starting location of the directive kind.
2634  /// \param EndLoc Ending Location of the directive.
2635  /// \param Clauses List of clauses.
2636  /// \param AssociatedStmt Statement, associated with the directive.
2637  ///
2638  static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2639                                   SourceLocation EndLoc,
2640                                   ArrayRef<OMPClause *> Clauses,
2641                                   Stmt *AssociatedStmt);
2642
2643  /// \brief Creates an empty directive with the place for \a NumClauses
2644  /// clauses.
2645  ///
2646  /// \param C AST context.
2647  /// \param NumClauses Number of clauses.
2648  ///
2649  static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
2650                                        unsigned NumClauses, EmptyShell);
2651
2652  static bool classof(const Stmt *T) {
2653    return T->getStmtClass() == OMPTeamsDirectiveClass;
2654  }
2655};
2656
2657/// \brief This represents '#pragma omp cancellation point' directive.
2658///
2659/// \code
2660/// #pragma omp cancellation point for
2661/// \endcode
2662///
2663/// In this example a cancellation point is created for innermost 'for' region.
2664class OMPCancellationPointDirective : public OMPExecutableDirective {
2665  friend class ASTStmtReader;
2666  OpenMPDirectiveKind CancelRegion;
2667  /// \brief Build directive with the given start and end location.
2668  ///
2669  /// \param StartLoc Starting location of the directive kind.
2670  /// \param EndLoc Ending location of the directive.
2671  ///
2672  OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2673      : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
2674                               OMPD_cancellation_point, StartLoc, EndLoc, 0, 0),
2675        CancelRegion(OMPD_unknown) {}
2676
2677  /// \brief Build an empty directive.
2678  ///
2679  explicit OMPCancellationPointDirective()
2680      : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
2681                               OMPD_cancellation_point, SourceLocation(),
2682                               SourceLocation(), 0, 0),
2683        CancelRegion(OMPD_unknown) {}
2684
2685  /// \brief Set cancel region for current cancellation point.
2686  /// \param CR Cancellation region.
2687  void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
2688
2689public:
2690  /// \brief Creates directive.
2691  ///
2692  /// \param C AST context.
2693  /// \param StartLoc Starting location of the directive kind.
2694  /// \param EndLoc Ending Location of the directive.
2695  ///
2696  static OMPCancellationPointDirective *
2697  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2698         OpenMPDirectiveKind CancelRegion);
2699
2700  /// \brief Creates an empty directive.
2701  ///
2702  /// \param C AST context.
2703  ///
2704  static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
2705                                                    EmptyShell);
2706
2707  /// \brief Get cancellation region for the current cancellation point.
2708  OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
2709
2710  static bool classof(const Stmt *T) {
2711    return T->getStmtClass() == OMPCancellationPointDirectiveClass;
2712  }
2713};
2714
2715/// \brief This represents '#pragma omp cancel' directive.
2716///
2717/// \code
2718/// #pragma omp cancel for
2719/// \endcode
2720///
2721/// In this example a cancel is created for innermost 'for' region.
2722class OMPCancelDirective : public OMPExecutableDirective {
2723  friend class ASTStmtReader;
2724  OpenMPDirectiveKind CancelRegion;
2725  /// \brief Build directive with the given start and end location.
2726  ///
2727  /// \param StartLoc Starting location of the directive kind.
2728  /// \param EndLoc Ending location of the directive.
2729  /// \param NumClauses Number of clauses.
2730  ///
2731  OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2732                     unsigned NumClauses)
2733      : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
2734                               StartLoc, EndLoc, NumClauses, 0),
2735        CancelRegion(OMPD_unknown) {}
2736
2737  /// \brief Build an empty directive.
2738  ///
2739  /// \param NumClauses Number of clauses.
2740  explicit OMPCancelDirective(unsigned NumClauses)
2741      : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
2742                               SourceLocation(), SourceLocation(), NumClauses,
2743                               0),
2744        CancelRegion(OMPD_unknown) {}
2745
2746  /// \brief Set cancel region for current cancellation point.
2747  /// \param CR Cancellation region.
2748  void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
2749
2750public:
2751  /// \brief Creates directive.
2752  ///
2753  /// \param C AST context.
2754  /// \param StartLoc Starting location of the directive kind.
2755  /// \param EndLoc Ending Location of the directive.
2756  /// \param Clauses List of clauses.
2757  ///
2758  static OMPCancelDirective *
2759  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2760         ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
2761
2762  /// \brief Creates an empty directive.
2763  ///
2764  /// \param C AST context.
2765  /// \param NumClauses Number of clauses.
2766  ///
2767  static OMPCancelDirective *CreateEmpty(const ASTContext &C,
2768                                         unsigned NumClauses, EmptyShell);
2769
2770  /// \brief Get cancellation region for the current cancellation point.
2771  OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
2772
2773  static bool classof(const Stmt *T) {
2774    return T->getStmtClass() == OMPCancelDirectiveClass;
2775  }
2776};
2777
2778/// \brief This represents '#pragma omp taskloop' directive.
2779///
2780/// \code
2781/// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
2782/// \endcode
2783/// In this example directive '#pragma omp taskloop' has clauses 'private'
2784/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
2785/// 'num_tasks' with expression 'num'.
2786///
2787class OMPTaskLoopDirective : public OMPLoopDirective {
2788  friend class ASTStmtReader;
2789  /// \brief Build directive with the given start and end location.
2790  ///
2791  /// \param StartLoc Starting location of the directive kind.
2792  /// \param EndLoc Ending location of the directive.
2793  /// \param CollapsedNum Number of collapsed nested loops.
2794  /// \param NumClauses Number of clauses.
2795  ///
2796  OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2797                       unsigned CollapsedNum, unsigned NumClauses)
2798      : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
2799                         StartLoc, EndLoc, CollapsedNum, NumClauses) {}
2800
2801  /// \brief Build an empty directive.
2802  ///
2803  /// \param CollapsedNum Number of collapsed nested loops.
2804  /// \param NumClauses Number of clauses.
2805  ///
2806  explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses)
2807      : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
2808                         SourceLocation(), SourceLocation(), CollapsedNum,
2809                         NumClauses) {}
2810
2811public:
2812  /// \brief Creates directive with a list of \a Clauses.
2813  ///
2814  /// \param C AST context.
2815  /// \param StartLoc Starting location of the directive kind.
2816  /// \param EndLoc Ending Location of the directive.
2817  /// \param CollapsedNum Number of collapsed loops.
2818  /// \param Clauses List of clauses.
2819  /// \param AssociatedStmt Statement, associated with the directive.
2820  /// \param Exprs Helper expressions for CodeGen.
2821  ///
2822  static OMPTaskLoopDirective *
2823  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2824         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2825         Stmt *AssociatedStmt, const HelperExprs &Exprs);
2826
2827  /// \brief Creates an empty directive with the place
2828  /// for \a NumClauses clauses.
2829  ///
2830  /// \param C AST context.
2831  /// \param CollapsedNum Number of collapsed nested loops.
2832  /// \param NumClauses Number of clauses.
2833  ///
2834  static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
2835                                           unsigned NumClauses,
2836                                           unsigned CollapsedNum, EmptyShell);
2837
2838  static bool classof(const Stmt *T) {
2839    return T->getStmtClass() == OMPTaskLoopDirectiveClass;
2840  }
2841};
2842
2843/// \brief This represents '#pragma omp taskloop simd' directive.
2844///
2845/// \code
2846/// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
2847/// \endcode
2848/// In this example directive '#pragma omp taskloop simd' has clauses 'private'
2849/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
2850/// 'num_tasks' with expression 'num'.
2851///
2852class OMPTaskLoopSimdDirective : public OMPLoopDirective {
2853  friend class ASTStmtReader;
2854  /// \brief Build directive with the given start and end location.
2855  ///
2856  /// \param StartLoc Starting location of the directive kind.
2857  /// \param EndLoc Ending location of the directive.
2858  /// \param CollapsedNum Number of collapsed nested loops.
2859  /// \param NumClauses Number of clauses.
2860  ///
2861  OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2862                           unsigned CollapsedNum, unsigned NumClauses)
2863      : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
2864                         OMPD_taskloop_simd, StartLoc, EndLoc, CollapsedNum,
2865                         NumClauses) {}
2866
2867  /// \brief Build an empty directive.
2868  ///
2869  /// \param CollapsedNum Number of collapsed nested loops.
2870  /// \param NumClauses Number of clauses.
2871  ///
2872  explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
2873      : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
2874                         OMPD_taskloop_simd, SourceLocation(), SourceLocation(),
2875                         CollapsedNum, NumClauses) {}
2876
2877public:
2878  /// \brief Creates directive with a list of \a Clauses.
2879  ///
2880  /// \param C AST context.
2881  /// \param StartLoc Starting location of the directive kind.
2882  /// \param EndLoc Ending Location of the directive.
2883  /// \param CollapsedNum Number of collapsed loops.
2884  /// \param Clauses List of clauses.
2885  /// \param AssociatedStmt Statement, associated with the directive.
2886  /// \param Exprs Helper expressions for CodeGen.
2887  ///
2888  static OMPTaskLoopSimdDirective *
2889  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2890         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2891         Stmt *AssociatedStmt, const HelperExprs &Exprs);
2892
2893  /// \brief Creates an empty directive with the place
2894  /// for \a NumClauses clauses.
2895  ///
2896  /// \param C AST context.
2897  /// \param CollapsedNum Number of collapsed nested loops.
2898  /// \param NumClauses Number of clauses.
2899  ///
2900  static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
2901                                               unsigned NumClauses,
2902                                               unsigned CollapsedNum,
2903                                               EmptyShell);
2904
2905  static bool classof(const Stmt *T) {
2906    return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
2907  }
2908};
2909
2910/// \brief This represents '#pragma omp distribute' directive.
2911///
2912/// \code
2913/// #pragma omp distribute private(a,b)
2914/// \endcode
2915/// In this example directive '#pragma omp distribute' has clauses 'private'
2916/// with the variables 'a' and 'b'
2917///
2918class OMPDistributeDirective : public OMPLoopDirective {
2919  friend class ASTStmtReader;
2920
2921  /// \brief Build directive with the given start and end location.
2922  ///
2923  /// \param StartLoc Starting location of the directive kind.
2924  /// \param EndLoc Ending location of the directive.
2925  /// \param CollapsedNum Number of collapsed nested loops.
2926  /// \param NumClauses Number of clauses.
2927  ///
2928  OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2929                         unsigned CollapsedNum, unsigned NumClauses)
2930      : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
2931                         StartLoc, EndLoc, CollapsedNum, NumClauses)
2932        {}
2933
2934  /// \brief Build an empty directive.
2935  ///
2936  /// \param CollapsedNum Number of collapsed nested loops.
2937  /// \param NumClauses Number of clauses.
2938  ///
2939  explicit OMPDistributeDirective(unsigned CollapsedNum, unsigned NumClauses)
2940      : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
2941                         SourceLocation(), SourceLocation(), CollapsedNum,
2942                         NumClauses)
2943        {}
2944
2945public:
2946  /// \brief Creates directive with a list of \a Clauses.
2947  ///
2948  /// \param C AST context.
2949  /// \param StartLoc Starting location of the directive kind.
2950  /// \param EndLoc Ending Location of the directive.
2951  /// \param CollapsedNum Number of collapsed loops.
2952  /// \param Clauses List of clauses.
2953  /// \param AssociatedStmt Statement, associated with the directive.
2954  /// \param Exprs Helper expressions for CodeGen.
2955  ///
2956  static OMPDistributeDirective *
2957  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2958         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2959         Stmt *AssociatedStmt, const HelperExprs &Exprs);
2960
2961  /// \brief Creates an empty directive with the place
2962  /// for \a NumClauses clauses.
2963  ///
2964  /// \param C AST context.
2965  /// \param CollapsedNum Number of collapsed nested loops.
2966  /// \param NumClauses Number of clauses.
2967  ///
2968  static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
2969                                             unsigned NumClauses,
2970                                             unsigned CollapsedNum, EmptyShell);
2971
2972  static bool classof(const Stmt *T) {
2973    return T->getStmtClass() == OMPDistributeDirectiveClass;
2974  }
2975};
2976
2977/// \brief This represents '#pragma omp target update' directive.
2978///
2979/// \code
2980/// #pragma omp target update to(a) from(b) device(1)
2981/// \endcode
2982/// In this example directive '#pragma omp target update' has clause 'to' with
2983/// argument 'a', clause 'from' with argument 'b' and clause 'device' with
2984/// argument '1'.
2985///
2986class OMPTargetUpdateDirective : public OMPExecutableDirective {
2987  friend class ASTStmtReader;
2988  /// \brief Build directive with the given start and end location.
2989  ///
2990  /// \param StartLoc Starting location of the directive kind.
2991  /// \param EndLoc Ending Location of the directive.
2992  /// \param NumClauses The number of clauses.
2993  ///
2994  OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2995                           unsigned NumClauses)
2996      : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
2997                               OMPD_target_update, StartLoc, EndLoc, NumClauses,
2998                               1) {}
2999
3000  /// \brief Build an empty directive.
3001  ///
3002  /// \param NumClauses Number of clauses.
3003  ///
3004  explicit OMPTargetUpdateDirective(unsigned NumClauses)
3005      : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
3006                               OMPD_target_update, SourceLocation(),
3007                               SourceLocation(), NumClauses, 1) {}
3008
3009public:
3010  /// \brief Creates directive with a list of \a Clauses.
3011  ///
3012  /// \param C AST context.
3013  /// \param StartLoc Starting location of the directive kind.
3014  /// \param EndLoc Ending Location of the directive.
3015  /// \param Clauses List of clauses.
3016  /// \param AssociatedStmt Statement, associated with the directive.
3017  ///
3018  static OMPTargetUpdateDirective *
3019  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3020         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
3021
3022  /// \brief Creates an empty directive with the place for \a NumClauses
3023  /// clauses.
3024  ///
3025  /// \param C AST context.
3026  /// \param NumClauses The number of clauses.
3027  ///
3028  static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C,
3029                                               unsigned NumClauses, EmptyShell);
3030
3031  static bool classof(const Stmt *T) {
3032    return T->getStmtClass() == OMPTargetUpdateDirectiveClass;
3033  }
3034};
3035
3036/// \brief This represents '#pragma omp distribute parallel for' composite
3037///  directive.
3038///
3039/// \code
3040/// #pragma omp distribute parallel for private(a,b)
3041/// \endcode
3042/// In this example directive '#pragma omp distribute parallel for' has clause
3043/// 'private' with the variables 'a' and 'b'
3044///
3045class OMPDistributeParallelForDirective : public OMPLoopDirective {
3046  friend class ASTStmtReader;
3047  /// true if the construct has inner cancel directive.
3048  bool HasCancel = false;
3049
3050  /// \brief Build directive with the given start and end location.
3051  ///
3052  /// \param StartLoc Starting location of the directive kind.
3053  /// \param EndLoc Ending location of the directive.
3054  /// \param CollapsedNum Number of collapsed nested loops.
3055  /// \param NumClauses Number of clauses.
3056  ///
3057  OMPDistributeParallelForDirective(SourceLocation StartLoc,
3058                                    SourceLocation EndLoc,
3059                                    unsigned CollapsedNum, unsigned NumClauses)
3060      : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass,
3061                         OMPD_distribute_parallel_for, StartLoc, EndLoc,
3062                         CollapsedNum, NumClauses), HasCancel(false) {}
3063
3064  /// \brief Build an empty directive.
3065  ///
3066  /// \param CollapsedNum Number of collapsed nested loops.
3067  /// \param NumClauses Number of clauses.
3068  ///
3069  explicit OMPDistributeParallelForDirective(unsigned CollapsedNum,
3070                                             unsigned NumClauses)
3071      : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass,
3072                         OMPD_distribute_parallel_for, SourceLocation(),
3073                         SourceLocation(), CollapsedNum, NumClauses),
3074        HasCancel(false) {}
3075
3076  /// Set cancel state.
3077  void setHasCancel(bool Has) { HasCancel = Has; }
3078
3079public:
3080  /// \brief Creates directive with a list of \a Clauses.
3081  ///
3082  /// \param C AST context.
3083  /// \param StartLoc Starting location of the directive kind.
3084  /// \param EndLoc Ending Location of the directive.
3085  /// \param CollapsedNum Number of collapsed loops.
3086  /// \param Clauses List of clauses.
3087  /// \param AssociatedStmt Statement, associated with the directive.
3088  /// \param Exprs Helper expressions for CodeGen.
3089  /// \param HasCancel true if this directive has inner cancel directive.
3090  ///
3091  static OMPDistributeParallelForDirective *
3092  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3093         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3094         Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3095
3096  /// \brief Creates an empty directive with the place
3097  /// for \a NumClauses clauses.
3098  ///
3099  /// \param C AST context.
3100  /// \param CollapsedNum Number of collapsed nested loops.
3101  /// \param NumClauses Number of clauses.
3102  ///
3103  static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C,
3104                                                        unsigned NumClauses,
3105                                                        unsigned CollapsedNum,
3106                                                        EmptyShell);
3107
3108  /// Return true if current directive has inner cancel directive.
3109  bool hasCancel() const { return HasCancel; }
3110
3111  static bool classof(const Stmt *T) {
3112    return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
3113  }
3114};
3115
3116/// This represents '#pragma omp distribute parallel for simd' composite
3117/// directive.
3118///
3119/// \code
3120/// #pragma omp distribute parallel for simd private(x)
3121/// \endcode
3122/// In this example directive '#pragma omp distribute parallel for simd' has
3123/// clause 'private' with the variables 'x'
3124///
3125class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective {
3126  friend class ASTStmtReader;
3127
3128  /// Build directive with the given start and end location.
3129  ///
3130  /// \param StartLoc Starting location of the directive kind.
3131  /// \param EndLoc Ending location of the directive.
3132  /// \param CollapsedNum Number of collapsed nested loops.
3133  /// \param NumClauses Number of clauses.
3134  ///
3135  OMPDistributeParallelForSimdDirective(SourceLocation StartLoc,
3136                                        SourceLocation EndLoc,
3137                                        unsigned CollapsedNum,
3138                                        unsigned NumClauses)
3139      : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass,
3140                         OMPD_distribute_parallel_for_simd, StartLoc,
3141                         EndLoc, CollapsedNum, NumClauses) {}
3142
3143  /// Build an empty directive.
3144  ///
3145  /// \param CollapsedNum Number of collapsed nested loops.
3146  /// \param NumClauses Number of clauses.
3147  ///
3148  explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum,
3149                                                 unsigned NumClauses)
3150      : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass,
3151                         OMPD_distribute_parallel_for_simd,
3152                         SourceLocation(), SourceLocation(), CollapsedNum,
3153                         NumClauses) {}
3154
3155public:
3156  /// Creates directive with a list of \a Clauses.
3157  ///
3158  /// \param C AST context.
3159  /// \param StartLoc Starting location of the directive kind.
3160  /// \param EndLoc Ending Location of the directive.
3161  /// \param CollapsedNum Number of collapsed loops.
3162  /// \param Clauses List of clauses.
3163  /// \param AssociatedStmt Statement, associated with the directive.
3164  /// \param Exprs Helper expressions for CodeGen.
3165  ///
3166  static OMPDistributeParallelForSimdDirective *Create(
3167      const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3168      unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3169      Stmt *AssociatedStmt, const HelperExprs &Exprs);
3170
3171  /// Creates an empty directive with the place for \a NumClauses clauses.
3172  ///
3173  /// \param C AST context.
3174  /// \param CollapsedNum Number of collapsed nested loops.
3175  /// \param NumClauses Number of clauses.
3176  ///
3177  static OMPDistributeParallelForSimdDirective *CreateEmpty(
3178      const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
3179      EmptyShell);
3180
3181  static bool classof(const Stmt *T) {
3182    return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass;
3183  }
3184};
3185
3186/// This represents '#pragma omp distribute simd' composite directive.
3187///
3188/// \code
3189/// #pragma omp distribute simd private(x)
3190/// \endcode
3191/// In this example directive '#pragma omp distribute simd' has clause
3192/// 'private' with the variables 'x'
3193///
3194class OMPDistributeSimdDirective final : public OMPLoopDirective {
3195  friend class ASTStmtReader;
3196
3197  /// Build directive with the given start and end location.
3198  ///
3199  /// \param StartLoc Starting location of the directive kind.
3200  /// \param EndLoc Ending location of the directive.
3201  /// \param CollapsedNum Number of collapsed nested loops.
3202  /// \param NumClauses Number of clauses.
3203  ///
3204  OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3205                             unsigned CollapsedNum, unsigned NumClauses)
3206      : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass,
3207                         OMPD_distribute_simd, StartLoc, EndLoc, CollapsedNum,
3208                         NumClauses) {}
3209
3210  /// Build an empty directive.
3211  ///
3212  /// \param CollapsedNum Number of collapsed nested loops.
3213  /// \param NumClauses Number of clauses.
3214  ///
3215  explicit OMPDistributeSimdDirective(unsigned CollapsedNum,
3216                                      unsigned NumClauses)
3217      : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass,
3218                         OMPD_distribute_simd, SourceLocation(),
3219                         SourceLocation(), CollapsedNum, NumClauses) {}
3220
3221public:
3222  /// Creates directive with a list of \a Clauses.
3223  ///
3224  /// \param C AST context.
3225  /// \param StartLoc Starting location of the directive kind.
3226  /// \param EndLoc Ending Location of the directive.
3227  /// \param CollapsedNum Number of collapsed loops.
3228  /// \param Clauses List of clauses.
3229  /// \param AssociatedStmt Statement, associated with the directive.
3230  /// \param Exprs Helper expressions for CodeGen.
3231  ///
3232  static OMPDistributeSimdDirective *
3233  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3234         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3235         Stmt *AssociatedStmt, const HelperExprs &Exprs);
3236
3237  /// Creates an empty directive with the place for \a NumClauses clauses.
3238  ///
3239  /// \param C AST context.
3240  /// \param CollapsedNum Number of collapsed nested loops.
3241  /// \param NumClauses Number of clauses.
3242  ///
3243  static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C,
3244                                                 unsigned NumClauses,
3245                                                 unsigned CollapsedNum,
3246                                                 EmptyShell);
3247
3248  static bool classof(const Stmt *T) {
3249    return T->getStmtClass() == OMPDistributeSimdDirectiveClass;
3250  }
3251};
3252
3253/// This represents '#pragma omp target parallel for simd' directive.
3254///
3255/// \code
3256/// #pragma omp target parallel for simd private(a) map(b) safelen(c)
3257/// \endcode
3258/// In this example directive '#pragma omp target parallel for simd' has clauses
3259/// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen'
3260/// with the variable 'c'.
3261///
3262class OMPTargetParallelForSimdDirective final : public OMPLoopDirective {
3263  friend class ASTStmtReader;
3264
3265  /// Build directive with the given start and end location.
3266  ///
3267  /// \param StartLoc Starting location of the directive kind.
3268  /// \param EndLoc Ending location of the directive.
3269  /// \param CollapsedNum Number of collapsed nested loops.
3270  /// \param NumClauses Number of clauses.
3271  ///
3272  OMPTargetParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3273                                unsigned CollapsedNum, unsigned NumClauses)
3274      : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass,
3275                         OMPD_target_parallel_for_simd, StartLoc, EndLoc,
3276                         CollapsedNum, NumClauses) {}
3277
3278  /// Build an empty directive.
3279  ///
3280  /// \param CollapsedNum Number of collapsed nested loops.
3281  /// \param NumClauses Number of clauses.
3282  ///
3283  explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum,
3284                                             unsigned NumClauses)
3285      : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass,
3286                         OMPD_target_parallel_for_simd, SourceLocation(),
3287                         SourceLocation(), CollapsedNum, NumClauses) {}
3288
3289public:
3290  /// Creates directive with a list of \a Clauses.
3291  ///
3292  /// \param C AST context.
3293  /// \param StartLoc Starting location of the directive kind.
3294  /// \param EndLoc Ending Location of the directive.
3295  /// \param CollapsedNum Number of collapsed loops.
3296  /// \param Clauses List of clauses.
3297  /// \param AssociatedStmt Statement, associated with the directive.
3298  /// \param Exprs Helper expressions for CodeGen.
3299  ///
3300  static OMPTargetParallelForSimdDirective *
3301  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3302         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3303         Stmt *AssociatedStmt, const HelperExprs &Exprs);
3304
3305  /// Creates an empty directive with the place for \a NumClauses clauses.
3306  ///
3307  /// \param C AST context.
3308  /// \param CollapsedNum Number of collapsed nested loops.
3309  /// \param NumClauses Number of clauses.
3310  ///
3311  static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C,
3312                                                        unsigned NumClauses,
3313                                                        unsigned CollapsedNum,
3314                                                        EmptyShell);
3315
3316  static bool classof(const Stmt *T) {
3317    return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
3318  }
3319};
3320
3321/// This represents '#pragma omp target simd' directive.
3322///
3323/// \code
3324/// #pragma omp target simd private(a) map(b) safelen(c)
3325/// \endcode
3326/// In this example directive '#pragma omp target simd' has clauses 'private'
3327/// with the variable 'a', 'map' with the variable 'b' and 'safelen' with
3328/// the variable 'c'.
3329///
3330class OMPTargetSimdDirective final : public OMPLoopDirective {
3331  friend class ASTStmtReader;
3332
3333  /// Build directive with the given start and end location.
3334  ///
3335  /// \param StartLoc Starting location of the directive kind.
3336  /// \param EndLoc Ending location of the directive.
3337  /// \param CollapsedNum Number of collapsed nested loops.
3338  /// \param NumClauses Number of clauses.
3339  ///
3340  OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3341                         unsigned CollapsedNum, unsigned NumClauses)
3342      : OMPLoopDirective(this, OMPTargetSimdDirectiveClass,
3343                         OMPD_target_simd, StartLoc, EndLoc, CollapsedNum,
3344                         NumClauses) {}
3345
3346  /// Build an empty directive.
3347  ///
3348  /// \param CollapsedNum Number of collapsed nested loops.
3349  /// \param NumClauses Number of clauses.
3350  ///
3351  explicit OMPTargetSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
3352      : OMPLoopDirective(this, OMPTargetSimdDirectiveClass, OMPD_target_simd,
3353                         SourceLocation(),SourceLocation(), CollapsedNum,
3354                         NumClauses) {}
3355
3356public:
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 CollapsedNum Number of collapsed loops.
3363  /// \param Clauses List of clauses.
3364  /// \param AssociatedStmt Statement, associated with the directive.
3365  /// \param Exprs Helper expressions for CodeGen.
3366  ///
3367  static OMPTargetSimdDirective *
3368  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3369         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3370         Stmt *AssociatedStmt, const HelperExprs &Exprs);
3371
3372  /// Creates an empty directive with the place for \a NumClauses clauses.
3373  ///
3374  /// \param C AST context.
3375  /// \param CollapsedNum Number of collapsed nested loops.
3376  /// \param NumClauses Number of clauses.
3377  ///
3378  static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C,
3379                                             unsigned NumClauses,
3380                                             unsigned CollapsedNum,
3381                                             EmptyShell);
3382
3383  static bool classof(const Stmt *T) {
3384    return T->getStmtClass() == OMPTargetSimdDirectiveClass;
3385  }
3386};
3387
3388/// This represents '#pragma omp teams distribute' directive.
3389///
3390/// \code
3391/// #pragma omp teams distribute private(a,b)
3392/// \endcode
3393/// In this example directive '#pragma omp teams distribute' has clauses
3394/// 'private' with the variables 'a' and 'b'
3395///
3396class OMPTeamsDistributeDirective final : public OMPLoopDirective {
3397  friend class ASTStmtReader;
3398
3399  /// Build directive with the given start and end location.
3400  ///
3401  /// \param StartLoc Starting location of the directive kind.
3402  /// \param EndLoc Ending location of the directive.
3403  /// \param CollapsedNum Number of collapsed nested loops.
3404  /// \param NumClauses Number of clauses.
3405  ///
3406  OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3407                              unsigned CollapsedNum, unsigned NumClauses)
3408      : OMPLoopDirective(this, OMPTeamsDistributeDirectiveClass,
3409                         OMPD_teams_distribute, StartLoc, EndLoc,
3410                         CollapsedNum, NumClauses) {}
3411
3412  /// Build an empty directive.
3413  ///
3414  /// \param CollapsedNum Number of collapsed nested loops.
3415  /// \param NumClauses Number of clauses.
3416  ///
3417  explicit OMPTeamsDistributeDirective(unsigned CollapsedNum,
3418                                       unsigned NumClauses)
3419      : OMPLoopDirective(this, OMPTeamsDistributeDirectiveClass,
3420                         OMPD_teams_distribute, SourceLocation(),
3421                         SourceLocation(), CollapsedNum, NumClauses) {}
3422
3423public:
3424  /// Creates directive with a list of \a Clauses.
3425  ///
3426  /// \param C AST context.
3427  /// \param StartLoc Starting location of the directive kind.
3428  /// \param EndLoc Ending Location of the directive.
3429  /// \param CollapsedNum Number of collapsed loops.
3430  /// \param Clauses List of clauses.
3431  /// \param AssociatedStmt Statement, associated with the directive.
3432  /// \param Exprs Helper expressions for CodeGen.
3433  ///
3434  static OMPTeamsDistributeDirective *
3435  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3436         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3437         Stmt *AssociatedStmt, const HelperExprs &Exprs);
3438
3439  /// Creates an empty directive with the place for \a NumClauses clauses.
3440  ///
3441  /// \param C AST context.
3442  /// \param CollapsedNum Number of collapsed nested loops.
3443  /// \param NumClauses Number of clauses.
3444  ///
3445  static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C,
3446                                                  unsigned NumClauses,
3447                                                  unsigned CollapsedNum,
3448                                                  EmptyShell);
3449
3450  static bool classof(const Stmt *T) {
3451    return T->getStmtClass() == OMPTeamsDistributeDirectiveClass;
3452  }
3453};
3454
3455/// This represents '#pragma omp teams distribute simd'
3456/// combined directive.
3457///
3458/// \code
3459/// #pragma omp teams distribute simd private(a,b)
3460/// \endcode
3461/// In this example directive '#pragma omp teams distribute simd'
3462/// has clause 'private' with the variables 'a' and 'b'
3463///
3464class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective {
3465  friend class ASTStmtReader;
3466
3467  /// Build directive with the given start and end location.
3468  ///
3469  /// \param StartLoc Starting location of the directive kind.
3470  /// \param EndLoc Ending location of the directive.
3471  /// \param CollapsedNum Number of collapsed nested loops.
3472  /// \param NumClauses Number of clauses.
3473  ///
3474  OMPTeamsDistributeSimdDirective(SourceLocation StartLoc,
3475                                  SourceLocation EndLoc, unsigned CollapsedNum,
3476                                  unsigned NumClauses)
3477      : OMPLoopDirective(this, OMPTeamsDistributeSimdDirectiveClass,
3478                         OMPD_teams_distribute_simd, StartLoc, EndLoc,
3479                         CollapsedNum, NumClauses) {}
3480
3481  /// Build an empty directive.
3482  ///
3483  /// \param CollapsedNum Number of collapsed nested loops.
3484  /// \param NumClauses Number of clauses.
3485  ///
3486  explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum,
3487                                           unsigned NumClauses)
3488      : OMPLoopDirective(this, OMPTeamsDistributeSimdDirectiveClass,
3489                         OMPD_teams_distribute_simd, SourceLocation(),
3490                         SourceLocation(), CollapsedNum, NumClauses) {}
3491
3492public:
3493  /// Creates directive with a list of \a Clauses.
3494  ///
3495  /// \param C AST context.
3496  /// \param StartLoc Starting location of the directive kind.
3497  /// \param EndLoc Ending Location of the directive.
3498  /// \param CollapsedNum Number of collapsed loops.
3499  /// \param Clauses List of clauses.
3500  /// \param AssociatedStmt Statement, associated with the directive.
3501  /// \param Exprs Helper expressions for CodeGen.
3502  ///
3503  static OMPTeamsDistributeSimdDirective *
3504  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3505         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3506         Stmt *AssociatedStmt, const HelperExprs &Exprs);
3507
3508  /// Creates an empty directive with the place
3509  /// for \a NumClauses clauses.
3510  ///
3511  /// \param C AST context.
3512  /// \param CollapsedNum Number of collapsed nested loops.
3513  /// \param NumClauses Number of clauses.
3514  ///
3515  static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C,
3516                                                      unsigned NumClauses,
3517                                                      unsigned CollapsedNum,
3518                                                      EmptyShell);
3519
3520  static bool classof(const Stmt *T) {
3521    return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass;
3522  }
3523};
3524
3525/// This represents '#pragma omp teams distribute parallel for simd' composite
3526/// directive.
3527///
3528/// \code
3529/// #pragma omp teams distribute parallel for simd private(x)
3530/// \endcode
3531/// In this example directive '#pragma omp teams distribute parallel for simd'
3532/// has clause 'private' with the variables 'x'
3533///
3534class OMPTeamsDistributeParallelForSimdDirective final
3535    : public OMPLoopDirective {
3536  friend class ASTStmtReader;
3537
3538  /// Build directive with the given start and end location.
3539  ///
3540  /// \param StartLoc Starting location of the directive kind.
3541  /// \param EndLoc Ending location of the directive.
3542  /// \param CollapsedNum Number of collapsed nested loops.
3543  /// \param NumClauses Number of clauses.
3544  ///
3545  OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
3546                                             SourceLocation EndLoc,
3547                                             unsigned CollapsedNum,
3548                                             unsigned NumClauses)
3549      : OMPLoopDirective(this, OMPTeamsDistributeParallelForSimdDirectiveClass,
3550                         OMPD_teams_distribute_parallel_for_simd, StartLoc,
3551                         EndLoc, CollapsedNum, NumClauses) {}
3552
3553  /// Build an empty directive.
3554  ///
3555  /// \param CollapsedNum Number of collapsed nested loops.
3556  /// \param NumClauses Number of clauses.
3557  ///
3558  explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum,
3559                                                      unsigned NumClauses)
3560      : OMPLoopDirective(this, OMPTeamsDistributeParallelForSimdDirectiveClass,
3561                         OMPD_teams_distribute_parallel_for_simd,
3562                         SourceLocation(), SourceLocation(), CollapsedNum,
3563                         NumClauses) {}
3564
3565public:
3566  /// Creates directive with a list of \a Clauses.
3567  ///
3568  /// \param C AST context.
3569  /// \param StartLoc Starting location of the directive kind.
3570  /// \param EndLoc Ending Location of the directive.
3571  /// \param CollapsedNum Number of collapsed loops.
3572  /// \param Clauses List of clauses.
3573  /// \param AssociatedStmt Statement, associated with the directive.
3574  /// \param Exprs Helper expressions for CodeGen.
3575  ///
3576  static OMPTeamsDistributeParallelForSimdDirective *
3577  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3578         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3579         Stmt *AssociatedStmt, const HelperExprs &Exprs);
3580
3581  /// Creates an empty directive with the place for \a NumClauses clauses.
3582  ///
3583  /// \param C AST context.
3584  /// \param CollapsedNum Number of collapsed nested loops.
3585  /// \param NumClauses Number of clauses.
3586  ///
3587  static OMPTeamsDistributeParallelForSimdDirective *
3588  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
3589              EmptyShell);
3590
3591  static bool classof(const Stmt *T) {
3592    return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass;
3593  }
3594};
3595
3596/// This represents '#pragma omp teams distribute parallel for' composite
3597/// directive.
3598///
3599/// \code
3600/// #pragma omp teams distribute parallel for private(x)
3601/// \endcode
3602/// In this example directive '#pragma omp teams distribute parallel for'
3603/// has clause 'private' with the variables 'x'
3604///
3605class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
3606  friend class ASTStmtReader;
3607  /// true if the construct has inner cancel directive.
3608  bool HasCancel = false;
3609
3610  /// Build directive with the given start and end location.
3611  ///
3612  /// \param StartLoc Starting location of the directive kind.
3613  /// \param EndLoc Ending location of the directive.
3614  /// \param CollapsedNum Number of collapsed nested loops.
3615  /// \param NumClauses Number of clauses.
3616  ///
3617  OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc,
3618                                         SourceLocation EndLoc,
3619                                         unsigned CollapsedNum,
3620                                         unsigned NumClauses)
3621      : OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass,
3622                         OMPD_teams_distribute_parallel_for, StartLoc, EndLoc,
3623                         CollapsedNum, NumClauses), HasCancel(false) {}
3624
3625  /// Build an empty directive.
3626  ///
3627  /// \param CollapsedNum Number of collapsed nested loops.
3628  /// \param NumClauses Number of clauses.
3629  ///
3630  explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum,
3631                                                  unsigned NumClauses)
3632      : OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass,
3633                         OMPD_teams_distribute_parallel_for, SourceLocation(),
3634                         SourceLocation(), CollapsedNum, NumClauses),
3635        HasCancel(false) {}
3636
3637  /// Set cancel state.
3638  void setHasCancel(bool Has) { HasCancel = Has; }
3639
3640public:
3641  /// Creates directive with a list of \a Clauses.
3642  ///
3643  /// \param C AST context.
3644  /// \param StartLoc Starting location of the directive kind.
3645  /// \param EndLoc Ending Location of the directive.
3646  /// \param CollapsedNum Number of collapsed loops.
3647  /// \param Clauses List of clauses.
3648  /// \param AssociatedStmt Statement, associated with the directive.
3649  /// \param Exprs Helper expressions for CodeGen.
3650  /// \param HasCancel true if this directive has inner cancel directive.
3651  ///
3652  static OMPTeamsDistributeParallelForDirective *
3653  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3654         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3655         Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3656
3657  /// Creates an empty directive with the place for \a NumClauses clauses.
3658  ///
3659  /// \param C AST context.
3660  /// \param CollapsedNum Number of collapsed nested loops.
3661  /// \param NumClauses Number of clauses.
3662  ///
3663  static OMPTeamsDistributeParallelForDirective *
3664  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
3665              EmptyShell);
3666
3667  /// Return true if current directive has inner cancel directive.
3668  bool hasCancel() const { return HasCancel; }
3669
3670  static bool classof(const Stmt *T) {
3671    return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass;
3672  }
3673};
3674
3675/// This represents '#pragma omp target teams' directive.
3676///
3677/// \code
3678/// #pragma omp target teams if(a>0)
3679/// \endcode
3680/// In this example directive '#pragma omp target teams' has clause 'if' with
3681/// condition 'a>0'.
3682///
3683class OMPTargetTeamsDirective final : public OMPExecutableDirective {
3684  friend class ASTStmtReader;
3685  /// Build directive with the given start and end location.
3686  ///
3687  /// \param StartLoc Starting location of the directive kind.
3688  /// \param EndLoc Ending location of the directive.
3689  /// \param NumClauses Number of clauses.
3690  ///
3691  OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3692                          unsigned NumClauses)
3693      : OMPExecutableDirective(this, OMPTargetTeamsDirectiveClass,
3694                               OMPD_target_teams, StartLoc, EndLoc, NumClauses,
3695                               1) {}
3696
3697  /// Build an empty directive.
3698  ///
3699  /// \param NumClauses Number of clauses.
3700  ///
3701  explicit OMPTargetTeamsDirective(unsigned NumClauses)
3702      : OMPExecutableDirective(this, OMPTargetTeamsDirectiveClass,
3703                               OMPD_target_teams, SourceLocation(),
3704                               SourceLocation(), NumClauses, 1) {}
3705
3706public:
3707  /// Creates directive with a list of \a Clauses.
3708  ///
3709  /// \param C AST context.
3710  /// \param StartLoc Starting location of the directive kind.
3711  /// \param EndLoc Ending Location of the directive.
3712  /// \param Clauses List of clauses.
3713  /// \param AssociatedStmt Statement, associated with the directive.
3714  ///
3715  static OMPTargetTeamsDirective *Create(const ASTContext &C,
3716                                         SourceLocation StartLoc,
3717                                         SourceLocation EndLoc,
3718                                         ArrayRef<OMPClause *> Clauses,
3719                                         Stmt *AssociatedStmt);
3720
3721  /// Creates an empty directive with the place for \a NumClauses clauses.
3722  ///
3723  /// \param C AST context.
3724  /// \param NumClauses Number of clauses.
3725  ///
3726  static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C,
3727                                              unsigned NumClauses, EmptyShell);
3728
3729  static bool classof(const Stmt *T) {
3730    return T->getStmtClass() == OMPTargetTeamsDirectiveClass;
3731  }
3732};
3733
3734/// This represents '#pragma omp target teams distribute' combined directive.
3735///
3736/// \code
3737/// #pragma omp target teams distribute private(x)
3738/// \endcode
3739/// In this example directive '#pragma omp target teams distribute' has clause
3740/// 'private' with the variables 'x'
3741///
3742class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective {
3743  friend class ASTStmtReader;
3744
3745  /// Build directive with the given start and end location.
3746  ///
3747  /// \param StartLoc Starting location of the directive kind.
3748  /// \param EndLoc Ending location of the directive.
3749  /// \param CollapsedNum Number of collapsed nested loops.
3750  /// \param NumClauses Number of clauses.
3751  ///
3752  OMPTargetTeamsDistributeDirective(SourceLocation StartLoc,
3753                                    SourceLocation EndLoc,
3754                                    unsigned CollapsedNum, unsigned NumClauses)
3755      : OMPLoopDirective(this, OMPTargetTeamsDistributeDirectiveClass,
3756                         OMPD_target_teams_distribute, StartLoc, EndLoc,
3757                         CollapsedNum, NumClauses) {}
3758
3759  /// Build an empty directive.
3760  ///
3761  /// \param CollapsedNum Number of collapsed nested loops.
3762  /// \param NumClauses Number of clauses.
3763  ///
3764  explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum,
3765                                             unsigned NumClauses)
3766      : OMPLoopDirective(this, OMPTargetTeamsDistributeDirectiveClass,
3767                         OMPD_target_teams_distribute, SourceLocation(),
3768                         SourceLocation(), CollapsedNum, NumClauses) {}
3769
3770public:
3771  /// Creates directive with a list of \a Clauses.
3772  ///
3773  /// \param C AST context.
3774  /// \param StartLoc Starting location of the directive kind.
3775  /// \param EndLoc Ending Location of the directive.
3776  /// \param CollapsedNum Number of collapsed loops.
3777  /// \param Clauses List of clauses.
3778  /// \param AssociatedStmt Statement, associated with the directive.
3779  /// \param Exprs Helper expressions for CodeGen.
3780  ///
3781  static OMPTargetTeamsDistributeDirective *
3782  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3783         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3784         Stmt *AssociatedStmt, const HelperExprs &Exprs);
3785
3786  /// Creates an empty directive with the place for \a NumClauses clauses.
3787  ///
3788  /// \param C AST context.
3789  /// \param CollapsedNum Number of collapsed nested loops.
3790  /// \param NumClauses Number of clauses.
3791  ///
3792  static OMPTargetTeamsDistributeDirective *
3793  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
3794              EmptyShell);
3795
3796  static bool classof(const Stmt *T) {
3797    return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass;
3798  }
3799};
3800
3801/// This represents '#pragma omp target teams distribute parallel for' combined
3802/// directive.
3803///
3804/// \code
3805/// #pragma omp target teams distribute parallel for private(x)
3806/// \endcode
3807/// In this example directive '#pragma omp target teams distribute parallel
3808/// for' has clause 'private' with the variables 'x'
3809///
3810class OMPTargetTeamsDistributeParallelForDirective final
3811    : public OMPLoopDirective {
3812  friend class ASTStmtReader;
3813  /// true if the construct has inner cancel directive.
3814  bool HasCancel = false;
3815
3816  /// Build directive with the given start and end location.
3817  ///
3818  /// \param StartLoc Starting location of the directive kind.
3819  /// \param EndLoc Ending location of the directive.
3820  /// \param CollapsedNum Number of collapsed nested loops.
3821  /// \param NumClauses Number of clauses.
3822  ///
3823  OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc,
3824                                               SourceLocation EndLoc,
3825                                               unsigned CollapsedNum,
3826                                               unsigned NumClauses)
3827      : OMPLoopDirective(this,
3828                         OMPTargetTeamsDistributeParallelForDirectiveClass,
3829                         OMPD_target_teams_distribute_parallel_for, StartLoc,
3830                         EndLoc, CollapsedNum, NumClauses),
3831        HasCancel(false) {}
3832
3833  /// Build an empty directive.
3834  ///
3835  /// \param CollapsedNum Number of collapsed nested loops.
3836  /// \param NumClauses Number of clauses.
3837  ///
3838  explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum,
3839                                                        unsigned NumClauses)
3840      : OMPLoopDirective(
3841            this, OMPTargetTeamsDistributeParallelForDirectiveClass,
3842            OMPD_target_teams_distribute_parallel_for, SourceLocation(),
3843            SourceLocation(), CollapsedNum, NumClauses),
3844        HasCancel(false) {}
3845
3846  /// Set cancel state.
3847  void setHasCancel(bool Has) { HasCancel = Has; }
3848
3849public:
3850  /// Creates directive with a list of \a Clauses.
3851  ///
3852  /// \param C AST context.
3853  /// \param StartLoc Starting location of the directive kind.
3854  /// \param EndLoc Ending Location of the directive.
3855  /// \param CollapsedNum Number of collapsed loops.
3856  /// \param Clauses List of clauses.
3857  /// \param AssociatedStmt Statement, associated with the directive.
3858  /// \param Exprs Helper expressions for CodeGen.
3859  /// \param HasCancel true if this directive has inner cancel directive.
3860  ///
3861  static OMPTargetTeamsDistributeParallelForDirective *
3862  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3863         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3864         Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
3865
3866  /// Creates an empty directive with the place for \a NumClauses clauses.
3867  ///
3868  /// \param C AST context.
3869  /// \param CollapsedNum Number of collapsed nested loops.
3870  /// \param NumClauses Number of clauses.
3871  ///
3872  static OMPTargetTeamsDistributeParallelForDirective *
3873  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
3874              EmptyShell);
3875
3876  /// Return true if current directive has inner cancel directive.
3877  bool hasCancel() const { return HasCancel; }
3878
3879  static bool classof(const Stmt *T) {
3880    return T->getStmtClass() ==
3881           OMPTargetTeamsDistributeParallelForDirectiveClass;
3882  }
3883};
3884
3885/// This represents '#pragma omp target teams distribute parallel for simd'
3886/// combined directive.
3887///
3888/// \code
3889/// #pragma omp target teams distribute parallel for simd private(x)
3890/// \endcode
3891/// In this example directive '#pragma omp target teams distribute parallel
3892/// for simd' has clause 'private' with the variables 'x'
3893///
3894class OMPTargetTeamsDistributeParallelForSimdDirective final
3895    : public OMPLoopDirective {
3896  friend class ASTStmtReader;
3897
3898  /// Build directive with the given start and end location.
3899  ///
3900  /// \param StartLoc Starting location of the directive kind.
3901  /// \param EndLoc Ending location of the directive.
3902  /// \param CollapsedNum Number of collapsed nested loops.
3903  /// \param NumClauses Number of clauses.
3904  ///
3905  OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
3906                                                   SourceLocation EndLoc,
3907                                                   unsigned CollapsedNum,
3908                                                   unsigned NumClauses)
3909      : OMPLoopDirective(this,
3910                         OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
3911                         OMPD_target_teams_distribute_parallel_for_simd,
3912                         StartLoc, EndLoc, CollapsedNum, NumClauses) {}
3913
3914  /// Build an empty directive.
3915  ///
3916  /// \param CollapsedNum Number of collapsed nested loops.
3917  /// \param NumClauses Number of clauses.
3918  ///
3919  explicit OMPTargetTeamsDistributeParallelForSimdDirective(
3920      unsigned CollapsedNum, unsigned NumClauses)
3921      : OMPLoopDirective(
3922            this, OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
3923            OMPD_target_teams_distribute_parallel_for_simd, SourceLocation(),
3924            SourceLocation(), CollapsedNum, NumClauses) {}
3925
3926public:
3927  /// Creates directive with a list of \a Clauses.
3928  ///
3929  /// \param C AST context.
3930  /// \param StartLoc Starting location of the directive kind.
3931  /// \param EndLoc Ending Location of the directive.
3932  /// \param CollapsedNum Number of collapsed loops.
3933  /// \param Clauses List of clauses.
3934  /// \param AssociatedStmt Statement, associated with the directive.
3935  /// \param Exprs Helper expressions for CodeGen.
3936  ///
3937  static OMPTargetTeamsDistributeParallelForSimdDirective *
3938  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3939         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3940         Stmt *AssociatedStmt, const HelperExprs &Exprs);
3941
3942  /// Creates an empty directive with the place for \a NumClauses clauses.
3943  ///
3944  /// \param C AST context.
3945  /// \param CollapsedNum Number of collapsed nested loops.
3946  /// \param NumClauses Number of clauses.
3947  ///
3948  static OMPTargetTeamsDistributeParallelForSimdDirective *
3949  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
3950              EmptyShell);
3951
3952  static bool classof(const Stmt *T) {
3953    return T->getStmtClass() ==
3954           OMPTargetTeamsDistributeParallelForSimdDirectiveClass;
3955  }
3956};
3957
3958/// This represents '#pragma omp target teams distribute simd' combined
3959/// directive.
3960///
3961/// \code
3962/// #pragma omp target teams distribute simd private(x)
3963/// \endcode
3964/// In this example directive '#pragma omp target teams distribute simd'
3965/// has clause 'private' with the variables 'x'
3966///
3967class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective {
3968  friend class ASTStmtReader;
3969
3970  /// Build directive with the given start and end location.
3971  ///
3972  /// \param StartLoc Starting location of the directive kind.
3973  /// \param EndLoc Ending location of the directive.
3974  /// \param CollapsedNum Number of collapsed nested loops.
3975  /// \param NumClauses Number of clauses.
3976  ///
3977  OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc,
3978                                        SourceLocation EndLoc,
3979                                        unsigned CollapsedNum,
3980                                        unsigned NumClauses)
3981      : OMPLoopDirective(this, OMPTargetTeamsDistributeSimdDirectiveClass,
3982                         OMPD_target_teams_distribute_simd, StartLoc, EndLoc,
3983                         CollapsedNum, NumClauses) {}
3984
3985  /// Build an empty directive.
3986  ///
3987  /// \param CollapsedNum Number of collapsed nested loops.
3988  /// \param NumClauses Number of clauses.
3989  ///
3990  explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum,
3991                                                 unsigned NumClauses)
3992      : OMPLoopDirective(this, OMPTargetTeamsDistributeSimdDirectiveClass,
3993                         OMPD_target_teams_distribute_simd, SourceLocation(),
3994                         SourceLocation(), CollapsedNum, NumClauses) {}
3995
3996public:
3997  /// Creates directive with a list of \a Clauses.
3998  ///
3999  /// \param C AST context.
4000  /// \param StartLoc Starting location of the directive kind.
4001  /// \param EndLoc Ending Location of the directive.
4002  /// \param CollapsedNum Number of collapsed loops.
4003  /// \param Clauses List of clauses.
4004  /// \param AssociatedStmt Statement, associated with the directive.
4005  /// \param Exprs Helper expressions for CodeGen.
4006  ///
4007  static OMPTargetTeamsDistributeSimdDirective *
4008  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
4009         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
4010         Stmt *AssociatedStmt, const HelperExprs &Exprs);
4011
4012  /// Creates an empty directive with the place for \a NumClauses clauses.
4013  ///
4014  /// \param C AST context.
4015  /// \param CollapsedNum Number of collapsed nested loops.
4016  /// \param NumClauses Number of clauses.
4017  ///
4018  static OMPTargetTeamsDistributeSimdDirective *
4019  CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
4020              EmptyShell);
4021
4022  static bool classof(const Stmt *T) {
4023    return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
4024  }
4025};
4026
4027} // end namespace clang
4028
4029#endif
4030