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