1//===- StmtOpenMP.h - Classes for OpenMP directives  ------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9/// \file
10/// \brief This file defines OpenMP AST classes for executable directives and
11/// clauses.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_AST_STMTOPENMP_H
16#define LLVM_CLANG_AST_STMTOPENMP_H
17
18#include "clang/AST/Expr.h"
19#include "clang/AST/OpenMPClause.h"
20#include "clang/AST/Stmt.h"
21#include "clang/Basic/OpenMPKinds.h"
22#include "clang/Basic/SourceLocation.h"
23
24namespace clang {
25
26//===----------------------------------------------------------------------===//
27// AST classes for directives.
28//===----------------------------------------------------------------------===//
29
30/// \brief This is a basic class for representing single OpenMP executable
31/// directive.
32///
33class OMPExecutableDirective : public Stmt {
34  friend class ASTStmtReader;
35  /// \brief Kind of the directive.
36  OpenMPDirectiveKind Kind;
37  /// \brief Starting location of the directive (directive keyword).
38  SourceLocation StartLoc;
39  /// \brief Ending location of the directive.
40  SourceLocation EndLoc;
41  /// \brief Numbers of clauses.
42  const unsigned NumClauses;
43  /// \brief Number of child expressions/stmts.
44  const unsigned NumChildren;
45  /// \brief Offset from this to the start of clauses.
46  /// There are NumClauses pointers to clauses, they are followed by
47  /// NumChildren pointers to child stmts/exprs (if the directive type
48  /// requires an associated stmt, then it has to be the first of them).
49  const unsigned ClausesOffset;
50
51  /// \brief Get the clauses storage.
52  MutableArrayRef<OMPClause *> getClauses() {
53    OMPClause **ClauseStorage = reinterpret_cast<OMPClause **>(
54        reinterpret_cast<char *>(this) + ClausesOffset);
55    return MutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);
56  }
57
58protected:
59  /// \brief Build instance of directive of class \a K.
60  ///
61  /// \param SC Statement class.
62  /// \param K Kind of OpenMP directive.
63  /// \param StartLoc Starting location of the directive (directive keyword).
64  /// \param EndLoc Ending location of the directive.
65  ///
66  template <typename T>
67  OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K,
68                         SourceLocation StartLoc, SourceLocation EndLoc,
69                         unsigned NumClauses, unsigned NumChildren)
70      : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
71        EndLoc(std::move(EndLoc)), NumClauses(NumClauses),
72        NumChildren(NumChildren),
73        ClausesOffset(llvm::alignTo(sizeof(T), llvm::alignOf<OMPClause *>())) {}
74
75  /// \brief Sets the list of variables for this clause.
76  ///
77  /// \param Clauses The list of clauses for the directive.
78  ///
79  void setClauses(ArrayRef<OMPClause *> Clauses);
80
81  /// \brief Set the associated statement for the directive.
82  ///
83  /// /param S Associated statement.
84  ///
85  void setAssociatedStmt(Stmt *S) {
86    assert(hasAssociatedStmt() && "no associated statement.");
87    *child_begin() = S;
88  }
89
90public:
91  /// \brief Iterates over a filtered subrange of clauses applied to a
92  /// directive.
93  ///
94  /// This iterator visits only clauses of type SpecificClause.
95  template <typename SpecificClause>
96  class specific_clause_iterator
97      : public llvm::iterator_adaptor_base<
98            specific_clause_iterator<SpecificClause>,
99            ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag,
100            const SpecificClause *, ptrdiff_t, const SpecificClause *,
101            const SpecificClause *> {
102    ArrayRef<OMPClause *>::const_iterator End;
103
104    void SkipToNextClause() {
105      while (this->I != End && !isa<SpecificClause>(*this->I))
106        ++this->I;
107    }
108
109  public:
110    explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses)
111        : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()),
112          End(Clauses.end()) {
113      SkipToNextClause();
114    }
115
116    const SpecificClause *operator*() const {
117      return cast<SpecificClause>(*this->I);
118    }
119    const SpecificClause *operator->() const { return **this; }
120
121    specific_clause_iterator &operator++() {
122      ++this->I;
123      SkipToNextClause();
124      return *this;
125    }
126  };
127
128  template <typename SpecificClause>
129  static llvm::iterator_range<specific_clause_iterator<SpecificClause>>
130  getClausesOfKind(ArrayRef<OMPClause *> Clauses) {
131    return {specific_clause_iterator<SpecificClause>(Clauses),
132            specific_clause_iterator<SpecificClause>(
133                llvm::makeArrayRef(Clauses.end(), 0))};
134  }
135
136  template <typename SpecificClause>
137  llvm::iterator_range<specific_clause_iterator<SpecificClause>>
138  getClausesOfKind() const {
139    return getClausesOfKind<SpecificClause>(clauses());
140  }
141
142  /// Gets a single clause of the specified kind associated with the
143  /// current directive iff there is only one clause of this kind (and assertion
144  /// is fired if there is more than one clause is associated with the
145  /// directive). Returns nullptr if no clause of this kind is associated with
146  /// the directive.
147  template <typename SpecificClause>
148  const SpecificClause *getSingleClause() const {
149    auto Clauses = getClausesOfKind<SpecificClause>();
150
151    if (Clauses.begin() != Clauses.end()) {
152      assert(std::next(Clauses.begin()) == Clauses.end() &&
153             "There are at least 2 clauses of the specified kind");
154      return *Clauses.begin();
155    }
156    return nullptr;
157  }
158
159  /// Returns true if the current directive has one or more clauses of a
160  /// specific kind.
161  template <typename SpecificClause>
162  bool hasClausesOfKind() const {
163    auto Clauses = getClausesOfKind<SpecificClause>();
164    return Clauses.begin() != Clauses.end();
165  }
166
167  /// \brief Returns starting location of directive kind.
168  SourceLocation getLocStart() const { return StartLoc; }
169  /// \brief Returns ending location of directive.
170  SourceLocation getLocEnd() const { return EndLoc; }
171
172  /// \brief Set starting location of directive kind.
173  ///
174  /// \param Loc New starting location of directive.
175  ///
176  void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
177  /// \brief Set ending location of directive.
178  ///
179  /// \param Loc New ending location of directive.
180  ///
181  void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
182
183  /// \brief Get number of clauses.
184  unsigned getNumClauses() const { return NumClauses; }
185
186  /// \brief Returns specified clause.
187  ///
188  /// \param i Number of clause.
189  ///
190  OMPClause *getClause(unsigned i) const { return clauses()[i]; }
191
192  /// \brief Returns true if directive has associated statement.
193  bool hasAssociatedStmt() const { return NumChildren > 0; }
194
195  /// \brief Returns statement associated with the directive.
196  Stmt *getAssociatedStmt() const {
197    assert(hasAssociatedStmt() && "no associated statement.");
198    return const_cast<Stmt *>(*child_begin());
199  }
200
201  OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
202
203  static bool classof(const Stmt *S) {
204    return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
205           S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
206  }
207
208  child_range children() {
209    if (!hasAssociatedStmt())
210      return child_range(child_iterator(), child_iterator());
211    Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
212    return child_range(ChildStorage, ChildStorage + NumChildren);
213  }
214
215  ArrayRef<OMPClause *> clauses() { return getClauses(); }
216
217  ArrayRef<OMPClause *> clauses() const {
218    return const_cast<OMPExecutableDirective *>(this)->getClauses();
219  }
220};
221
222/// \brief This represents '#pragma omp parallel' directive.
223///
224/// \code
225/// #pragma omp parallel private(a,b) reduction(+: c,d)
226/// \endcode
227/// In this example directive '#pragma omp parallel' has clauses 'private'
228/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
229/// variables 'c' and 'd'.
230///
231class OMPParallelDirective : public OMPExecutableDirective {
232  friend class ASTStmtReader;
233  /// \brief true if the construct has inner cancel directive.
234  bool HasCancel;
235
236  /// \brief Build directive with the given start and end location.
237  ///
238  /// \param StartLoc Starting location of the directive (directive keyword).
239  /// \param EndLoc Ending Location of the directive.
240  ///
241  OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
242                       unsigned NumClauses)
243      : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
244                               StartLoc, EndLoc, NumClauses, 1),
245        HasCancel(false) {}
246
247  /// \brief Build an empty directive.
248  ///
249  /// \param NumClauses Number of clauses.
250  ///
251  explicit OMPParallelDirective(unsigned NumClauses)
252      : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
253                               SourceLocation(), SourceLocation(), NumClauses,
254                               1),
255        HasCancel(false) {}
256
257  /// \brief Set cancel state.
258  void setHasCancel(bool Has) { HasCancel = Has; }
259
260public:
261  /// \brief Creates directive with a list of \a Clauses.
262  ///
263  /// \param C AST context.
264  /// \param StartLoc Starting location of the directive kind.
265  /// \param EndLoc Ending Location of the directive.
266  /// \param Clauses List of clauses.
267  /// \param AssociatedStmt Statement associated with the directive.
268  /// \param HasCancel true if this directive has inner cancel directive.
269  ///
270  static OMPParallelDirective *
271  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
272         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
273
274  /// \brief Creates an empty directive with the place for \a N clauses.
275  ///
276  /// \param C AST context.
277  /// \param NumClauses Number of clauses.
278  ///
279  static OMPParallelDirective *CreateEmpty(const ASTContext &C,
280                                           unsigned NumClauses, EmptyShell);
281
282  /// \brief Return true if current directive has inner cancel directive.
283  bool hasCancel() const { return HasCancel; }
284
285  static bool classof(const Stmt *T) {
286    return T->getStmtClass() == OMPParallelDirectiveClass;
287  }
288};
289
290/// \brief This is a common base class for loop directives ('omp simd', 'omp
291/// for', 'omp for simd' etc.). It is responsible for the loop code generation.
292///
293class OMPLoopDirective : public OMPExecutableDirective {
294  friend class ASTStmtReader;
295  /// \brief Number of collapsed loops as specified by 'collapse' clause.
296  unsigned CollapsedNum;
297
298  /// \brief Offsets to the stored exprs.
299  /// This enumeration contains offsets to all the pointers to children
300  /// expressions stored in OMPLoopDirective.
301  /// The first 9 children are nesessary for all the loop directives, and
302  /// the next 10 are specific to the worksharing ones.
303  /// After the fixed children, three arrays of length CollapsedNum are
304  /// allocated: loop counters, their updates and final values.
305  /// PrevLowerBound and PrevUpperBound are used to communicate blocking
306  /// information in composite constructs which require loop blocking
307  ///
308  enum {
309    AssociatedStmtOffset = 0,
310    IterationVariableOffset = 1,
311    LastIterationOffset = 2,
312    CalcLastIterationOffset = 3,
313    PreConditionOffset = 4,
314    CondOffset = 5,
315    InitOffset = 6,
316    IncOffset = 7,
317    PreInitsOffset = 8,
318    // The '...End' enumerators do not correspond to child expressions - they
319    // specify the offset to the end (and start of the following counters/
320    // updates/finals arrays).
321    DefaultEnd = 9,
322    // The following 7 exprs are used by worksharing loops only.
323    IsLastIterVariableOffset = 9,
324    LowerBoundVariableOffset = 10,
325    UpperBoundVariableOffset = 11,
326    StrideVariableOffset = 12,
327    EnsureUpperBoundOffset = 13,
328    NextLowerBoundOffset = 14,
329    NextUpperBoundOffset = 15,
330    NumIterationsOffset = 16,
331    PrevLowerBoundVariableOffset = 17,
332    PrevUpperBoundVariableOffset = 18,
333    // Offset to the end (and start of the following counters/updates/finals
334    // arrays) for worksharing loop directives.
335    WorksharingEnd = 19,
336  };
337
338  /// \brief Get the counters storage.
339  MutableArrayRef<Expr *> getCounters() {
340    Expr **Storage = reinterpret_cast<Expr **>(
341        &(*(std::next(child_begin(), getArraysOffset(getDirectiveKind())))));
342    return MutableArrayRef<Expr *>(Storage, CollapsedNum);
343  }
344
345  /// \brief Get the private counters storage.
346  MutableArrayRef<Expr *> getPrivateCounters() {
347    Expr **Storage = reinterpret_cast<Expr **>(&*std::next(
348        child_begin(), getArraysOffset(getDirectiveKind()) + CollapsedNum));
349    return MutableArrayRef<Expr *>(Storage, CollapsedNum);
350  }
351
352  /// \brief Get the updates storage.
353  MutableArrayRef<Expr *> getInits() {
354    Expr **Storage = reinterpret_cast<Expr **>(
355        &*std::next(child_begin(),
356                    getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum));
357    return MutableArrayRef<Expr *>(Storage, CollapsedNum);
358  }
359
360  /// \brief Get the updates storage.
361  MutableArrayRef<Expr *> getUpdates() {
362    Expr **Storage = reinterpret_cast<Expr **>(
363        &*std::next(child_begin(),
364                    getArraysOffset(getDirectiveKind()) + 3 * CollapsedNum));
365    return MutableArrayRef<Expr *>(Storage, CollapsedNum);
366  }
367
368  /// \brief Get the final counter updates storage.
369  MutableArrayRef<Expr *> getFinals() {
370    Expr **Storage = reinterpret_cast<Expr **>(
371        &*std::next(child_begin(),
372                    getArraysOffset(getDirectiveKind()) + 4 * CollapsedNum));
373    return MutableArrayRef<Expr *>(Storage, CollapsedNum);
374  }
375
376protected:
377  /// \brief Build instance of loop directive of class \a Kind.
378  ///
379  /// \param SC Statement class.
380  /// \param Kind Kind of OpenMP directive.
381  /// \param StartLoc Starting location of the directive (directive keyword).
382  /// \param EndLoc Ending location of the directive.
383  /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
384  /// \param NumClauses Number of clauses.
385  /// \param NumSpecialChildren Number of additional directive-specific stmts.
386  ///
387  template <typename T>
388  OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind,
389                   SourceLocation StartLoc, SourceLocation EndLoc,
390                   unsigned CollapsedNum, unsigned NumClauses,
391                   unsigned NumSpecialChildren = 0)
392      : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses,
393                               numLoopChildren(CollapsedNum, Kind) +
394                                   NumSpecialChildren),
395        CollapsedNum(CollapsedNum) {}
396
397  /// \brief Offset to the start of children expression arrays.
398  static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
399    return (isOpenMPWorksharingDirective(Kind) ||
400            isOpenMPTaskLoopDirective(Kind) ||
401            isOpenMPDistributeDirective(Kind))
402               ? WorksharingEnd
403               : DefaultEnd;
404  }
405
406  /// \brief Children number.
407  static unsigned numLoopChildren(unsigned CollapsedNum,
408                                  OpenMPDirectiveKind Kind) {
409    return getArraysOffset(Kind) + 5 * CollapsedNum; // Counters,
410                                                     // PrivateCounters, Inits,
411                                                     // Updates and Finals
412  }
413
414  void setIterationVariable(Expr *IV) {
415    *std::next(child_begin(), IterationVariableOffset) = IV;
416  }
417  void setLastIteration(Expr *LI) {
418    *std::next(child_begin(), LastIterationOffset) = LI;
419  }
420  void setCalcLastIteration(Expr *CLI) {
421    *std::next(child_begin(), CalcLastIterationOffset) = CLI;
422  }
423  void setPreCond(Expr *PC) {
424    *std::next(child_begin(), PreConditionOffset) = PC;
425  }
426  void setCond(Expr *Cond) {
427    *std::next(child_begin(), CondOffset) = Cond;
428  }
429  void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; }
430  void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; }
431  void setPreInits(Stmt *PreInits) {
432    *std::next(child_begin(), PreInitsOffset) = PreInits;
433  }
434  void setIsLastIterVariable(Expr *IL) {
435    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
436            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
437            isOpenMPDistributeDirective(getDirectiveKind())) &&
438           "expected worksharing loop directive");
439    *std::next(child_begin(), IsLastIterVariableOffset) = IL;
440  }
441  void setLowerBoundVariable(Expr *LB) {
442    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
443            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
444            isOpenMPDistributeDirective(getDirectiveKind())) &&
445           "expected worksharing loop directive");
446    *std::next(child_begin(), LowerBoundVariableOffset) = LB;
447  }
448  void setUpperBoundVariable(Expr *UB) {
449    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
450            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
451            isOpenMPDistributeDirective(getDirectiveKind())) &&
452           "expected worksharing loop directive");
453    *std::next(child_begin(), UpperBoundVariableOffset) = UB;
454  }
455  void setStrideVariable(Expr *ST) {
456    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
457            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
458            isOpenMPDistributeDirective(getDirectiveKind())) &&
459           "expected worksharing loop directive");
460    *std::next(child_begin(), StrideVariableOffset) = ST;
461  }
462  void setEnsureUpperBound(Expr *EUB) {
463    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
464            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
465            isOpenMPDistributeDirective(getDirectiveKind())) &&
466           "expected worksharing loop directive");
467    *std::next(child_begin(), EnsureUpperBoundOffset) = EUB;
468  }
469  void setNextLowerBound(Expr *NLB) {
470    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
471            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
472            isOpenMPDistributeDirective(getDirectiveKind())) &&
473           "expected worksharing loop directive");
474    *std::next(child_begin(), NextLowerBoundOffset) = NLB;
475  }
476  void setNextUpperBound(Expr *NUB) {
477    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
478            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
479            isOpenMPDistributeDirective(getDirectiveKind())) &&
480           "expected worksharing loop directive");
481    *std::next(child_begin(), NextUpperBoundOffset) = NUB;
482  }
483  void setNumIterations(Expr *NI) {
484    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
485            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
486            isOpenMPDistributeDirective(getDirectiveKind())) &&
487           "expected worksharing loop directive");
488    *std::next(child_begin(), NumIterationsOffset) = NI;
489  }
490  void setPrevLowerBoundVariable(Expr *PrevLB) {
491    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
492            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
493            isOpenMPDistributeDirective(getDirectiveKind())) &&
494           "expected worksharing loop directive");
495    *std::next(child_begin(), PrevLowerBoundVariableOffset) = PrevLB;
496  }
497  void setPrevUpperBoundVariable(Expr *PrevUB) {
498    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
499            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
500            isOpenMPDistributeDirective(getDirectiveKind())) &&
501           "expected worksharing loop directive");
502    *std::next(child_begin(), PrevUpperBoundVariableOffset) = PrevUB;
503  }
504  void setCounters(ArrayRef<Expr *> A);
505  void setPrivateCounters(ArrayRef<Expr *> A);
506  void setInits(ArrayRef<Expr *> A);
507  void setUpdates(ArrayRef<Expr *> A);
508  void setFinals(ArrayRef<Expr *> A);
509
510public:
511  /// \brief The expressions built for the OpenMP loop CodeGen for the
512  /// whole collapsed loop nest.
513  struct HelperExprs {
514    /// \brief Loop iteration variable.
515    Expr *IterationVarRef;
516    /// \brief Loop last iteration number.
517    Expr *LastIteration;
518    /// \brief Loop number of iterations.
519    Expr *NumIterations;
520    /// \brief Calculation of last iteration.
521    Expr *CalcLastIteration;
522    /// \brief Loop pre-condition.
523    Expr *PreCond;
524    /// \brief Loop condition.
525    Expr *Cond;
526    /// \brief Loop iteration variable init.
527    Expr *Init;
528    /// \brief Loop increment.
529    Expr *Inc;
530    /// \brief IsLastIteration - local flag variable passed to runtime.
531    Expr *IL;
532    /// \brief LowerBound - local variable passed to runtime.
533    Expr *LB;
534    /// \brief UpperBound - local variable passed to runtime.
535    Expr *UB;
536    /// \brief Stride - local variable passed to runtime.
537    Expr *ST;
538    /// \brief EnsureUpperBound -- expression LB = min(LB, NumIterations).
539    Expr *EUB;
540    /// \brief Update of LowerBound for statically sheduled 'omp for' loops.
541    Expr *NLB;
542    /// \brief Update of UpperBound for statically sheduled 'omp for' loops.
543    Expr *NUB;
544    /// \brief PreviousLowerBound - local variable passed to runtime in the
545    /// enclosing schedule or null if that does not apply.
546    Expr *PrevLB;
547    /// \brief PreviousUpperBound - local variable passed to runtime in the
548    /// enclosing schedule or null if that does not apply.
549    Expr *PrevUB;
550    /// \brief Counters Loop counters.
551    SmallVector<Expr *, 4> Counters;
552    /// \brief PrivateCounters Loop counters.
553    SmallVector<Expr *, 4> PrivateCounters;
554    /// \brief Expressions for loop counters inits for CodeGen.
555    SmallVector<Expr *, 4> Inits;
556    /// \brief Expressions for loop counters update for CodeGen.
557    SmallVector<Expr *, 4> Updates;
558    /// \brief Final loop counter values for GodeGen.
559    SmallVector<Expr *, 4> Finals;
560    /// Init statement for all captured expressions.
561    Stmt *PreInits;
562
563    /// \brief Check if all the expressions are built (does not check the
564    /// worksharing ones).
565    bool builtAll() {
566      return IterationVarRef != nullptr && LastIteration != nullptr &&
567             NumIterations != nullptr && PreCond != nullptr &&
568             Cond != nullptr && Init != nullptr && Inc != nullptr;
569    }
570
571    /// \brief Initialize all the fields to null.
572    /// \param Size Number of elements in the counters/finals/updates arrays.
573    void clear(unsigned Size) {
574      IterationVarRef = nullptr;
575      LastIteration = nullptr;
576      CalcLastIteration = nullptr;
577      PreCond = nullptr;
578      Cond = nullptr;
579      Init = nullptr;
580      Inc = nullptr;
581      IL = nullptr;
582      LB = nullptr;
583      UB = nullptr;
584      ST = nullptr;
585      EUB = nullptr;
586      NLB = nullptr;
587      NUB = nullptr;
588      NumIterations = nullptr;
589      PrevLB = nullptr;
590      PrevUB = nullptr;
591      Counters.resize(Size);
592      PrivateCounters.resize(Size);
593      Inits.resize(Size);
594      Updates.resize(Size);
595      Finals.resize(Size);
596      for (unsigned i = 0; i < Size; ++i) {
597        Counters[i] = nullptr;
598        PrivateCounters[i] = nullptr;
599        Inits[i] = nullptr;
600        Updates[i] = nullptr;
601        Finals[i] = nullptr;
602      }
603      PreInits = nullptr;
604    }
605  };
606
607  /// \brief Get number of collapsed loops.
608  unsigned getCollapsedNumber() const { return CollapsedNum; }
609
610  Expr *getIterationVariable() const {
611    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
612        *std::next(child_begin(), IterationVariableOffset)));
613  }
614  Expr *getLastIteration() const {
615    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
616        *std::next(child_begin(), LastIterationOffset)));
617  }
618  Expr *getCalcLastIteration() const {
619    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
620        *std::next(child_begin(), CalcLastIterationOffset)));
621  }
622  Expr *getPreCond() const {
623    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
624        *std::next(child_begin(), PreConditionOffset)));
625  }
626  Expr *getCond() const {
627    return const_cast<Expr *>(
628        reinterpret_cast<const Expr *>(*std::next(child_begin(), CondOffset)));
629  }
630  Expr *getInit() const {
631    return const_cast<Expr *>(
632        reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset)));
633  }
634  Expr *getInc() const {
635    return const_cast<Expr *>(
636        reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset)));
637  }
638  const Stmt *getPreInits() const {
639    return *std::next(child_begin(), PreInitsOffset);
640  }
641  Stmt *getPreInits() { return *std::next(child_begin(), PreInitsOffset); }
642  Expr *getIsLastIterVariable() const {
643    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
644            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
645            isOpenMPDistributeDirective(getDirectiveKind())) &&
646           "expected worksharing loop directive");
647    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
648        *std::next(child_begin(), IsLastIterVariableOffset)));
649  }
650  Expr *getLowerBoundVariable() const {
651    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
652            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
653            isOpenMPDistributeDirective(getDirectiveKind())) &&
654           "expected worksharing loop directive");
655    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
656        *std::next(child_begin(), LowerBoundVariableOffset)));
657  }
658  Expr *getUpperBoundVariable() const {
659    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
660            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
661            isOpenMPDistributeDirective(getDirectiveKind())) &&
662           "expected worksharing loop directive");
663    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
664        *std::next(child_begin(), UpperBoundVariableOffset)));
665  }
666  Expr *getStrideVariable() const {
667    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
668            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
669            isOpenMPDistributeDirective(getDirectiveKind())) &&
670           "expected worksharing loop directive");
671    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
672        *std::next(child_begin(), StrideVariableOffset)));
673  }
674  Expr *getEnsureUpperBound() const {
675    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
676            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
677            isOpenMPDistributeDirective(getDirectiveKind())) &&
678           "expected worksharing loop directive");
679    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
680        *std::next(child_begin(), EnsureUpperBoundOffset)));
681  }
682  Expr *getNextLowerBound() const {
683    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
684            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
685            isOpenMPDistributeDirective(getDirectiveKind())) &&
686           "expected worksharing loop directive");
687    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
688        *std::next(child_begin(), NextLowerBoundOffset)));
689  }
690  Expr *getNextUpperBound() const {
691    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
692            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
693            isOpenMPDistributeDirective(getDirectiveKind())) &&
694           "expected worksharing loop directive");
695    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
696        *std::next(child_begin(), NextUpperBoundOffset)));
697  }
698  Expr *getNumIterations() const {
699    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
700            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
701            isOpenMPDistributeDirective(getDirectiveKind())) &&
702           "expected worksharing loop directive");
703    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
704        *std::next(child_begin(), NumIterationsOffset)));
705  }
706  Expr *getPrevLowerBoundVariable() const {
707    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
708            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
709            isOpenMPDistributeDirective(getDirectiveKind())) &&
710           "expected worksharing loop directive");
711    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
712        *std::next(child_begin(), PrevLowerBoundVariableOffset)));
713  }
714  Expr *getPrevUpperBoundVariable() const {
715    assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
716            isOpenMPTaskLoopDirective(getDirectiveKind()) ||
717            isOpenMPDistributeDirective(getDirectiveKind())) &&
718           "expected worksharing loop directive");
719    return const_cast<Expr *>(reinterpret_cast<const Expr *>(
720        *std::next(child_begin(), PrevUpperBoundVariableOffset)));
721  }
722  const Stmt *getBody() const {
723    // This relies on the loop form is already checked by Sema.
724    Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
725    Body = cast<ForStmt>(Body)->getBody();
726    for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
727      Body = Body->IgnoreContainers();
728      Body = cast<ForStmt>(Body)->getBody();
729    }
730    return Body;
731  }
732
733  ArrayRef<Expr *> counters() { return getCounters(); }
734
735  ArrayRef<Expr *> counters() const {
736    return const_cast<OMPLoopDirective *>(this)->getCounters();
737  }
738
739  ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
740
741  ArrayRef<Expr *> private_counters() const {
742    return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
743  }
744
745  ArrayRef<Expr *> inits() { return getInits(); }
746
747  ArrayRef<Expr *> inits() const {
748    return const_cast<OMPLoopDirective *>(this)->getInits();
749  }
750
751  ArrayRef<Expr *> updates() { return getUpdates(); }
752
753  ArrayRef<Expr *> updates() const {
754    return const_cast<OMPLoopDirective *>(this)->getUpdates();
755  }
756
757  ArrayRef<Expr *> finals() { return getFinals(); }
758
759  ArrayRef<Expr *> finals() const {
760    return const_cast<OMPLoopDirective *>(this)->getFinals();
761  }
762
763  static bool classof(const Stmt *T) {
764    return T->getStmtClass() == OMPSimdDirectiveClass ||
765           T->getStmtClass() == OMPForDirectiveClass ||
766           T->getStmtClass() == OMPForSimdDirectiveClass ||
767           T->getStmtClass() == OMPParallelForDirectiveClass ||
768           T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
769           T->getStmtClass() == OMPTaskLoopDirectiveClass ||
770           T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
771           T->getStmtClass() == OMPDistributeDirectiveClass ||
772           T->getStmtClass() == OMPTargetParallelForDirectiveClass ||
773           T->getStmtClass() == OMPDistributeParallelForDirectiveClass ||
774           T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass ||
775           T->getStmtClass() == OMPDistributeSimdDirectiveClass ||
776           T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
777  }
778};
779
780/// \brief This represents '#pragma omp simd' directive.
781///
782/// \code
783/// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
784/// \endcode
785/// In this example directive '#pragma omp simd' has clauses 'private'
786/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
787/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
788///
789class OMPSimdDirective : public OMPLoopDirective {
790  friend class ASTStmtReader;
791  /// \brief Build directive with the given start and end location.
792  ///
793  /// \param StartLoc Starting location of the directive kind.
794  /// \param EndLoc Ending location of the directive.
795  /// \param CollapsedNum Number of collapsed nested loops.
796  /// \param NumClauses Number of clauses.
797  ///
798  OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
799                   unsigned CollapsedNum, unsigned NumClauses)
800      : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
801                         EndLoc, CollapsedNum, NumClauses) {}
802
803  /// \brief Build an empty directive.
804  ///
805  /// \param CollapsedNum Number of collapsed nested loops.
806  /// \param NumClauses Number of clauses.
807  ///
808  explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
809      : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd,
810                         SourceLocation(), SourceLocation(), CollapsedNum,
811                         NumClauses) {}
812
813public:
814  /// \brief Creates directive with a list of \a Clauses.
815  ///
816  /// \param C AST context.
817  /// \param StartLoc Starting location of the directive kind.
818  /// \param EndLoc Ending Location of the directive.
819  /// \param CollapsedNum Number of collapsed loops.
820  /// \param Clauses List of clauses.
821  /// \param AssociatedStmt Statement, associated with the directive.
822  /// \param Exprs Helper expressions for CodeGen.
823  ///
824  static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
825                                  SourceLocation EndLoc, unsigned CollapsedNum,
826                                  ArrayRef<OMPClause *> Clauses,
827                                  Stmt *AssociatedStmt,
828                                  const HelperExprs &Exprs);
829
830  /// \brief Creates an empty directive with the place
831  /// for \a NumClauses clauses.
832  ///
833  /// \param C AST context.
834  /// \param CollapsedNum Number of collapsed nested loops.
835  /// \param NumClauses Number of clauses.
836  ///
837  static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
838                                       unsigned CollapsedNum, EmptyShell);
839
840  static bool classof(const Stmt *T) {
841    return T->getStmtClass() == OMPSimdDirectiveClass;
842  }
843};
844
845/// \brief This represents '#pragma omp for' directive.
846///
847/// \code
848/// #pragma omp for private(a,b) reduction(+:c,d)
849/// \endcode
850/// In this example directive '#pragma omp for' has clauses 'private' with the
851/// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
852/// and 'd'.
853///
854class OMPForDirective : public OMPLoopDirective {
855  friend class ASTStmtReader;
856
857  /// \brief true if current directive has inner cancel directive.
858  bool HasCancel;
859
860  /// \brief Build directive with the given start and end location.
861  ///
862  /// \param StartLoc Starting location of the directive kind.
863  /// \param EndLoc Ending location of the directive.
864  /// \param CollapsedNum Number of collapsed nested loops.
865  /// \param NumClauses Number of clauses.
866  ///
867  OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
868                  unsigned CollapsedNum, unsigned NumClauses)
869      : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc,
870                         CollapsedNum, NumClauses),
871        HasCancel(false) {}
872
873  /// \brief Build an empty directive.
874  ///
875  /// \param CollapsedNum Number of collapsed nested loops.
876  /// \param NumClauses Number of clauses.
877  ///
878  explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
879      : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(),
880                         SourceLocation(), CollapsedNum, NumClauses),
881        HasCancel(false) {}
882
883  /// \brief Set cancel state.
884  void setHasCancel(bool Has) { HasCancel = Has; }
885
886public:
887  /// \brief Creates directive with a list of \a Clauses.
888  ///
889  /// \param C AST context.
890  /// \param StartLoc Starting location of the directive kind.
891  /// \param EndLoc Ending Location of the directive.
892  /// \param CollapsedNum Number of collapsed loops.
893  /// \param Clauses List of clauses.
894  /// \param AssociatedStmt Statement, associated with the directive.
895  /// \param Exprs Helper expressions for CodeGen.
896  /// \param HasCancel true if current directive has inner cancel directive.
897  ///
898  static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
899                                 SourceLocation EndLoc, unsigned CollapsedNum,
900                                 ArrayRef<OMPClause *> Clauses,
901                                 Stmt *AssociatedStmt, const HelperExprs &Exprs,
902                                 bool HasCancel);
903
904  /// \brief Creates an empty directive with the place
905  /// for \a NumClauses clauses.
906  ///
907  /// \param C AST context.
908  /// \param CollapsedNum Number of collapsed nested loops.
909  /// \param NumClauses Number of clauses.
910  ///
911  static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
912                                      unsigned CollapsedNum, EmptyShell);
913
914  /// \brief Return true if current directive has inner cancel directive.
915  bool hasCancel() const { return HasCancel; }
916
917  static bool classof(const Stmt *T) {
918    return T->getStmtClass() == OMPForDirectiveClass;
919  }
920};
921
922/// \brief This represents '#pragma omp for simd' directive.
923///
924/// \code
925/// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
926/// \endcode
927/// In this example directive '#pragma omp for simd' has clauses 'private'
928/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
929/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
930///
931class OMPForSimdDirective : public OMPLoopDirective {
932  friend class ASTStmtReader;
933  /// \brief Build directive with the given start and end location.
934  ///
935  /// \param StartLoc Starting location of the directive kind.
936  /// \param EndLoc Ending location of the directive.
937  /// \param CollapsedNum Number of collapsed nested loops.
938  /// \param NumClauses Number of clauses.
939  ///
940  OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
941                      unsigned CollapsedNum, unsigned NumClauses)
942      : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
943                         StartLoc, EndLoc, CollapsedNum, NumClauses) {}
944
945  /// \brief Build an empty directive.
946  ///
947  /// \param CollapsedNum Number of collapsed nested loops.
948  /// \param NumClauses Number of clauses.
949  ///
950  explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
951      : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
952                         SourceLocation(), SourceLocation(), CollapsedNum,
953                         NumClauses) {}
954
955public:
956  /// \brief Creates directive with a list of \a Clauses.
957  ///
958  /// \param C AST context.
959  /// \param StartLoc Starting location of the directive kind.
960  /// \param EndLoc Ending Location of the directive.
961  /// \param CollapsedNum Number of collapsed loops.
962  /// \param Clauses List of clauses.
963  /// \param AssociatedStmt Statement, associated with the directive.
964  /// \param Exprs Helper expressions for CodeGen.
965  ///
966  static OMPForSimdDirective *
967  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
968         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
969         Stmt *AssociatedStmt, const HelperExprs &Exprs);
970
971  /// \brief Creates an empty directive with the place
972  /// for \a NumClauses clauses.
973  ///
974  /// \param C AST context.
975  /// \param CollapsedNum Number of collapsed nested loops.
976  /// \param NumClauses Number of clauses.
977  ///
978  static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
979                                          unsigned NumClauses,
980                                          unsigned CollapsedNum, EmptyShell);
981
982  static bool classof(const Stmt *T) {
983    return T->getStmtClass() == OMPForSimdDirectiveClass;
984  }
985};
986
987/// \brief This represents '#pragma omp sections' directive.
988///
989/// \code
990/// #pragma omp sections private(a,b) reduction(+:c,d)
991/// \endcode
992/// In this example directive '#pragma omp sections' has clauses 'private' with
993/// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
994/// 'c' and 'd'.
995///
996class OMPSectionsDirective : public OMPExecutableDirective {
997  friend class ASTStmtReader;
998
999  /// \brief true if current directive has inner cancel directive.
1000  bool HasCancel;
1001
1002  /// \brief Build directive with the given start and end location.
1003  ///
1004  /// \param StartLoc Starting location of the directive kind.
1005  /// \param EndLoc Ending location of the directive.
1006  /// \param NumClauses Number of clauses.
1007  ///
1008  OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1009                       unsigned NumClauses)
1010      : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
1011                               StartLoc, EndLoc, NumClauses, 1),
1012        HasCancel(false) {}
1013
1014  /// \brief Build an empty directive.
1015  ///
1016  /// \param NumClauses Number of clauses.
1017  ///
1018  explicit OMPSectionsDirective(unsigned NumClauses)
1019      : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
1020                               SourceLocation(), SourceLocation(), NumClauses,
1021                               1),
1022        HasCancel(false) {}
1023
1024  /// \brief Set cancel state.
1025  void setHasCancel(bool Has) { HasCancel = Has; }
1026
1027public:
1028  /// \brief Creates directive with a list of \a Clauses.
1029  ///
1030  /// \param C AST context.
1031  /// \param StartLoc Starting location of the directive kind.
1032  /// \param EndLoc Ending Location of the directive.
1033  /// \param Clauses List of clauses.
1034  /// \param AssociatedStmt Statement, associated with the directive.
1035  /// \param HasCancel true if current directive has inner directive.
1036  ///
1037  static OMPSectionsDirective *
1038  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1039         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
1040
1041  /// \brief Creates an empty directive with the place for \a NumClauses
1042  /// clauses.
1043  ///
1044  /// \param C AST context.
1045  /// \param NumClauses Number of clauses.
1046  ///
1047  static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
1048                                           unsigned NumClauses, EmptyShell);
1049
1050  /// \brief Return true if current directive has inner cancel directive.
1051  bool hasCancel() const { return HasCancel; }
1052
1053  static bool classof(const Stmt *T) {
1054    return T->getStmtClass() == OMPSectionsDirectiveClass;
1055  }
1056};
1057
1058/// \brief This represents '#pragma omp section' directive.
1059///
1060/// \code
1061/// #pragma omp section
1062/// \endcode
1063///
1064class OMPSectionDirective : public OMPExecutableDirective {
1065  friend class ASTStmtReader;
1066
1067  /// \brief true if current directive has inner cancel directive.
1068  bool HasCancel;
1069
1070  /// \brief Build directive with the given start and end location.
1071  ///
1072  /// \param StartLoc Starting location of the directive kind.
1073  /// \param EndLoc Ending location of the directive.
1074  ///
1075  OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1076      : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
1077                               StartLoc, EndLoc, 0, 1),
1078        HasCancel(false) {}
1079
1080  /// \brief Build an empty directive.
1081  ///
1082  explicit OMPSectionDirective()
1083      : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
1084                               SourceLocation(), SourceLocation(), 0, 1),
1085        HasCancel(false) {}
1086
1087public:
1088  /// \brief Creates directive.
1089  ///
1090  /// \param C AST context.
1091  /// \param StartLoc Starting location of the directive kind.
1092  /// \param EndLoc Ending Location of the directive.
1093  /// \param AssociatedStmt Statement, associated with the directive.
1094  /// \param HasCancel true if current directive has inner directive.
1095  ///
1096  static OMPSectionDirective *Create(const ASTContext &C,
1097                                     SourceLocation StartLoc,
1098                                     SourceLocation EndLoc,
1099                                     Stmt *AssociatedStmt, bool HasCancel);
1100
1101  /// \brief Creates an empty directive.
1102  ///
1103  /// \param C AST context.
1104  ///
1105  static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1106
1107  /// \brief Set cancel state.
1108  void setHasCancel(bool Has) { HasCancel = Has; }
1109
1110  /// \brief Return true if current directive has inner cancel directive.
1111  bool hasCancel() const { return HasCancel; }
1112
1113  static bool classof(const Stmt *T) {
1114    return T->getStmtClass() == OMPSectionDirectiveClass;
1115  }
1116};
1117
1118/// \brief This represents '#pragma omp single' directive.
1119///
1120/// \code
1121/// #pragma omp single private(a,b) copyprivate(c,d)
1122/// \endcode
1123/// In this example directive '#pragma omp single' has clauses 'private' with
1124/// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
1125///
1126class OMPSingleDirective : public OMPExecutableDirective {
1127  friend class ASTStmtReader;
1128  /// \brief Build directive with the given start and end location.
1129  ///
1130  /// \param StartLoc Starting location of the directive kind.
1131  /// \param EndLoc Ending location of the directive.
1132  /// \param NumClauses Number of clauses.
1133  ///
1134  OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1135                     unsigned NumClauses)
1136      : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
1137                               StartLoc, EndLoc, NumClauses, 1) {}
1138
1139  /// \brief Build an empty directive.
1140  ///
1141  /// \param NumClauses Number of clauses.
1142  ///
1143  explicit OMPSingleDirective(unsigned NumClauses)
1144      : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
1145                               SourceLocation(), SourceLocation(), NumClauses,
1146                               1) {}
1147
1148public:
1149  /// \brief Creates directive with a list of \a Clauses.
1150  ///
1151  /// \param C AST context.
1152  /// \param StartLoc Starting location of the directive kind.
1153  /// \param EndLoc Ending Location of the directive.
1154  /// \param Clauses List of clauses.
1155  /// \param AssociatedStmt Statement, associated with the directive.
1156  ///
1157  static OMPSingleDirective *
1158  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1159         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1160
1161  /// \brief Creates an empty directive with the place for \a NumClauses
1162  /// clauses.
1163  ///
1164  /// \param C AST context.
1165  /// \param NumClauses Number of clauses.
1166  ///
1167  static OMPSingleDirective *CreateEmpty(const ASTContext &C,
1168                                         unsigned NumClauses, EmptyShell);
1169
1170  static bool classof(const Stmt *T) {
1171    return T->getStmtClass() == OMPSingleDirectiveClass;
1172  }
1173};
1174
1175/// \brief This represents '#pragma omp master' directive.
1176///
1177/// \code
1178/// #pragma omp master
1179/// \endcode
1180///
1181class OMPMasterDirective : public OMPExecutableDirective {
1182  friend class ASTStmtReader;
1183  /// \brief 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  ///
1188  OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1189      : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
1190                               StartLoc, EndLoc, 0, 1) {}
1191
1192  /// \brief Build an empty directive.
1193  ///
1194  explicit OMPMasterDirective()
1195      : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
1196                               SourceLocation(), SourceLocation(), 0, 1) {}
1197
1198public:
1199  /// \brief Creates directive.
1200  ///
1201  /// \param C AST context.
1202  /// \param StartLoc Starting location of the directive kind.
1203  /// \param EndLoc Ending Location of the directive.
1204  /// \param AssociatedStmt Statement, associated with the directive.
1205  ///
1206  static OMPMasterDirective *Create(const ASTContext &C,
1207                                    SourceLocation StartLoc,
1208                                    SourceLocation EndLoc,
1209                                    Stmt *AssociatedStmt);
1210
1211  /// \brief Creates an empty directive.
1212  ///
1213  /// \param C AST context.
1214  ///
1215  static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1216
1217  static bool classof(const Stmt *T) {
1218    return T->getStmtClass() == OMPMasterDirectiveClass;
1219  }
1220};
1221
1222/// \brief This represents '#pragma omp critical' directive.
1223///
1224/// \code
1225/// #pragma omp critical
1226/// \endcode
1227///
1228class OMPCriticalDirective : public OMPExecutableDirective {
1229  friend class ASTStmtReader;
1230  /// \brief Name of the directive.
1231  DeclarationNameInfo DirName;
1232  /// \brief Build directive with the given start and end location.
1233  ///
1234  /// \param Name Name of the directive.
1235  /// \param StartLoc Starting location of the directive kind.
1236  /// \param EndLoc Ending location of the directive.
1237  /// \param NumClauses Number of clauses.
1238  ///
1239  OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
1240                       SourceLocation EndLoc, unsigned NumClauses)
1241      : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
1242                               StartLoc, EndLoc, NumClauses, 1),
1243        DirName(Name) {}
1244
1245  /// \brief Build an empty directive.
1246  ///
1247  /// \param NumClauses Number of clauses.
1248  ///
1249  explicit OMPCriticalDirective(unsigned NumClauses)
1250      : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
1251                               SourceLocation(), SourceLocation(), NumClauses,
1252                               1),
1253        DirName() {}
1254
1255  /// \brief Set name of the directive.
1256  ///
1257  /// \param Name Name of the directive.
1258  ///
1259  void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
1260
1261public:
1262  /// \brief Creates directive.
1263  ///
1264  /// \param C AST context.
1265  /// \param Name Name of the directive.
1266  /// \param StartLoc Starting location of the directive kind.
1267  /// \param EndLoc Ending Location of the directive.
1268  /// \param Clauses List of clauses.
1269  /// \param AssociatedStmt Statement, associated with the directive.
1270  ///
1271  static OMPCriticalDirective *
1272  Create(const ASTContext &C, const DeclarationNameInfo &Name,
1273         SourceLocation StartLoc, SourceLocation EndLoc,
1274         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1275
1276  /// \brief Creates an empty directive.
1277  ///
1278  /// \param C AST context.
1279  /// \param NumClauses Number of clauses.
1280  ///
1281  static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
1282                                           unsigned NumClauses, EmptyShell);
1283
1284  /// \brief Return name of the directive.
1285  ///
1286  DeclarationNameInfo getDirectiveName() const { return DirName; }
1287
1288  static bool classof(const Stmt *T) {
1289    return T->getStmtClass() == OMPCriticalDirectiveClass;
1290  }
1291};
1292
1293/// \brief This represents '#pragma omp parallel for' directive.
1294///
1295/// \code
1296/// #pragma omp parallel for private(a,b) reduction(+:c,d)
1297/// \endcode
1298/// In this example directive '#pragma omp parallel for' has clauses 'private'
1299/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
1300/// variables 'c' and 'd'.
1301///
1302class OMPParallelForDirective : public OMPLoopDirective {
1303  friend class ASTStmtReader;
1304
1305  /// \brief true if current region has inner cancel directive.
1306  bool HasCancel;
1307
1308  /// \brief Build directive with the given start and end location.
1309  ///
1310  /// \param StartLoc Starting location of the directive kind.
1311  /// \param EndLoc Ending location of the directive.
1312  /// \param CollapsedNum Number of collapsed nested loops.
1313  /// \param NumClauses Number of clauses.
1314  ///
1315  OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1316                          unsigned CollapsedNum, unsigned NumClauses)
1317      : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
1318                         StartLoc, EndLoc, CollapsedNum, NumClauses),
1319        HasCancel(false) {}
1320
1321  /// \brief Build an empty directive.
1322  ///
1323  /// \param CollapsedNum Number of collapsed nested loops.
1324  /// \param NumClauses Number of clauses.
1325  ///
1326  explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
1327      : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
1328                         SourceLocation(), SourceLocation(), CollapsedNum,
1329                         NumClauses),
1330        HasCancel(false) {}
1331
1332  /// \brief Set cancel state.
1333  void setHasCancel(bool Has) { HasCancel = Has; }
1334
1335public:
1336  /// \brief Creates directive with a list of \a Clauses.
1337  ///
1338  /// \param C AST context.
1339  /// \param StartLoc Starting location of the directive kind.
1340  /// \param EndLoc Ending Location of the directive.
1341  /// \param CollapsedNum Number of collapsed loops.
1342  /// \param Clauses List of clauses.
1343  /// \param AssociatedStmt Statement, associated with the directive.
1344  /// \param Exprs Helper expressions for CodeGen.
1345  /// \param HasCancel true if current directive has inner cancel directive.
1346  ///
1347  static OMPParallelForDirective *
1348  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1349         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1350         Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
1351
1352  /// \brief Creates an empty directive with the place
1353  /// for \a NumClauses clauses.
1354  ///
1355  /// \param C AST context.
1356  /// \param CollapsedNum Number of collapsed nested loops.
1357  /// \param NumClauses Number of clauses.
1358  ///
1359  static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
1360                                              unsigned NumClauses,
1361                                              unsigned CollapsedNum,
1362                                              EmptyShell);
1363
1364  /// \brief Return true if current directive has inner cancel directive.
1365  bool hasCancel() const { return HasCancel; }
1366
1367  static bool classof(const Stmt *T) {
1368    return T->getStmtClass() == OMPParallelForDirectiveClass;
1369  }
1370};
1371
1372/// \brief This represents '#pragma omp parallel for simd' directive.
1373///
1374/// \code
1375/// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
1376/// \endcode
1377/// In this example directive '#pragma omp parallel for simd' has clauses
1378/// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
1379/// and linear step 's', 'reduction' with operator '+' and variables 'c' and
1380/// 'd'.
1381///
1382class OMPParallelForSimdDirective : public OMPLoopDirective {
1383  friend class ASTStmtReader;
1384  /// \brief Build directive with the given start and end location.
1385  ///
1386  /// \param StartLoc Starting location of the directive kind.
1387  /// \param EndLoc Ending location of the directive.
1388  /// \param CollapsedNum Number of collapsed nested loops.
1389  /// \param NumClauses Number of clauses.
1390  ///
1391  OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1392                              unsigned CollapsedNum, unsigned NumClauses)
1393      : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
1394                         OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum,
1395                         NumClauses) {}
1396
1397  /// \brief Build an empty directive.
1398  ///
1399  /// \param CollapsedNum Number of collapsed nested loops.
1400  /// \param NumClauses Number of clauses.
1401  ///
1402  explicit OMPParallelForSimdDirective(unsigned CollapsedNum,
1403                                       unsigned NumClauses)
1404      : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
1405                         OMPD_parallel_for_simd, SourceLocation(),
1406                         SourceLocation(), CollapsedNum, NumClauses) {}
1407
1408public:
1409  /// \brief Creates directive with a list of \a Clauses.
1410  ///
1411  /// \param C AST context.
1412  /// \param StartLoc Starting location of the directive kind.
1413  /// \param EndLoc Ending Location of the directive.
1414  /// \param CollapsedNum Number of collapsed loops.
1415  /// \param Clauses List of clauses.
1416  /// \param AssociatedStmt Statement, associated with the directive.
1417  /// \param Exprs Helper expressions for CodeGen.
1418  ///
1419  static OMPParallelForSimdDirective *
1420  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1421         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1422         Stmt *AssociatedStmt, const HelperExprs &Exprs);
1423
1424  /// \brief Creates an empty directive with the place
1425  /// for \a NumClauses clauses.
1426  ///
1427  /// \param C AST context.
1428  /// \param CollapsedNum Number of collapsed nested loops.
1429  /// \param NumClauses Number of clauses.
1430  ///
1431  static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
1432                                                  unsigned NumClauses,
1433                                                  unsigned CollapsedNum,
1434                                                  EmptyShell);
1435
1436  static bool classof(const Stmt *T) {
1437    return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
1438  }
1439};
1440
1441/// \brief This represents '#pragma omp parallel sections' directive.
1442///
1443/// \code
1444/// #pragma omp parallel sections private(a,b) reduction(+:c,d)
1445/// \endcode
1446/// In this example directive '#pragma omp parallel sections' has clauses
1447/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
1448/// and variables 'c' and 'd'.
1449///
1450class OMPParallelSectionsDirective : public OMPExecutableDirective {
1451  friend class ASTStmtReader;
1452
1453  /// \brief true if current directive has inner cancel directive.
1454  bool HasCancel;
1455
1456  /// \brief Build directive with the given start and end location.
1457  ///
1458  /// \param StartLoc Starting location of the directive kind.
1459  /// \param EndLoc Ending location of the directive.
1460  /// \param NumClauses Number of clauses.
1461  ///
1462  OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1463                               unsigned NumClauses)
1464      : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
1465                               OMPD_parallel_sections, StartLoc, EndLoc,
1466                               NumClauses, 1),
1467        HasCancel(false) {}
1468
1469  /// \brief Build an empty directive.
1470  ///
1471  /// \param NumClauses Number of clauses.
1472  ///
1473  explicit OMPParallelSectionsDirective(unsigned NumClauses)
1474      : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
1475                               OMPD_parallel_sections, SourceLocation(),
1476                               SourceLocation(), NumClauses, 1),
1477        HasCancel(false) {}
1478
1479  /// \brief Set cancel state.
1480  void setHasCancel(bool Has) { HasCancel = Has; }
1481
1482public:
1483  /// \brief Creates directive with a list of \a Clauses.
1484  ///
1485  /// \param C AST context.
1486  /// \param StartLoc Starting location of the directive kind.
1487  /// \param EndLoc Ending Location of the directive.
1488  /// \param Clauses List of clauses.
1489  /// \param AssociatedStmt Statement, associated with the directive.
1490  /// \param HasCancel true if current directive has inner cancel directive.
1491  ///
1492  static OMPParallelSectionsDirective *
1493  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1494         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
1495
1496  /// \brief Creates an empty directive with the place for \a NumClauses
1497  /// clauses.
1498  ///
1499  /// \param C AST context.
1500  /// \param NumClauses Number of clauses.
1501  ///
1502  static OMPParallelSectionsDirective *
1503  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
1504
1505  /// \brief Return true if current directive has inner cancel directive.
1506  bool hasCancel() const { return HasCancel; }
1507
1508  static bool classof(const Stmt *T) {
1509    return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
1510  }
1511};
1512
1513/// \brief This represents '#pragma omp task' directive.
1514///
1515/// \code
1516/// #pragma omp task private(a,b) final(d)
1517/// \endcode
1518/// In this example directive '#pragma omp task' has clauses 'private' with the
1519/// variables 'a' and 'b' and 'final' with condition 'd'.
1520///
1521class OMPTaskDirective : public OMPExecutableDirective {
1522  friend class ASTStmtReader;
1523  /// \brief true if this directive has inner cancel directive.
1524  bool HasCancel;
1525
1526  /// \brief Build directive with the given start and end location.
1527  ///
1528  /// \param StartLoc Starting location of the directive kind.
1529  /// \param EndLoc Ending location of the directive.
1530  /// \param NumClauses Number of clauses.
1531  ///
1532  OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1533                   unsigned NumClauses)
1534      : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
1535                               EndLoc, NumClauses, 1),
1536        HasCancel(false) {}
1537
1538  /// \brief Build an empty directive.
1539  ///
1540  /// \param NumClauses Number of clauses.
1541  ///
1542  explicit OMPTaskDirective(unsigned NumClauses)
1543      : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
1544                               SourceLocation(), SourceLocation(), NumClauses,
1545                               1),
1546        HasCancel(false) {}
1547
1548  /// \brief Set cancel state.
1549  void setHasCancel(bool Has) { HasCancel = Has; }
1550
1551public:
1552  /// \brief Creates directive with a list of \a Clauses.
1553  ///
1554  /// \param C AST context.
1555  /// \param StartLoc Starting location of the directive kind.
1556  /// \param EndLoc Ending Location of the directive.
1557  /// \param Clauses List of clauses.
1558  /// \param AssociatedStmt Statement, associated with the directive.
1559  /// \param HasCancel true, if current directive has inner cancel directive.
1560  ///
1561  static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1562                                  SourceLocation EndLoc,
1563                                  ArrayRef<OMPClause *> Clauses,
1564                                  Stmt *AssociatedStmt, bool HasCancel);
1565
1566  /// \brief Creates an empty directive with the place for \a NumClauses
1567  /// clauses.
1568  ///
1569  /// \param C AST context.
1570  /// \param NumClauses Number of clauses.
1571  ///
1572  static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1573                                       EmptyShell);
1574
1575  /// \brief Return true if current directive has inner cancel directive.
1576  bool hasCancel() const { return HasCancel; }
1577
1578  static bool classof(const Stmt *T) {
1579    return T->getStmtClass() == OMPTaskDirectiveClass;
1580  }
1581};
1582
1583/// \brief This represents '#pragma omp taskyield' directive.
1584///
1585/// \code
1586/// #pragma omp taskyield
1587/// \endcode
1588///
1589class OMPTaskyieldDirective : public OMPExecutableDirective {
1590  friend class ASTStmtReader;
1591  /// \brief Build directive with the given start and end location.
1592  ///
1593  /// \param StartLoc Starting location of the directive kind.
1594  /// \param EndLoc Ending location of the directive.
1595  ///
1596  OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1597      : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
1598                               StartLoc, EndLoc, 0, 0) {}
1599
1600  /// \brief Build an empty directive.
1601  ///
1602  explicit OMPTaskyieldDirective()
1603      : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
1604                               SourceLocation(), SourceLocation(), 0, 0) {}
1605
1606public:
1607  /// \brief Creates directive.
1608  ///
1609  /// \param C AST context.
1610  /// \param StartLoc Starting location of the directive kind.
1611  /// \param EndLoc Ending Location of the directive.
1612  ///
1613  static OMPTaskyieldDirective *
1614  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1615
1616  /// \brief Creates an empty directive.
1617  ///
1618  /// \param C AST context.
1619  ///
1620  static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1621
1622  static bool classof(const Stmt *T) {
1623    return T->getStmtClass() == OMPTaskyieldDirectiveClass;
1624  }
1625};
1626
1627/// \brief This represents '#pragma omp barrier' directive.
1628///
1629/// \code
1630/// #pragma omp barrier
1631/// \endcode
1632///
1633class OMPBarrierDirective : public OMPExecutableDirective {
1634  friend class ASTStmtReader;
1635  /// \brief Build directive with the given start and end location.
1636  ///
1637  /// \param StartLoc Starting location of the directive kind.
1638  /// \param EndLoc Ending location of the directive.
1639  ///
1640  OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1641      : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
1642                               StartLoc, EndLoc, 0, 0) {}
1643
1644  /// \brief Build an empty directive.
1645  ///
1646  explicit OMPBarrierDirective()
1647      : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
1648                               SourceLocation(), SourceLocation(), 0, 0) {}
1649
1650public:
1651  /// \brief Creates directive.
1652  ///
1653  /// \param C AST context.
1654  /// \param StartLoc Starting location of the directive kind.
1655  /// \param EndLoc Ending Location of the directive.
1656  ///
1657  static OMPBarrierDirective *
1658  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1659
1660  /// \brief Creates an empty directive.
1661  ///
1662  /// \param C AST context.
1663  ///
1664  static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1665
1666  static bool classof(const Stmt *T) {
1667    return T->getStmtClass() == OMPBarrierDirectiveClass;
1668  }
1669};
1670
1671/// \brief This represents '#pragma omp taskwait' directive.
1672///
1673/// \code
1674/// #pragma omp taskwait
1675/// \endcode
1676///
1677class OMPTaskwaitDirective : public OMPExecutableDirective {
1678  friend class ASTStmtReader;
1679  /// \brief Build directive with the given start and end location.
1680  ///
1681  /// \param StartLoc Starting location of the directive kind.
1682  /// \param EndLoc Ending location of the directive.
1683  ///
1684  OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1685      : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
1686                               StartLoc, EndLoc, 0, 0) {}
1687
1688  /// \brief Build an empty directive.
1689  ///
1690  explicit OMPTaskwaitDirective()
1691      : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
1692                               SourceLocation(), SourceLocation(), 0, 0) {}
1693
1694public:
1695  /// \brief Creates directive.
1696  ///
1697  /// \param C AST context.
1698  /// \param StartLoc Starting location of the directive kind.
1699  /// \param EndLoc Ending Location of the directive.
1700  ///
1701  static OMPTaskwaitDirective *
1702  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1703
1704  /// \brief Creates an empty directive.
1705  ///
1706  /// \param C AST context.
1707  ///
1708  static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1709
1710  static bool classof(const Stmt *T) {
1711    return T->getStmtClass() == OMPTaskwaitDirectiveClass;
1712  }
1713};
1714
1715/// \brief This represents '#pragma omp taskgroup' directive.
1716///
1717/// \code
1718/// #pragma omp taskgroup
1719/// \endcode
1720///
1721class OMPTaskgroupDirective : public OMPExecutableDirective {
1722  friend class ASTStmtReader;
1723  /// \brief Build directive with the given start and end location.
1724  ///
1725  /// \param StartLoc Starting location of the directive kind.
1726  /// \param EndLoc Ending location of the directive.
1727  ///
1728  OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1729      : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
1730                               StartLoc, EndLoc, 0, 1) {}
1731
1732  /// \brief Build an empty directive.
1733  ///
1734  explicit OMPTaskgroupDirective()
1735      : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
1736                               SourceLocation(), SourceLocation(), 0, 1) {}
1737
1738public:
1739  /// \brief Creates directive.
1740  ///
1741  /// \param C AST context.
1742  /// \param StartLoc Starting location of the directive kind.
1743  /// \param EndLoc Ending Location of the directive.
1744  /// \param AssociatedStmt Statement, associated with the directive.
1745  ///
1746  static OMPTaskgroupDirective *Create(const ASTContext &C,
1747                                       SourceLocation StartLoc,
1748                                       SourceLocation EndLoc,
1749                                       Stmt *AssociatedStmt);
1750
1751  /// \brief Creates an empty directive.
1752  ///
1753  /// \param C AST context.
1754  ///
1755  static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1756
1757  static bool classof(const Stmt *T) {
1758    return T->getStmtClass() == OMPTaskgroupDirectiveClass;
1759  }
1760};
1761
1762/// \brief This represents '#pragma omp flush' directive.
1763///
1764/// \code
1765/// #pragma omp flush(a,b)
1766/// \endcode
1767/// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
1768/// and 'b'.
1769/// 'omp flush' directive does not have clauses but have an optional list of
1770/// variables to flush. This list of variables is stored within some fake clause
1771/// FlushClause.
1772class OMPFlushDirective : public OMPExecutableDirective {
1773  friend class ASTStmtReader;
1774  /// \brief Build directive with the given start and end location.
1775  ///
1776  /// \param StartLoc Starting location of the directive kind.
1777  /// \param EndLoc Ending location of the directive.
1778  /// \param NumClauses Number of clauses.
1779  ///
1780  OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1781                    unsigned NumClauses)
1782      : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
1783                               StartLoc, EndLoc, NumClauses, 0) {}
1784
1785  /// \brief Build an empty directive.
1786  ///
1787  /// \param NumClauses Number of clauses.
1788  ///
1789  explicit OMPFlushDirective(unsigned NumClauses)
1790      : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
1791                               SourceLocation(), SourceLocation(), NumClauses,
1792                               0) {}
1793
1794public:
1795  /// \brief Creates directive with a list of \a Clauses.
1796  ///
1797  /// \param C AST context.
1798  /// \param StartLoc Starting location of the directive kind.
1799  /// \param EndLoc Ending Location of the directive.
1800  /// \param Clauses List of clauses (only single OMPFlushClause clause is
1801  /// allowed).
1802  ///
1803  static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1804                                   SourceLocation EndLoc,
1805                                   ArrayRef<OMPClause *> Clauses);
1806
1807  /// \brief Creates an empty directive with the place for \a NumClauses
1808  /// clauses.
1809  ///
1810  /// \param C AST context.
1811  /// \param NumClauses Number of clauses.
1812  ///
1813  static OMPFlushDirective *CreateEmpty(const ASTContext &C,
1814                                        unsigned NumClauses, EmptyShell);
1815
1816  static bool classof(const Stmt *T) {
1817    return T->getStmtClass() == OMPFlushDirectiveClass;
1818  }
1819};
1820
1821/// \brief This represents '#pragma omp ordered' directive.
1822///
1823/// \code
1824/// #pragma omp ordered
1825/// \endcode
1826///
1827class OMPOrderedDirective : public OMPExecutableDirective {
1828  friend class ASTStmtReader;
1829  /// \brief Build directive with the given start and end location.
1830  ///
1831  /// \param StartLoc Starting location of the directive kind.
1832  /// \param EndLoc Ending location of the directive.
1833  /// \param NumClauses Number of clauses.
1834  ///
1835  OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1836                      unsigned NumClauses)
1837      : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
1838                               StartLoc, EndLoc, NumClauses, 1) {}
1839
1840  /// \brief Build an empty directive.
1841  ///
1842  /// \param NumClauses Number of clauses.
1843  ///
1844  explicit OMPOrderedDirective(unsigned NumClauses)
1845      : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
1846                               SourceLocation(), SourceLocation(), NumClauses,
1847                               1) {}
1848
1849public:
1850  /// \brief Creates directive.
1851  ///
1852  /// \param C AST context.
1853  /// \param StartLoc Starting location of the directive kind.
1854  /// \param EndLoc Ending Location of the directive.
1855  /// \param Clauses List of clauses.
1856  /// \param AssociatedStmt Statement, associated with the directive.
1857  ///
1858  static OMPOrderedDirective *
1859  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1860         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1861
1862  /// \brief Creates an empty directive.
1863  ///
1864  /// \param C AST context.
1865  /// \param NumClauses Number of clauses.
1866  ///
1867  static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
1868                                          unsigned NumClauses, EmptyShell);
1869
1870  static bool classof(const Stmt *T) {
1871    return T->getStmtClass() == OMPOrderedDirectiveClass;
1872  }
1873};
1874
1875/// \brief This represents '#pragma omp atomic' directive.
1876///
1877/// \code
1878/// #pragma omp atomic capture
1879/// \endcode
1880/// In this example directive '#pragma omp atomic' has clause 'capture'.
1881///
1882class OMPAtomicDirective : public OMPExecutableDirective {
1883  friend class ASTStmtReader;
1884  /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
1885  /// have atomic expressions of forms
1886  /// \code
1887  /// x = x binop expr;
1888  /// x = expr binop x;
1889  /// \endcode
1890  /// This field is true for the first form of the expression and false for the
1891  /// second. Required for correct codegen of non-associative operations (like
1892  /// << or >>).
1893  bool IsXLHSInRHSPart;
1894  /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
1895  /// have atomic expressions of forms
1896  /// \code
1897  /// v = x; <update x>;
1898  /// <update x>; v = x;
1899  /// \endcode
1900  /// This field is true for the first(postfix) form of the expression and false
1901  /// otherwise.
1902  bool IsPostfixUpdate;
1903
1904  /// \brief Build directive with the given start and end location.
1905  ///
1906  /// \param StartLoc Starting location of the directive kind.
1907  /// \param EndLoc Ending location of the directive.
1908  /// \param NumClauses Number of clauses.
1909  ///
1910  OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1911                     unsigned NumClauses)
1912      : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
1913                               StartLoc, EndLoc, NumClauses, 5),
1914        IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
1915
1916  /// \brief Build an empty directive.
1917  ///
1918  /// \param NumClauses Number of clauses.
1919  ///
1920  explicit OMPAtomicDirective(unsigned NumClauses)
1921      : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
1922                               SourceLocation(), SourceLocation(), NumClauses,
1923                               5),
1924        IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
1925
1926  /// \brief Set 'x' part of the associated expression/statement.
1927  void setX(Expr *X) { *std::next(child_begin()) = X; }
1928  /// \brief Set helper expression of the form
1929  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1930  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1931  void setUpdateExpr(Expr *UE) { *std::next(child_begin(), 2) = UE; }
1932  /// \brief Set 'v' part of the associated expression/statement.
1933  void setV(Expr *V) { *std::next(child_begin(), 3) = V; }
1934  /// \brief Set 'expr' part of the associated expression/statement.
1935  void setExpr(Expr *E) { *std::next(child_begin(), 4) = E; }
1936
1937public:
1938  /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
1939  /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
1940  /// detailed description of 'x', 'v' and 'expr').
1941  ///
1942  /// \param C AST context.
1943  /// \param StartLoc Starting location of the directive kind.
1944  /// \param EndLoc Ending Location of the directive.
1945  /// \param Clauses List of clauses.
1946  /// \param AssociatedStmt Statement, associated with the directive.
1947  /// \param X 'x' part of the associated expression/statement.
1948  /// \param V 'v' part of the associated expression/statement.
1949  /// \param E 'expr' part of the associated expression/statement.
1950  /// \param UE Helper expression of the form
1951  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1952  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1953  /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the
1954  /// second.
1955  /// \param IsPostfixUpdate true if original value of 'x' must be stored in
1956  /// 'v', not an updated one.
1957  static OMPAtomicDirective *
1958  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1959         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
1960         Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate);
1961
1962  /// \brief Creates an empty directive with the place for \a NumClauses
1963  /// clauses.
1964  ///
1965  /// \param C AST context.
1966  /// \param NumClauses Number of clauses.
1967  ///
1968  static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
1969                                         unsigned NumClauses, EmptyShell);
1970
1971  /// \brief Get 'x' part of the associated expression/statement.
1972  Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); }
1973  const Expr *getX() const {
1974    return cast_or_null<Expr>(*std::next(child_begin()));
1975  }
1976  /// \brief Get helper expression of the form
1977  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1978  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1979  Expr *getUpdateExpr() {
1980    return cast_or_null<Expr>(*std::next(child_begin(), 2));
1981  }
1982  const Expr *getUpdateExpr() const {
1983    return cast_or_null<Expr>(*std::next(child_begin(), 2));
1984  }
1985  /// \brief Return true if helper update expression has form
1986  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
1987  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1988  bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
1989  /// \brief Return true if 'v' expression must be updated to original value of
1990  /// 'x', false if 'v' must be updated to the new value of 'x'.
1991  bool isPostfixUpdate() const { return IsPostfixUpdate; }
1992  /// \brief Get 'v' part of the associated expression/statement.
1993  Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); }
1994  const Expr *getV() const {
1995    return cast_or_null<Expr>(*std::next(child_begin(), 3));
1996  }
1997  /// \brief Get 'expr' part of the associated expression/statement.
1998  Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 4)); }
1999  const Expr *getExpr() const {
2000    return cast_or_null<Expr>(*std::next(child_begin(), 4));
2001  }
2002
2003  static bool classof(const Stmt *T) {
2004    return T->getStmtClass() == OMPAtomicDirectiveClass;
2005  }
2006};
2007
2008/// \brief This represents '#pragma omp target' directive.
2009///
2010/// \code
2011/// #pragma omp target if(a)
2012/// \endcode
2013/// In this example directive '#pragma omp target' has clause 'if' with
2014/// condition 'a'.
2015///
2016class OMPTargetDirective : public OMPExecutableDirective {
2017  friend class ASTStmtReader;
2018  /// \brief Build directive with the given start and end location.
2019  ///
2020  /// \param StartLoc Starting location of the directive kind.
2021  /// \param EndLoc Ending location of the directive.
2022  /// \param NumClauses Number of clauses.
2023  ///
2024  OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2025                     unsigned NumClauses)
2026      : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
2027                               StartLoc, EndLoc, NumClauses, 1) {}
2028
2029  /// \brief Build an empty directive.
2030  ///
2031  /// \param NumClauses Number of clauses.
2032  ///
2033  explicit OMPTargetDirective(unsigned NumClauses)
2034      : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
2035                               SourceLocation(), SourceLocation(), NumClauses,
2036                               1) {}
2037
2038public:
2039  /// \brief Creates directive with a list of \a Clauses.
2040  ///
2041  /// \param C AST context.
2042  /// \param StartLoc Starting location of the directive kind.
2043  /// \param EndLoc Ending Location of the directive.
2044  /// \param Clauses List of clauses.
2045  /// \param AssociatedStmt Statement, associated with the directive.
2046  ///
2047  static OMPTargetDirective *
2048  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2049         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2050
2051  /// \brief Creates an empty directive with the place for \a NumClauses
2052  /// clauses.
2053  ///
2054  /// \param C AST context.
2055  /// \param NumClauses Number of clauses.
2056  ///
2057  static OMPTargetDirective *CreateEmpty(const ASTContext &C,
2058                                         unsigned NumClauses, EmptyShell);
2059
2060  static bool classof(const Stmt *T) {
2061    return T->getStmtClass() == OMPTargetDirectiveClass;
2062  }
2063};
2064
2065/// \brief This represents '#pragma omp target data' directive.
2066///
2067/// \code
2068/// #pragma omp target data device(0) if(a) map(b[:])
2069/// \endcode
2070/// In this example directive '#pragma omp target data' has clauses 'device'
2071/// with the value '0', 'if' with condition 'a' and 'map' with array
2072/// section 'b[:]'.
2073///
2074class OMPTargetDataDirective : public OMPExecutableDirective {
2075  friend class ASTStmtReader;
2076  /// \brief Build directive with the given start and end location.
2077  ///
2078  /// \param StartLoc Starting location of the directive kind.
2079  /// \param EndLoc Ending Location of the directive.
2080  /// \param NumClauses The number of clauses.
2081  ///
2082  OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2083                         unsigned NumClauses)
2084      : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
2085                               OMPD_target_data, StartLoc, EndLoc, NumClauses,
2086                               1) {}
2087
2088  /// \brief Build an empty directive.
2089  ///
2090  /// \param NumClauses Number of clauses.
2091  ///
2092  explicit OMPTargetDataDirective(unsigned NumClauses)
2093      : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
2094                               OMPD_target_data, SourceLocation(),
2095                               SourceLocation(), NumClauses, 1) {}
2096
2097public:
2098  /// \brief Creates directive with a list of \a Clauses.
2099  ///
2100  /// \param C AST context.
2101  /// \param StartLoc Starting location of the directive kind.
2102  /// \param EndLoc Ending Location of the directive.
2103  /// \param Clauses List of clauses.
2104  /// \param AssociatedStmt Statement, associated with the directive.
2105  ///
2106  static OMPTargetDataDirective *
2107  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2108         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2109
2110  /// \brief Creates an empty directive with the place for \a N clauses.
2111  ///
2112  /// \param C AST context.
2113  /// \param N The number of clauses.
2114  ///
2115  static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
2116                                             EmptyShell);
2117
2118  static bool classof(const Stmt *T) {
2119    return T->getStmtClass() == OMPTargetDataDirectiveClass;
2120  }
2121};
2122
2123/// \brief This represents '#pragma omp target enter data' directive.
2124///
2125/// \code
2126/// #pragma omp target enter data device(0) if(a) map(b[:])
2127/// \endcode
2128/// In this example directive '#pragma omp target enter data' has clauses
2129/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
2130/// section 'b[:]'.
2131///
2132class OMPTargetEnterDataDirective : public OMPExecutableDirective {
2133  friend class ASTStmtReader;
2134  /// \brief Build directive with the given start and end location.
2135  ///
2136  /// \param StartLoc Starting location of the directive kind.
2137  /// \param EndLoc Ending Location of the directive.
2138  /// \param NumClauses The number of clauses.
2139  ///
2140  OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2141                              unsigned NumClauses)
2142      : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
2143                               OMPD_target_enter_data, StartLoc, EndLoc,
2144                               NumClauses, /*NumChildren=*/0) {}
2145
2146  /// \brief Build an empty directive.
2147  ///
2148  /// \param NumClauses Number of clauses.
2149  ///
2150  explicit OMPTargetEnterDataDirective(unsigned NumClauses)
2151      : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
2152                               OMPD_target_enter_data, SourceLocation(),
2153                               SourceLocation(), NumClauses,
2154                               /*NumChildren=*/0) {}
2155
2156public:
2157  /// \brief Creates directive with a list of \a Clauses.
2158  ///
2159  /// \param C AST context.
2160  /// \param StartLoc Starting location of the directive kind.
2161  /// \param EndLoc Ending Location of the directive.
2162  /// \param Clauses List of clauses.
2163  ///
2164  static OMPTargetEnterDataDirective *Create(const ASTContext &C,
2165                                             SourceLocation StartLoc,
2166                                             SourceLocation EndLoc,
2167                                             ArrayRef<OMPClause *> Clauses);
2168
2169  /// \brief Creates an empty directive with the place for \a N clauses.
2170  ///
2171  /// \param C AST context.
2172  /// \param N The number of clauses.
2173  ///
2174  static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C,
2175                                                  unsigned N, EmptyShell);
2176
2177  static bool classof(const Stmt *T) {
2178    return T->getStmtClass() == OMPTargetEnterDataDirectiveClass;
2179  }
2180};
2181
2182/// \brief This represents '#pragma omp target exit data' directive.
2183///
2184/// \code
2185/// #pragma omp target exit data device(0) if(a) map(b[:])
2186/// \endcode
2187/// In this example directive '#pragma omp target exit data' has clauses
2188/// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
2189/// section 'b[:]'.
2190///
2191class OMPTargetExitDataDirective : public OMPExecutableDirective {
2192  friend class ASTStmtReader;
2193  /// \brief Build directive with the given start and end location.
2194  ///
2195  /// \param StartLoc Starting location of the directive kind.
2196  /// \param EndLoc Ending Location of the directive.
2197  /// \param NumClauses The number of clauses.
2198  ///
2199  OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2200                             unsigned NumClauses)
2201      : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
2202                               OMPD_target_exit_data, StartLoc, EndLoc,
2203                               NumClauses, /*NumChildren=*/0) {}
2204
2205  /// \brief Build an empty directive.
2206  ///
2207  /// \param NumClauses Number of clauses.
2208  ///
2209  explicit OMPTargetExitDataDirective(unsigned NumClauses)
2210      : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
2211                               OMPD_target_exit_data, SourceLocation(),
2212                               SourceLocation(), NumClauses,
2213                               /*NumChildren=*/0) {}
2214
2215public:
2216  /// \brief Creates directive with a list of \a Clauses.
2217  ///
2218  /// \param C AST context.
2219  /// \param StartLoc Starting location of the directive kind.
2220  /// \param EndLoc Ending Location of the directive.
2221  /// \param Clauses List of clauses.
2222  ///
2223  static OMPTargetExitDataDirective *Create(const ASTContext &C,
2224                                            SourceLocation StartLoc,
2225                                            SourceLocation EndLoc,
2226                                            ArrayRef<OMPClause *> Clauses);
2227
2228  /// \brief Creates an empty directive with the place for \a N clauses.
2229  ///
2230  /// \param C AST context.
2231  /// \param N The number of clauses.
2232  ///
2233  static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
2234                                                 unsigned N, EmptyShell);
2235
2236  static bool classof(const Stmt *T) {
2237    return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
2238  }
2239};
2240
2241/// \brief This represents '#pragma omp target parallel' directive.
2242///
2243/// \code
2244/// #pragma omp target parallel if(a)
2245/// \endcode
2246/// In this example directive '#pragma omp target parallel' has clause 'if' with
2247/// condition 'a'.
2248///
2249class OMPTargetParallelDirective : public OMPExecutableDirective {
2250  friend class ASTStmtReader;
2251  /// \brief Build directive with the given start and end location.
2252  ///
2253  /// \param StartLoc Starting location of the directive kind.
2254  /// \param EndLoc Ending location of the directive.
2255  /// \param NumClauses Number of clauses.
2256  ///
2257  OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2258                             unsigned NumClauses)
2259      : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass,
2260                               OMPD_target_parallel, StartLoc, EndLoc,
2261                               NumClauses, /*NumChildren=*/1) {}
2262
2263  /// \brief Build an empty directive.
2264  ///
2265  /// \param NumClauses Number of clauses.
2266  ///
2267  explicit OMPTargetParallelDirective(unsigned NumClauses)
2268      : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass,
2269                               OMPD_target_parallel, SourceLocation(),
2270                               SourceLocation(), NumClauses,
2271                               /*NumChildren=*/1) {}
2272
2273public:
2274  /// \brief Creates directive with a list of \a Clauses.
2275  ///
2276  /// \param C AST context.
2277  /// \param StartLoc Starting location of the directive kind.
2278  /// \param EndLoc Ending Location of the directive.
2279  /// \param Clauses List of clauses.
2280  /// \param AssociatedStmt Statement, associated with the directive.
2281  ///
2282  static OMPTargetParallelDirective *
2283  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2284         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2285
2286  /// \brief Creates an empty directive with the place for \a NumClauses
2287  /// clauses.
2288  ///
2289  /// \param C AST context.
2290  /// \param NumClauses Number of clauses.
2291  ///
2292  static OMPTargetParallelDirective *
2293  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2294
2295  static bool classof(const Stmt *T) {
2296    return T->getStmtClass() == OMPTargetParallelDirectiveClass;
2297  }
2298};
2299
2300/// \brief This represents '#pragma omp target parallel for' directive.
2301///
2302/// \code
2303/// #pragma omp target parallel for private(a,b) reduction(+:c,d)
2304/// \endcode
2305/// In this example directive '#pragma omp target parallel for' has clauses
2306/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
2307/// and variables 'c' and 'd'.
2308///
2309class OMPTargetParallelForDirective : public OMPLoopDirective {
2310  friend class ASTStmtReader;
2311
2312  /// \brief true if current region has inner cancel directive.
2313  bool HasCancel;
2314
2315  /// \brief Build directive with the given start and end location.
2316  ///
2317  /// \param StartLoc Starting location of the directive kind.
2318  /// \param EndLoc Ending location of the directive.
2319  /// \param CollapsedNum Number of collapsed nested loops.
2320  /// \param NumClauses Number of clauses.
2321  ///
2322  OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2323                                unsigned CollapsedNum, unsigned NumClauses)
2324      : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass,
2325                         OMPD_target_parallel_for, StartLoc, EndLoc,
2326                         CollapsedNum, NumClauses),
2327        HasCancel(false) {}
2328
2329  /// \brief Build an empty directive.
2330  ///
2331  /// \param CollapsedNum Number of collapsed nested loops.
2332  /// \param NumClauses Number of clauses.
2333  ///
2334  explicit OMPTargetParallelForDirective(unsigned CollapsedNum,
2335                                         unsigned NumClauses)
2336      : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass,
2337                         OMPD_target_parallel_for, SourceLocation(),
2338                         SourceLocation(), CollapsedNum, NumClauses),
2339        HasCancel(false) {}
2340
2341  /// \brief Set cancel state.
2342  void setHasCancel(bool Has) { HasCancel = Has; }
2343
2344public:
2345  /// \brief Creates directive with a list of \a Clauses.
2346  ///
2347  /// \param C AST context.
2348  /// \param StartLoc Starting location of the directive kind.
2349  /// \param EndLoc Ending Location of the directive.
2350  /// \param CollapsedNum Number of collapsed loops.
2351  /// \param Clauses List of clauses.
2352  /// \param AssociatedStmt Statement, associated with the directive.
2353  /// \param Exprs Helper expressions for CodeGen.
2354  /// \param HasCancel true if current directive has inner cancel directive.
2355  ///
2356  static OMPTargetParallelForDirective *
2357  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2358         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2359         Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
2360
2361  /// \brief Creates an empty directive with the place
2362  /// for \a NumClauses clauses.
2363  ///
2364  /// \param C AST context.
2365  /// \param CollapsedNum Number of collapsed nested loops.
2366  /// \param NumClauses Number of clauses.
2367  ///
2368  static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C,
2369                                                    unsigned NumClauses,
2370                                                    unsigned CollapsedNum,
2371                                                    EmptyShell);
2372
2373  /// \brief Return true if current directive has inner cancel directive.
2374  bool hasCancel() const { return HasCancel; }
2375
2376  static bool classof(const Stmt *T) {
2377    return T->getStmtClass() == OMPTargetParallelForDirectiveClass;
2378  }
2379};
2380
2381/// \brief This represents '#pragma omp teams' directive.
2382///
2383/// \code
2384/// #pragma omp teams if(a)
2385/// \endcode
2386/// In this example directive '#pragma omp teams' has clause 'if' with
2387/// condition 'a'.
2388///
2389class OMPTeamsDirective : public OMPExecutableDirective {
2390  friend class ASTStmtReader;
2391  /// \brief Build directive with the given start and end location.
2392  ///
2393  /// \param StartLoc Starting location of the directive kind.
2394  /// \param EndLoc Ending location of the directive.
2395  /// \param NumClauses Number of clauses.
2396  ///
2397  OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2398                    unsigned NumClauses)
2399      : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
2400                               StartLoc, EndLoc, NumClauses, 1) {}
2401
2402  /// \brief Build an empty directive.
2403  ///
2404  /// \param NumClauses Number of clauses.
2405  ///
2406  explicit OMPTeamsDirective(unsigned NumClauses)
2407      : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
2408                               SourceLocation(), SourceLocation(), NumClauses,
2409                               1) {}
2410
2411public:
2412  /// \brief Creates directive with a list of \a Clauses.
2413  ///
2414  /// \param C AST context.
2415  /// \param StartLoc Starting location of the directive kind.
2416  /// \param EndLoc Ending Location of the directive.
2417  /// \param Clauses List of clauses.
2418  /// \param AssociatedStmt Statement, associated with the directive.
2419  ///
2420  static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2421                                   SourceLocation EndLoc,
2422                                   ArrayRef<OMPClause *> Clauses,
2423                                   Stmt *AssociatedStmt);
2424
2425  /// \brief Creates an empty directive with the place for \a NumClauses
2426  /// clauses.
2427  ///
2428  /// \param C AST context.
2429  /// \param NumClauses Number of clauses.
2430  ///
2431  static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
2432                                        unsigned NumClauses, EmptyShell);
2433
2434  static bool classof(const Stmt *T) {
2435    return T->getStmtClass() == OMPTeamsDirectiveClass;
2436  }
2437};
2438
2439/// \brief This represents '#pragma omp cancellation point' directive.
2440///
2441/// \code
2442/// #pragma omp cancellation point for
2443/// \endcode
2444///
2445/// In this example a cancellation point is created for innermost 'for' region.
2446class OMPCancellationPointDirective : public OMPExecutableDirective {
2447  friend class ASTStmtReader;
2448  OpenMPDirectiveKind CancelRegion;
2449  /// \brief Build directive with the given start and end location.
2450  ///
2451  /// \param StartLoc Starting location of the directive kind.
2452  /// \param EndLoc Ending location of the directive.
2453  ///
2454  OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2455      : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
2456                               OMPD_cancellation_point, StartLoc, EndLoc, 0, 0),
2457        CancelRegion(OMPD_unknown) {}
2458
2459  /// \brief Build an empty directive.
2460  ///
2461  explicit OMPCancellationPointDirective()
2462      : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
2463                               OMPD_cancellation_point, SourceLocation(),
2464                               SourceLocation(), 0, 0),
2465        CancelRegion(OMPD_unknown) {}
2466
2467  /// \brief Set cancel region for current cancellation point.
2468  /// \param CR Cancellation region.
2469  void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
2470
2471public:
2472  /// \brief Creates directive.
2473  ///
2474  /// \param C AST context.
2475  /// \param StartLoc Starting location of the directive kind.
2476  /// \param EndLoc Ending Location of the directive.
2477  ///
2478  static OMPCancellationPointDirective *
2479  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2480         OpenMPDirectiveKind CancelRegion);
2481
2482  /// \brief Creates an empty directive.
2483  ///
2484  /// \param C AST context.
2485  ///
2486  static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
2487                                                    EmptyShell);
2488
2489  /// \brief Get cancellation region for the current cancellation point.
2490  OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
2491
2492  static bool classof(const Stmt *T) {
2493    return T->getStmtClass() == OMPCancellationPointDirectiveClass;
2494  }
2495};
2496
2497/// \brief This represents '#pragma omp cancel' directive.
2498///
2499/// \code
2500/// #pragma omp cancel for
2501/// \endcode
2502///
2503/// In this example a cancel is created for innermost 'for' region.
2504class OMPCancelDirective : public OMPExecutableDirective {
2505  friend class ASTStmtReader;
2506  OpenMPDirectiveKind CancelRegion;
2507  /// \brief Build directive with the given start and end location.
2508  ///
2509  /// \param StartLoc Starting location of the directive kind.
2510  /// \param EndLoc Ending location of the directive.
2511  /// \param NumClauses Number of clauses.
2512  ///
2513  OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2514                     unsigned NumClauses)
2515      : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
2516                               StartLoc, EndLoc, NumClauses, 0),
2517        CancelRegion(OMPD_unknown) {}
2518
2519  /// \brief Build an empty directive.
2520  ///
2521  /// \param NumClauses Number of clauses.
2522  explicit OMPCancelDirective(unsigned NumClauses)
2523      : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
2524                               SourceLocation(), SourceLocation(), NumClauses,
2525                               0),
2526        CancelRegion(OMPD_unknown) {}
2527
2528  /// \brief Set cancel region for current cancellation point.
2529  /// \param CR Cancellation region.
2530  void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
2531
2532public:
2533  /// \brief Creates directive.
2534  ///
2535  /// \param C AST context.
2536  /// \param StartLoc Starting location of the directive kind.
2537  /// \param EndLoc Ending Location of the directive.
2538  /// \param Clauses List of clauses.
2539  ///
2540  static OMPCancelDirective *
2541  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2542         ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
2543
2544  /// \brief Creates an empty directive.
2545  ///
2546  /// \param C AST context.
2547  /// \param NumClauses Number of clauses.
2548  ///
2549  static OMPCancelDirective *CreateEmpty(const ASTContext &C,
2550                                         unsigned NumClauses, EmptyShell);
2551
2552  /// \brief Get cancellation region for the current cancellation point.
2553  OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
2554
2555  static bool classof(const Stmt *T) {
2556    return T->getStmtClass() == OMPCancelDirectiveClass;
2557  }
2558};
2559
2560/// \brief This represents '#pragma omp taskloop' directive.
2561///
2562/// \code
2563/// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
2564/// \endcode
2565/// In this example directive '#pragma omp taskloop' has clauses 'private'
2566/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
2567/// 'num_tasks' with expression 'num'.
2568///
2569class OMPTaskLoopDirective : public OMPLoopDirective {
2570  friend class ASTStmtReader;
2571  /// \brief Build directive with the given start and end location.
2572  ///
2573  /// \param StartLoc Starting location of the directive kind.
2574  /// \param EndLoc Ending location of the directive.
2575  /// \param CollapsedNum Number of collapsed nested loops.
2576  /// \param NumClauses Number of clauses.
2577  ///
2578  OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2579                       unsigned CollapsedNum, unsigned NumClauses)
2580      : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
2581                         StartLoc, EndLoc, CollapsedNum, NumClauses) {}
2582
2583  /// \brief Build an empty directive.
2584  ///
2585  /// \param CollapsedNum Number of collapsed nested loops.
2586  /// \param NumClauses Number of clauses.
2587  ///
2588  explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses)
2589      : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
2590                         SourceLocation(), SourceLocation(), CollapsedNum,
2591                         NumClauses) {}
2592
2593public:
2594  /// \brief Creates directive with a list of \a Clauses.
2595  ///
2596  /// \param C AST context.
2597  /// \param StartLoc Starting location of the directive kind.
2598  /// \param EndLoc Ending Location of the directive.
2599  /// \param CollapsedNum Number of collapsed loops.
2600  /// \param Clauses List of clauses.
2601  /// \param AssociatedStmt Statement, associated with the directive.
2602  /// \param Exprs Helper expressions for CodeGen.
2603  ///
2604  static OMPTaskLoopDirective *
2605  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2606         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2607         Stmt *AssociatedStmt, const HelperExprs &Exprs);
2608
2609  /// \brief Creates an empty directive with the place
2610  /// for \a NumClauses clauses.
2611  ///
2612  /// \param C AST context.
2613  /// \param CollapsedNum Number of collapsed nested loops.
2614  /// \param NumClauses Number of clauses.
2615  ///
2616  static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
2617                                           unsigned NumClauses,
2618                                           unsigned CollapsedNum, EmptyShell);
2619
2620  static bool classof(const Stmt *T) {
2621    return T->getStmtClass() == OMPTaskLoopDirectiveClass;
2622  }
2623};
2624
2625/// \brief This represents '#pragma omp taskloop simd' directive.
2626///
2627/// \code
2628/// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
2629/// \endcode
2630/// In this example directive '#pragma omp taskloop simd' has clauses 'private'
2631/// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
2632/// 'num_tasks' with expression 'num'.
2633///
2634class OMPTaskLoopSimdDirective : public OMPLoopDirective {
2635  friend class ASTStmtReader;
2636  /// \brief Build directive with the given start and end location.
2637  ///
2638  /// \param StartLoc Starting location of the directive kind.
2639  /// \param EndLoc Ending location of the directive.
2640  /// \param CollapsedNum Number of collapsed nested loops.
2641  /// \param NumClauses Number of clauses.
2642  ///
2643  OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2644                           unsigned CollapsedNum, unsigned NumClauses)
2645      : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
2646                         OMPD_taskloop_simd, StartLoc, EndLoc, CollapsedNum,
2647                         NumClauses) {}
2648
2649  /// \brief Build an empty directive.
2650  ///
2651  /// \param CollapsedNum Number of collapsed nested loops.
2652  /// \param NumClauses Number of clauses.
2653  ///
2654  explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
2655      : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
2656                         OMPD_taskloop_simd, SourceLocation(), SourceLocation(),
2657                         CollapsedNum, NumClauses) {}
2658
2659public:
2660  /// \brief Creates directive with a list of \a Clauses.
2661  ///
2662  /// \param C AST context.
2663  /// \param StartLoc Starting location of the directive kind.
2664  /// \param EndLoc Ending Location of the directive.
2665  /// \param CollapsedNum Number of collapsed loops.
2666  /// \param Clauses List of clauses.
2667  /// \param AssociatedStmt Statement, associated with the directive.
2668  /// \param Exprs Helper expressions for CodeGen.
2669  ///
2670  static OMPTaskLoopSimdDirective *
2671  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2672         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2673         Stmt *AssociatedStmt, const HelperExprs &Exprs);
2674
2675  /// \brief Creates an empty directive with the place
2676  /// for \a NumClauses clauses.
2677  ///
2678  /// \param C AST context.
2679  /// \param CollapsedNum Number of collapsed nested loops.
2680  /// \param NumClauses Number of clauses.
2681  ///
2682  static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
2683                                               unsigned NumClauses,
2684                                               unsigned CollapsedNum,
2685                                               EmptyShell);
2686
2687  static bool classof(const Stmt *T) {
2688    return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
2689  }
2690};
2691
2692/// \brief This represents '#pragma omp distribute' directive.
2693///
2694/// \code
2695/// #pragma omp distribute private(a,b)
2696/// \endcode
2697/// In this example directive '#pragma omp distribute' has clauses 'private'
2698/// with the variables 'a' and 'b'
2699///
2700class OMPDistributeDirective : public OMPLoopDirective {
2701  friend class ASTStmtReader;
2702
2703  /// \brief Build directive with the given start and end location.
2704  ///
2705  /// \param StartLoc Starting location of the directive kind.
2706  /// \param EndLoc Ending location of the directive.
2707  /// \param CollapsedNum Number of collapsed nested loops.
2708  /// \param NumClauses Number of clauses.
2709  ///
2710  OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2711                         unsigned CollapsedNum, unsigned NumClauses)
2712      : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
2713                         StartLoc, EndLoc, CollapsedNum, NumClauses)
2714        {}
2715
2716  /// \brief Build an empty directive.
2717  ///
2718  /// \param CollapsedNum Number of collapsed nested loops.
2719  /// \param NumClauses Number of clauses.
2720  ///
2721  explicit OMPDistributeDirective(unsigned CollapsedNum, unsigned NumClauses)
2722      : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
2723                         SourceLocation(), SourceLocation(), CollapsedNum,
2724                         NumClauses)
2725        {}
2726
2727public:
2728  /// \brief Creates directive with a list of \a Clauses.
2729  ///
2730  /// \param C AST context.
2731  /// \param StartLoc Starting location of the directive kind.
2732  /// \param EndLoc Ending Location of the directive.
2733  /// \param CollapsedNum Number of collapsed loops.
2734  /// \param Clauses List of clauses.
2735  /// \param AssociatedStmt Statement, associated with the directive.
2736  /// \param Exprs Helper expressions for CodeGen.
2737  ///
2738  static OMPDistributeDirective *
2739  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2740         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2741         Stmt *AssociatedStmt, const HelperExprs &Exprs);
2742
2743  /// \brief Creates an empty directive with the place
2744  /// for \a NumClauses clauses.
2745  ///
2746  /// \param C AST context.
2747  /// \param CollapsedNum Number of collapsed nested loops.
2748  /// \param NumClauses Number of clauses.
2749  ///
2750  static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
2751                                             unsigned NumClauses,
2752                                             unsigned CollapsedNum, EmptyShell);
2753
2754  static bool classof(const Stmt *T) {
2755    return T->getStmtClass() == OMPDistributeDirectiveClass;
2756  }
2757};
2758
2759/// \brief This represents '#pragma omp target update' directive.
2760///
2761/// \code
2762/// #pragma omp target update to(a) from(b) device(1)
2763/// \endcode
2764/// In this example directive '#pragma omp target update' has clause 'to' with
2765/// argument 'a', clause 'from' with argument 'b' and clause 'device' with
2766/// argument '1'.
2767///
2768class OMPTargetUpdateDirective : public OMPExecutableDirective {
2769  friend class ASTStmtReader;
2770  /// \brief Build directive with the given start and end location.
2771  ///
2772  /// \param StartLoc Starting location of the directive kind.
2773  /// \param EndLoc Ending Location of the directive.
2774  /// \param NumClauses The number of clauses.
2775  ///
2776  OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2777                           unsigned NumClauses)
2778      : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
2779                               OMPD_target_update, StartLoc, EndLoc, NumClauses,
2780                               0) {}
2781
2782  /// \brief Build an empty directive.
2783  ///
2784  /// \param NumClauses Number of clauses.
2785  ///
2786  explicit OMPTargetUpdateDirective(unsigned NumClauses)
2787      : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
2788                               OMPD_target_update, SourceLocation(),
2789                               SourceLocation(), NumClauses, 0) {}
2790
2791public:
2792  /// \brief Creates directive with a list of \a Clauses.
2793  ///
2794  /// \param C AST context.
2795  /// \param StartLoc Starting location of the directive kind.
2796  /// \param EndLoc Ending Location of the directive.
2797  /// \param Clauses List of clauses.
2798  ///
2799  static OMPTargetUpdateDirective *Create(const ASTContext &C,
2800                                          SourceLocation StartLoc,
2801                                          SourceLocation EndLoc,
2802                                          ArrayRef<OMPClause *> Clauses);
2803
2804  /// \brief Creates an empty directive with the place for \a NumClauses
2805  /// clauses.
2806  ///
2807  /// \param C AST context.
2808  /// \param NumClauses The number of clauses.
2809  ///
2810  static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C,
2811                                               unsigned NumClauses, EmptyShell);
2812
2813  static bool classof(const Stmt *T) {
2814    return T->getStmtClass() == OMPTargetUpdateDirectiveClass;
2815  }
2816};
2817
2818/// \brief This represents '#pragma omp distribute parallel for' composite
2819///  directive.
2820///
2821/// \code
2822/// #pragma omp distribute parallel for private(a,b)
2823/// \endcode
2824/// In this example directive '#pragma omp distribute parallel for' has clause
2825/// 'private' with the variables 'a' and 'b'
2826///
2827class OMPDistributeParallelForDirective : public OMPLoopDirective {
2828  friend class ASTStmtReader;
2829
2830  /// \brief Build directive with the given start and end location.
2831  ///
2832  /// \param StartLoc Starting location of the directive kind.
2833  /// \param EndLoc Ending location of the directive.
2834  /// \param CollapsedNum Number of collapsed nested loops.
2835  /// \param NumClauses Number of clauses.
2836  ///
2837  OMPDistributeParallelForDirective(SourceLocation StartLoc,
2838                                    SourceLocation EndLoc,
2839                                    unsigned CollapsedNum, unsigned NumClauses)
2840      : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass,
2841                         OMPD_distribute_parallel_for, StartLoc, EndLoc,
2842                         CollapsedNum, NumClauses) {}
2843
2844  /// \brief Build an empty directive.
2845  ///
2846  /// \param CollapsedNum Number of collapsed nested loops.
2847  /// \param NumClauses Number of clauses.
2848  ///
2849  explicit OMPDistributeParallelForDirective(unsigned CollapsedNum,
2850                                             unsigned NumClauses)
2851      : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass,
2852                         OMPD_distribute_parallel_for, SourceLocation(),
2853                         SourceLocation(), CollapsedNum, NumClauses) {}
2854
2855public:
2856  /// \brief Creates directive with a list of \a Clauses.
2857  ///
2858  /// \param C AST context.
2859  /// \param StartLoc Starting location of the directive kind.
2860  /// \param EndLoc Ending Location of the directive.
2861  /// \param CollapsedNum Number of collapsed loops.
2862  /// \param Clauses List of clauses.
2863  /// \param AssociatedStmt Statement, associated with the directive.
2864  /// \param Exprs Helper expressions for CodeGen.
2865  ///
2866  static OMPDistributeParallelForDirective *
2867  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2868         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2869         Stmt *AssociatedStmt, const HelperExprs &Exprs);
2870
2871  /// \brief Creates an empty directive with the place
2872  /// for \a NumClauses clauses.
2873  ///
2874  /// \param C AST context.
2875  /// \param CollapsedNum Number of collapsed nested loops.
2876  /// \param NumClauses Number of clauses.
2877  ///
2878  static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C,
2879                                                        unsigned NumClauses,
2880                                                        unsigned CollapsedNum,
2881                                                        EmptyShell);
2882
2883  static bool classof(const Stmt *T) {
2884    return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
2885  }
2886};
2887
2888/// This represents '#pragma omp distribute parallel for simd' composite
2889/// directive.
2890///
2891/// \code
2892/// #pragma omp distribute parallel for simd private(x)
2893/// \endcode
2894/// In this example directive '#pragma omp distribute parallel for simd' has
2895/// clause 'private' with the variables 'x'
2896///
2897class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective {
2898  friend class ASTStmtReader;
2899
2900  /// Build directive with the given start and end location.
2901  ///
2902  /// \param StartLoc Starting location of the directive kind.
2903  /// \param EndLoc Ending location of the directive.
2904  /// \param CollapsedNum Number of collapsed nested loops.
2905  /// \param NumClauses Number of clauses.
2906  ///
2907  OMPDistributeParallelForSimdDirective(SourceLocation StartLoc,
2908                                        SourceLocation EndLoc,
2909                                        unsigned CollapsedNum,
2910                                        unsigned NumClauses)
2911      : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass,
2912                         OMPD_distribute_parallel_for_simd, StartLoc,
2913                         EndLoc, CollapsedNum, NumClauses) {}
2914
2915  /// Build an empty directive.
2916  ///
2917  /// \param CollapsedNum Number of collapsed nested loops.
2918  /// \param NumClauses Number of clauses.
2919  ///
2920  explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum,
2921                                                 unsigned NumClauses)
2922      : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass,
2923                         OMPD_distribute_parallel_for_simd,
2924                         SourceLocation(), SourceLocation(), CollapsedNum,
2925                         NumClauses) {}
2926
2927public:
2928  /// Creates directive with a list of \a Clauses.
2929  ///
2930  /// \param C AST context.
2931  /// \param StartLoc Starting location of the directive kind.
2932  /// \param EndLoc Ending Location of the directive.
2933  /// \param CollapsedNum Number of collapsed loops.
2934  /// \param Clauses List of clauses.
2935  /// \param AssociatedStmt Statement, associated with the directive.
2936  /// \param Exprs Helper expressions for CodeGen.
2937  ///
2938  static OMPDistributeParallelForSimdDirective *Create(
2939      const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2940      unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2941      Stmt *AssociatedStmt, const HelperExprs &Exprs);
2942
2943  /// Creates an empty directive with the place for \a NumClauses clauses.
2944  ///
2945  /// \param C AST context.
2946  /// \param CollapsedNum Number of collapsed nested loops.
2947  /// \param NumClauses Number of clauses.
2948  ///
2949  static OMPDistributeParallelForSimdDirective *CreateEmpty(
2950      const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
2951      EmptyShell);
2952
2953  static bool classof(const Stmt *T) {
2954    return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass;
2955  }
2956};
2957
2958/// This represents '#pragma omp distribute simd' composite directive.
2959///
2960/// \code
2961/// #pragma omp distribute simd private(x)
2962/// \endcode
2963/// In this example directive '#pragma omp distribute simd' has clause
2964/// 'private' with the variables 'x'
2965///
2966class OMPDistributeSimdDirective final : public OMPLoopDirective {
2967  friend class ASTStmtReader;
2968
2969  /// Build directive with the given start and end location.
2970  ///
2971  /// \param StartLoc Starting location of the directive kind.
2972  /// \param EndLoc Ending location of the directive.
2973  /// \param CollapsedNum Number of collapsed nested loops.
2974  /// \param NumClauses Number of clauses.
2975  ///
2976  OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2977                             unsigned CollapsedNum, unsigned NumClauses)
2978      : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass,
2979                         OMPD_distribute_simd, StartLoc, EndLoc, CollapsedNum,
2980                         NumClauses) {}
2981
2982  /// Build an empty directive.
2983  ///
2984  /// \param CollapsedNum Number of collapsed nested loops.
2985  /// \param NumClauses Number of clauses.
2986  ///
2987  explicit OMPDistributeSimdDirective(unsigned CollapsedNum,
2988                                      unsigned NumClauses)
2989      : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass,
2990                         OMPD_distribute_simd, SourceLocation(),
2991                         SourceLocation(), CollapsedNum, NumClauses) {}
2992
2993public:
2994  /// Creates directive with a list of \a Clauses.
2995  ///
2996  /// \param C AST context.
2997  /// \param StartLoc Starting location of the directive kind.
2998  /// \param EndLoc Ending Location of the directive.
2999  /// \param CollapsedNum Number of collapsed loops.
3000  /// \param Clauses List of clauses.
3001  /// \param AssociatedStmt Statement, associated with the directive.
3002  /// \param Exprs Helper expressions for CodeGen.
3003  ///
3004  static OMPDistributeSimdDirective *
3005  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3006         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3007         Stmt *AssociatedStmt, const HelperExprs &Exprs);
3008
3009  /// Creates an empty directive with the place for \a NumClauses clauses.
3010  ///
3011  /// \param C AST context.
3012  /// \param CollapsedNum Number of collapsed nested loops.
3013  /// \param NumClauses Number of clauses.
3014  ///
3015  static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C,
3016                                                 unsigned NumClauses,
3017                                                 unsigned CollapsedNum,
3018                                                 EmptyShell);
3019
3020  static bool classof(const Stmt *T) {
3021    return T->getStmtClass() == OMPDistributeSimdDirectiveClass;
3022  }
3023};
3024
3025/// This represents '#pragma omp target parallel for simd' directive.
3026///
3027/// \code
3028/// #pragma omp target parallel for simd private(a) map(b) safelen(c)
3029/// \endcode
3030/// In this example directive '#pragma omp target parallel for simd' has clauses
3031/// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen'
3032/// with the variable 'c'.
3033///
3034class OMPTargetParallelForSimdDirective final : public OMPLoopDirective {
3035  friend class ASTStmtReader;
3036
3037  /// Build directive with the given start and end location.
3038  ///
3039  /// \param StartLoc Starting location of the directive kind.
3040  /// \param EndLoc Ending location of the directive.
3041  /// \param CollapsedNum Number of collapsed nested loops.
3042  /// \param NumClauses Number of clauses.
3043  ///
3044  OMPTargetParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3045                                unsigned CollapsedNum, unsigned NumClauses)
3046      : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass,
3047                         OMPD_target_parallel_for_simd, StartLoc, EndLoc,
3048                         CollapsedNum, NumClauses) {}
3049
3050  /// Build an empty directive.
3051  ///
3052  /// \param CollapsedNum Number of collapsed nested loops.
3053  /// \param NumClauses Number of clauses.
3054  ///
3055  explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum,
3056                                             unsigned NumClauses)
3057      : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass,
3058                         OMPD_target_parallel_for_simd, SourceLocation(),
3059                         SourceLocation(), CollapsedNum, NumClauses) {}
3060
3061public:
3062  /// Creates directive with a list of \a Clauses.
3063  ///
3064  /// \param C AST context.
3065  /// \param StartLoc Starting location of the directive kind.
3066  /// \param EndLoc Ending Location of the directive.
3067  /// \param CollapsedNum Number of collapsed loops.
3068  /// \param Clauses List of clauses.
3069  /// \param AssociatedStmt Statement, associated with the directive.
3070  /// \param Exprs Helper expressions for CodeGen.
3071  ///
3072  static OMPTargetParallelForSimdDirective *
3073  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3074         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3075         Stmt *AssociatedStmt, const HelperExprs &Exprs);
3076
3077  /// Creates an empty directive with the place for \a NumClauses clauses.
3078  ///
3079  /// \param C AST context.
3080  /// \param CollapsedNum Number of collapsed nested loops.
3081  /// \param NumClauses Number of clauses.
3082  ///
3083  static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C,
3084                                                        unsigned NumClauses,
3085                                                        unsigned CollapsedNum,
3086                                                        EmptyShell);
3087
3088  static bool classof(const Stmt *T) {
3089    return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
3090  }
3091};
3092
3093} // end namespace clang
3094
3095#endif
3096