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