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