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