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