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