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