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