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