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