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