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