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