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