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