• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 /// \brief 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 /// \brief This is a basic class for representing single OpenMP executable
31 /// directive.
32 ///
33 class OMPExecutableDirective : public Stmt {
34   friend class ASTStmtReader;
35   /// \brief Kind of the directive.
36   OpenMPDirectiveKind Kind;
37   /// \brief Starting location of the directive (directive keyword).
38   SourceLocation StartLoc;
39   /// \brief Ending location of the directive.
40   SourceLocation EndLoc;
41   /// \brief Numbers of clauses.
42   const unsigned NumClauses;
43   /// \brief Number of child expressions/stmts.
44   const unsigned NumChildren;
45   /// \brief 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   /// \brief 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   /// \brief 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), llvm::alignOf<OMPClause *>())) {}
74 
75   /// \brief 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   /// \brief 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   /// \brief 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   /// \brief Returns starting location of directive kind.
getLocStart()168   SourceLocation getLocStart() const { return StartLoc; }
169   /// \brief Returns ending location of directive.
getLocEnd()170   SourceLocation getLocEnd() const { return EndLoc; }
171 
172   /// \brief 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   /// \brief 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   /// \brief Get number of clauses.
getNumClauses()184   unsigned getNumClauses() const { return NumClauses; }
185 
186   /// \brief 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   /// \brief Returns true if directive has associated statement.
hasAssociatedStmt()193   bool hasAssociatedStmt() const { return NumChildren > 0; }
194 
195   /// \brief Returns statement associated with the directive.
getAssociatedStmt()196   Stmt *getAssociatedStmt() const {
197     assert(hasAssociatedStmt() && "no associated statement.");
198     return const_cast<Stmt *>(*child_begin());
199   }
200 
getDirectiveKind()201   OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
202 
classof(const Stmt * S)203   static bool classof(const Stmt *S) {
204     return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
205            S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
206   }
207 
children()208   child_range children() {
209     if (!hasAssociatedStmt())
210       return child_range(child_iterator(), child_iterator());
211     Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
212     return child_range(ChildStorage, ChildStorage + NumChildren);
213   }
214 
clauses()215   ArrayRef<OMPClause *> clauses() { return getClauses(); }
216 
clauses()217   ArrayRef<OMPClause *> clauses() const {
218     return const_cast<OMPExecutableDirective *>(this)->getClauses();
219   }
220 };
221 
222 /// \brief This represents '#pragma omp parallel' directive.
223 ///
224 /// \code
225 /// #pragma omp parallel private(a,b) reduction(+: c,d)
226 /// \endcode
227 /// In this example directive '#pragma omp parallel' has clauses 'private'
228 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
229 /// variables 'c' and 'd'.
230 ///
231 class OMPParallelDirective : public OMPExecutableDirective {
232   friend class ASTStmtReader;
233   /// \brief true if the construct has inner cancel directive.
234   bool HasCancel;
235 
236   /// \brief Build directive with the given start and end location.
237   ///
238   /// \param StartLoc Starting location of the directive (directive keyword).
239   /// \param EndLoc Ending Location of the directive.
240   ///
OMPParallelDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)241   OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
242                        unsigned NumClauses)
243       : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
244                                StartLoc, EndLoc, NumClauses, 1),
245         HasCancel(false) {}
246 
247   /// \brief Build an empty directive.
248   ///
249   /// \param NumClauses Number of clauses.
250   ///
OMPParallelDirective(unsigned NumClauses)251   explicit OMPParallelDirective(unsigned NumClauses)
252       : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
253                                SourceLocation(), SourceLocation(), NumClauses,
254                                1),
255         HasCancel(false) {}
256 
257   /// \brief Set cancel state.
setHasCancel(bool Has)258   void setHasCancel(bool Has) { HasCancel = Has; }
259 
260 public:
261   /// \brief Creates directive with a list of \a Clauses.
262   ///
263   /// \param C AST context.
264   /// \param StartLoc Starting location of the directive kind.
265   /// \param EndLoc Ending Location of the directive.
266   /// \param Clauses List of clauses.
267   /// \param AssociatedStmt Statement associated with the directive.
268   /// \param HasCancel true if this directive has inner cancel directive.
269   ///
270   static OMPParallelDirective *
271   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
272          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
273 
274   /// \brief Creates an empty directive with the place for \a N clauses.
275   ///
276   /// \param C AST context.
277   /// \param NumClauses Number of clauses.
278   ///
279   static OMPParallelDirective *CreateEmpty(const ASTContext &C,
280                                            unsigned NumClauses, EmptyShell);
281 
282   /// \brief Return true if current directive has inner cancel directive.
hasCancel()283   bool hasCancel() const { return HasCancel; }
284 
classof(const Stmt * T)285   static bool classof(const Stmt *T) {
286     return T->getStmtClass() == OMPParallelDirectiveClass;
287   }
288 };
289 
290 /// \brief This is a common base class for loop directives ('omp simd', 'omp
291 /// for', 'omp for simd' etc.). It is responsible for the loop code generation.
292 ///
293 class OMPLoopDirective : public OMPExecutableDirective {
294   friend class ASTStmtReader;
295   /// \brief Number of collapsed loops as specified by 'collapse' clause.
296   unsigned CollapsedNum;
297 
298   /// \brief Offsets to the stored exprs.
299   /// This enumeration contains offsets to all the pointers to children
300   /// expressions stored in OMPLoopDirective.
301   /// The first 9 children are nesessary for all the loop directives, and
302   /// the next 10 are specific to the worksharing ones.
303   /// After the fixed children, three arrays of length CollapsedNum are
304   /// allocated: loop counters, their updates and final values.
305   /// PrevLowerBound and PrevUpperBound are used to communicate blocking
306   /// information in composite constructs which require loop blocking
307   ///
308   enum {
309     AssociatedStmtOffset = 0,
310     IterationVariableOffset = 1,
311     LastIterationOffset = 2,
312     CalcLastIterationOffset = 3,
313     PreConditionOffset = 4,
314     CondOffset = 5,
315     InitOffset = 6,
316     IncOffset = 7,
317     PreInitsOffset = 8,
318     // The '...End' enumerators do not correspond to child expressions - they
319     // specify the offset to the end (and start of the following counters/
320     // updates/finals arrays).
321     DefaultEnd = 9,
322     // The following 7 exprs are used by worksharing loops only.
323     IsLastIterVariableOffset = 9,
324     LowerBoundVariableOffset = 10,
325     UpperBoundVariableOffset = 11,
326     StrideVariableOffset = 12,
327     EnsureUpperBoundOffset = 13,
328     NextLowerBoundOffset = 14,
329     NextUpperBoundOffset = 15,
330     NumIterationsOffset = 16,
331     PrevLowerBoundVariableOffset = 17,
332     PrevUpperBoundVariableOffset = 18,
333     // Offset to the end (and start of the following counters/updates/finals
334     // arrays) for worksharing loop directives.
335     WorksharingEnd = 19,
336   };
337 
338   /// \brief Get the counters storage.
getCounters()339   MutableArrayRef<Expr *> getCounters() {
340     Expr **Storage = reinterpret_cast<Expr **>(
341         &(*(std::next(child_begin(), getArraysOffset(getDirectiveKind())))));
342     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
343   }
344 
345   /// \brief Get the private counters storage.
getPrivateCounters()346   MutableArrayRef<Expr *> getPrivateCounters() {
347     Expr **Storage = reinterpret_cast<Expr **>(&*std::next(
348         child_begin(), getArraysOffset(getDirectiveKind()) + CollapsedNum));
349     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
350   }
351 
352   /// \brief Get the updates storage.
getInits()353   MutableArrayRef<Expr *> getInits() {
354     Expr **Storage = reinterpret_cast<Expr **>(
355         &*std::next(child_begin(),
356                     getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum));
357     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
358   }
359 
360   /// \brief Get the updates storage.
getUpdates()361   MutableArrayRef<Expr *> getUpdates() {
362     Expr **Storage = reinterpret_cast<Expr **>(
363         &*std::next(child_begin(),
364                     getArraysOffset(getDirectiveKind()) + 3 * CollapsedNum));
365     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
366   }
367 
368   /// \brief Get the final counter updates storage.
getFinals()369   MutableArrayRef<Expr *> getFinals() {
370     Expr **Storage = reinterpret_cast<Expr **>(
371         &*std::next(child_begin(),
372                     getArraysOffset(getDirectiveKind()) + 4 * CollapsedNum));
373     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
374   }
375 
376 protected:
377   /// \brief Build instance of loop directive of class \a Kind.
378   ///
379   /// \param SC Statement class.
380   /// \param Kind Kind of OpenMP directive.
381   /// \param StartLoc Starting location of the directive (directive keyword).
382   /// \param EndLoc Ending location of the directive.
383   /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
384   /// \param NumClauses Number of clauses.
385   /// \param NumSpecialChildren Number of additional directive-specific stmts.
386   ///
387   template <typename T>
388   OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind,
389                    SourceLocation StartLoc, SourceLocation EndLoc,
390                    unsigned CollapsedNum, unsigned NumClauses,
391                    unsigned NumSpecialChildren = 0)
392       : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses,
393                                numLoopChildren(CollapsedNum, Kind) +
394                                    NumSpecialChildren),
395         CollapsedNum(CollapsedNum) {}
396 
397   /// \brief Offset to the start of children expression arrays.
getArraysOffset(OpenMPDirectiveKind Kind)398   static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
399     return (isOpenMPWorksharingDirective(Kind) ||
400             isOpenMPTaskLoopDirective(Kind) ||
401             isOpenMPDistributeDirective(Kind))
402                ? WorksharingEnd
403                : DefaultEnd;
404   }
405 
406   /// \brief Children number.
numLoopChildren(unsigned CollapsedNum,OpenMPDirectiveKind Kind)407   static unsigned numLoopChildren(unsigned CollapsedNum,
408                                   OpenMPDirectiveKind Kind) {
409     return getArraysOffset(Kind) + 5 * CollapsedNum; // Counters,
410                                                      // PrivateCounters, Inits,
411                                                      // Updates and Finals
412   }
413 
setIterationVariable(Expr * IV)414   void setIterationVariable(Expr *IV) {
415     *std::next(child_begin(), IterationVariableOffset) = IV;
416   }
setLastIteration(Expr * LI)417   void setLastIteration(Expr *LI) {
418     *std::next(child_begin(), LastIterationOffset) = LI;
419   }
setCalcLastIteration(Expr * CLI)420   void setCalcLastIteration(Expr *CLI) {
421     *std::next(child_begin(), CalcLastIterationOffset) = CLI;
422   }
setPreCond(Expr * PC)423   void setPreCond(Expr *PC) {
424     *std::next(child_begin(), PreConditionOffset) = PC;
425   }
setCond(Expr * Cond)426   void setCond(Expr *Cond) {
427     *std::next(child_begin(), CondOffset) = Cond;
428   }
setInit(Expr * Init)429   void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; }
setInc(Expr * Inc)430   void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; }
setPreInits(Stmt * PreInits)431   void setPreInits(Stmt *PreInits) {
432     *std::next(child_begin(), PreInitsOffset) = PreInits;
433   }
setIsLastIterVariable(Expr * IL)434   void setIsLastIterVariable(Expr *IL) {
435     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
436             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
437             isOpenMPDistributeDirective(getDirectiveKind())) &&
438            "expected worksharing loop directive");
439     *std::next(child_begin(), IsLastIterVariableOffset) = IL;
440   }
setLowerBoundVariable(Expr * LB)441   void setLowerBoundVariable(Expr *LB) {
442     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
443             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
444             isOpenMPDistributeDirective(getDirectiveKind())) &&
445            "expected worksharing loop directive");
446     *std::next(child_begin(), LowerBoundVariableOffset) = LB;
447   }
setUpperBoundVariable(Expr * UB)448   void setUpperBoundVariable(Expr *UB) {
449     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
450             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
451             isOpenMPDistributeDirective(getDirectiveKind())) &&
452            "expected worksharing loop directive");
453     *std::next(child_begin(), UpperBoundVariableOffset) = UB;
454   }
setStrideVariable(Expr * ST)455   void setStrideVariable(Expr *ST) {
456     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
457             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
458             isOpenMPDistributeDirective(getDirectiveKind())) &&
459            "expected worksharing loop directive");
460     *std::next(child_begin(), StrideVariableOffset) = ST;
461   }
setEnsureUpperBound(Expr * EUB)462   void setEnsureUpperBound(Expr *EUB) {
463     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
464             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
465             isOpenMPDistributeDirective(getDirectiveKind())) &&
466            "expected worksharing loop directive");
467     *std::next(child_begin(), EnsureUpperBoundOffset) = EUB;
468   }
setNextLowerBound(Expr * NLB)469   void setNextLowerBound(Expr *NLB) {
470     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
471             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
472             isOpenMPDistributeDirective(getDirectiveKind())) &&
473            "expected worksharing loop directive");
474     *std::next(child_begin(), NextLowerBoundOffset) = NLB;
475   }
setNextUpperBound(Expr * NUB)476   void setNextUpperBound(Expr *NUB) {
477     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
478             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
479             isOpenMPDistributeDirective(getDirectiveKind())) &&
480            "expected worksharing loop directive");
481     *std::next(child_begin(), NextUpperBoundOffset) = NUB;
482   }
setNumIterations(Expr * NI)483   void setNumIterations(Expr *NI) {
484     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
485             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
486             isOpenMPDistributeDirective(getDirectiveKind())) &&
487            "expected worksharing loop directive");
488     *std::next(child_begin(), NumIterationsOffset) = NI;
489   }
setPrevLowerBoundVariable(Expr * PrevLB)490   void setPrevLowerBoundVariable(Expr *PrevLB) {
491     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
492             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
493             isOpenMPDistributeDirective(getDirectiveKind())) &&
494            "expected worksharing loop directive");
495     *std::next(child_begin(), PrevLowerBoundVariableOffset) = PrevLB;
496   }
setPrevUpperBoundVariable(Expr * PrevUB)497   void setPrevUpperBoundVariable(Expr *PrevUB) {
498     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
499             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
500             isOpenMPDistributeDirective(getDirectiveKind())) &&
501            "expected worksharing loop directive");
502     *std::next(child_begin(), PrevUpperBoundVariableOffset) = PrevUB;
503   }
504   void setCounters(ArrayRef<Expr *> A);
505   void setPrivateCounters(ArrayRef<Expr *> A);
506   void setInits(ArrayRef<Expr *> A);
507   void setUpdates(ArrayRef<Expr *> A);
508   void setFinals(ArrayRef<Expr *> A);
509 
510 public:
511   /// \brief The expressions built for the OpenMP loop CodeGen for the
512   /// whole collapsed loop nest.
513   struct HelperExprs {
514     /// \brief Loop iteration variable.
515     Expr *IterationVarRef;
516     /// \brief Loop last iteration number.
517     Expr *LastIteration;
518     /// \brief Loop number of iterations.
519     Expr *NumIterations;
520     /// \brief Calculation of last iteration.
521     Expr *CalcLastIteration;
522     /// \brief Loop pre-condition.
523     Expr *PreCond;
524     /// \brief Loop condition.
525     Expr *Cond;
526     /// \brief Loop iteration variable init.
527     Expr *Init;
528     /// \brief Loop increment.
529     Expr *Inc;
530     /// \brief IsLastIteration - local flag variable passed to runtime.
531     Expr *IL;
532     /// \brief LowerBound - local variable passed to runtime.
533     Expr *LB;
534     /// \brief UpperBound - local variable passed to runtime.
535     Expr *UB;
536     /// \brief Stride - local variable passed to runtime.
537     Expr *ST;
538     /// \brief EnsureUpperBound -- expression LB = min(LB, NumIterations).
539     Expr *EUB;
540     /// \brief Update of LowerBound for statically sheduled 'omp for' loops.
541     Expr *NLB;
542     /// \brief Update of UpperBound for statically sheduled 'omp for' loops.
543     Expr *NUB;
544     /// \brief PreviousLowerBound - local variable passed to runtime in the
545     /// enclosing schedule or null if that does not apply.
546     Expr *PrevLB;
547     /// \brief PreviousUpperBound - local variable passed to runtime in the
548     /// enclosing schedule or null if that does not apply.
549     Expr *PrevUB;
550     /// \brief Counters Loop counters.
551     SmallVector<Expr *, 4> Counters;
552     /// \brief PrivateCounters Loop counters.
553     SmallVector<Expr *, 4> PrivateCounters;
554     /// \brief Expressions for loop counters inits for CodeGen.
555     SmallVector<Expr *, 4> Inits;
556     /// \brief Expressions for loop counters update for CodeGen.
557     SmallVector<Expr *, 4> Updates;
558     /// \brief Final loop counter values for GodeGen.
559     SmallVector<Expr *, 4> Finals;
560     /// Init statement for all captured expressions.
561     Stmt *PreInits;
562 
563     /// \brief Check if all the expressions are built (does not check the
564     /// worksharing ones).
builtAllHelperExprs565     bool builtAll() {
566       return IterationVarRef != nullptr && LastIteration != nullptr &&
567              NumIterations != nullptr && PreCond != nullptr &&
568              Cond != nullptr && Init != nullptr && Inc != nullptr;
569     }
570 
571     /// \brief Initialize all the fields to null.
572     /// \param Size Number of elements in the counters/finals/updates arrays.
clearHelperExprs573     void clear(unsigned Size) {
574       IterationVarRef = nullptr;
575       LastIteration = nullptr;
576       CalcLastIteration = nullptr;
577       PreCond = nullptr;
578       Cond = nullptr;
579       Init = nullptr;
580       Inc = nullptr;
581       IL = nullptr;
582       LB = nullptr;
583       UB = nullptr;
584       ST = nullptr;
585       EUB = nullptr;
586       NLB = nullptr;
587       NUB = nullptr;
588       NumIterations = nullptr;
589       PrevLB = nullptr;
590       PrevUB = nullptr;
591       Counters.resize(Size);
592       PrivateCounters.resize(Size);
593       Inits.resize(Size);
594       Updates.resize(Size);
595       Finals.resize(Size);
596       for (unsigned i = 0; i < Size; ++i) {
597         Counters[i] = nullptr;
598         PrivateCounters[i] = nullptr;
599         Inits[i] = nullptr;
600         Updates[i] = nullptr;
601         Finals[i] = nullptr;
602       }
603       PreInits = nullptr;
604     }
605   };
606 
607   /// \brief Get number of collapsed loops.
getCollapsedNumber()608   unsigned getCollapsedNumber() const { return CollapsedNum; }
609 
getIterationVariable()610   Expr *getIterationVariable() const {
611     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
612         *std::next(child_begin(), IterationVariableOffset)));
613   }
getLastIteration()614   Expr *getLastIteration() const {
615     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
616         *std::next(child_begin(), LastIterationOffset)));
617   }
getCalcLastIteration()618   Expr *getCalcLastIteration() const {
619     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
620         *std::next(child_begin(), CalcLastIterationOffset)));
621   }
getPreCond()622   Expr *getPreCond() const {
623     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
624         *std::next(child_begin(), PreConditionOffset)));
625   }
getCond()626   Expr *getCond() const {
627     return const_cast<Expr *>(
628         reinterpret_cast<const Expr *>(*std::next(child_begin(), CondOffset)));
629   }
getInit()630   Expr *getInit() const {
631     return const_cast<Expr *>(
632         reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset)));
633   }
getInc()634   Expr *getInc() const {
635     return const_cast<Expr *>(
636         reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset)));
637   }
getPreInits()638   const Stmt *getPreInits() const {
639     return *std::next(child_begin(), PreInitsOffset);
640   }
getPreInits()641   Stmt *getPreInits() { return *std::next(child_begin(), PreInitsOffset); }
getIsLastIterVariable()642   Expr *getIsLastIterVariable() const {
643     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
644             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
645             isOpenMPDistributeDirective(getDirectiveKind())) &&
646            "expected worksharing loop directive");
647     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
648         *std::next(child_begin(), IsLastIterVariableOffset)));
649   }
getLowerBoundVariable()650   Expr *getLowerBoundVariable() const {
651     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
652             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
653             isOpenMPDistributeDirective(getDirectiveKind())) &&
654            "expected worksharing loop directive");
655     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
656         *std::next(child_begin(), LowerBoundVariableOffset)));
657   }
getUpperBoundVariable()658   Expr *getUpperBoundVariable() const {
659     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
660             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
661             isOpenMPDistributeDirective(getDirectiveKind())) &&
662            "expected worksharing loop directive");
663     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
664         *std::next(child_begin(), UpperBoundVariableOffset)));
665   }
getStrideVariable()666   Expr *getStrideVariable() const {
667     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
668             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
669             isOpenMPDistributeDirective(getDirectiveKind())) &&
670            "expected worksharing loop directive");
671     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
672         *std::next(child_begin(), StrideVariableOffset)));
673   }
getEnsureUpperBound()674   Expr *getEnsureUpperBound() const {
675     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
676             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
677             isOpenMPDistributeDirective(getDirectiveKind())) &&
678            "expected worksharing loop directive");
679     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
680         *std::next(child_begin(), EnsureUpperBoundOffset)));
681   }
getNextLowerBound()682   Expr *getNextLowerBound() const {
683     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
684             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
685             isOpenMPDistributeDirective(getDirectiveKind())) &&
686            "expected worksharing loop directive");
687     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
688         *std::next(child_begin(), NextLowerBoundOffset)));
689   }
getNextUpperBound()690   Expr *getNextUpperBound() const {
691     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
692             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
693             isOpenMPDistributeDirective(getDirectiveKind())) &&
694            "expected worksharing loop directive");
695     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
696         *std::next(child_begin(), NextUpperBoundOffset)));
697   }
getNumIterations()698   Expr *getNumIterations() const {
699     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
700             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
701             isOpenMPDistributeDirective(getDirectiveKind())) &&
702            "expected worksharing loop directive");
703     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
704         *std::next(child_begin(), NumIterationsOffset)));
705   }
getPrevLowerBoundVariable()706   Expr *getPrevLowerBoundVariable() const {
707     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
708             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
709             isOpenMPDistributeDirective(getDirectiveKind())) &&
710            "expected worksharing loop directive");
711     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
712         *std::next(child_begin(), PrevLowerBoundVariableOffset)));
713   }
getPrevUpperBoundVariable()714   Expr *getPrevUpperBoundVariable() const {
715     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
716             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
717             isOpenMPDistributeDirective(getDirectiveKind())) &&
718            "expected worksharing loop directive");
719     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
720         *std::next(child_begin(), PrevUpperBoundVariableOffset)));
721   }
getBody()722   const Stmt *getBody() const {
723     // This relies on the loop form is already checked by Sema.
724     Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
725     Body = cast<ForStmt>(Body)->getBody();
726     for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
727       Body = Body->IgnoreContainers();
728       Body = cast<ForStmt>(Body)->getBody();
729     }
730     return Body;
731   }
732 
counters()733   ArrayRef<Expr *> counters() { return getCounters(); }
734 
counters()735   ArrayRef<Expr *> counters() const {
736     return const_cast<OMPLoopDirective *>(this)->getCounters();
737   }
738 
private_counters()739   ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
740 
private_counters()741   ArrayRef<Expr *> private_counters() const {
742     return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
743   }
744 
inits()745   ArrayRef<Expr *> inits() { return getInits(); }
746 
inits()747   ArrayRef<Expr *> inits() const {
748     return const_cast<OMPLoopDirective *>(this)->getInits();
749   }
750 
updates()751   ArrayRef<Expr *> updates() { return getUpdates(); }
752 
updates()753   ArrayRef<Expr *> updates() const {
754     return const_cast<OMPLoopDirective *>(this)->getUpdates();
755   }
756 
finals()757   ArrayRef<Expr *> finals() { return getFinals(); }
758 
finals()759   ArrayRef<Expr *> finals() const {
760     return const_cast<OMPLoopDirective *>(this)->getFinals();
761   }
762 
classof(const Stmt * T)763   static bool classof(const Stmt *T) {
764     return T->getStmtClass() == OMPSimdDirectiveClass ||
765            T->getStmtClass() == OMPForDirectiveClass ||
766            T->getStmtClass() == OMPForSimdDirectiveClass ||
767            T->getStmtClass() == OMPParallelForDirectiveClass ||
768            T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
769            T->getStmtClass() == OMPTaskLoopDirectiveClass ||
770            T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
771            T->getStmtClass() == OMPDistributeDirectiveClass ||
772            T->getStmtClass() == OMPTargetParallelForDirectiveClass ||
773            T->getStmtClass() == OMPDistributeParallelForDirectiveClass ||
774            T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass ||
775            T->getStmtClass() == OMPDistributeSimdDirectiveClass ||
776            T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
777   }
778 };
779 
780 /// \brief This represents '#pragma omp simd' directive.
781 ///
782 /// \code
783 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
784 /// \endcode
785 /// In this example directive '#pragma omp simd' has clauses 'private'
786 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
787 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
788 ///
789 class OMPSimdDirective : public OMPLoopDirective {
790   friend class ASTStmtReader;
791   /// \brief Build directive with the given start and end location.
792   ///
793   /// \param StartLoc Starting location of the directive kind.
794   /// \param EndLoc Ending location of the directive.
795   /// \param CollapsedNum Number of collapsed nested loops.
796   /// \param NumClauses Number of clauses.
797   ///
OMPSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)798   OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
799                    unsigned CollapsedNum, unsigned NumClauses)
800       : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
801                          EndLoc, CollapsedNum, NumClauses) {}
802 
803   /// \brief Build an empty directive.
804   ///
805   /// \param CollapsedNum Number of collapsed nested loops.
806   /// \param NumClauses Number of clauses.
807   ///
OMPSimdDirective(unsigned CollapsedNum,unsigned NumClauses)808   explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
809       : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd,
810                          SourceLocation(), SourceLocation(), CollapsedNum,
811                          NumClauses) {}
812 
813 public:
814   /// \brief Creates directive with a list of \a Clauses.
815   ///
816   /// \param C AST context.
817   /// \param StartLoc Starting location of the directive kind.
818   /// \param EndLoc Ending Location of the directive.
819   /// \param CollapsedNum Number of collapsed loops.
820   /// \param Clauses List of clauses.
821   /// \param AssociatedStmt Statement, associated with the directive.
822   /// \param Exprs Helper expressions for CodeGen.
823   ///
824   static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
825                                   SourceLocation EndLoc, unsigned CollapsedNum,
826                                   ArrayRef<OMPClause *> Clauses,
827                                   Stmt *AssociatedStmt,
828                                   const HelperExprs &Exprs);
829 
830   /// \brief Creates an empty directive with the place
831   /// for \a NumClauses clauses.
832   ///
833   /// \param C AST context.
834   /// \param CollapsedNum Number of collapsed nested loops.
835   /// \param NumClauses Number of clauses.
836   ///
837   static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
838                                        unsigned CollapsedNum, EmptyShell);
839 
classof(const Stmt * T)840   static bool classof(const Stmt *T) {
841     return T->getStmtClass() == OMPSimdDirectiveClass;
842   }
843 };
844 
845 /// \brief This represents '#pragma omp for' directive.
846 ///
847 /// \code
848 /// #pragma omp for private(a,b) reduction(+:c,d)
849 /// \endcode
850 /// In this example directive '#pragma omp for' has clauses 'private' with the
851 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
852 /// and 'd'.
853 ///
854 class OMPForDirective : public OMPLoopDirective {
855   friend class ASTStmtReader;
856 
857   /// \brief true if current directive has inner cancel directive.
858   bool HasCancel;
859 
860   /// \brief Build directive with the given start and end location.
861   ///
862   /// \param StartLoc Starting location of the directive kind.
863   /// \param EndLoc Ending location of the directive.
864   /// \param CollapsedNum Number of collapsed nested loops.
865   /// \param NumClauses Number of clauses.
866   ///
OMPForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)867   OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
868                   unsigned CollapsedNum, unsigned NumClauses)
869       : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc,
870                          CollapsedNum, NumClauses),
871         HasCancel(false) {}
872 
873   /// \brief Build an empty directive.
874   ///
875   /// \param CollapsedNum Number of collapsed nested loops.
876   /// \param NumClauses Number of clauses.
877   ///
OMPForDirective(unsigned CollapsedNum,unsigned NumClauses)878   explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
879       : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(),
880                          SourceLocation(), CollapsedNum, NumClauses),
881         HasCancel(false) {}
882 
883   /// \brief Set cancel state.
setHasCancel(bool Has)884   void setHasCancel(bool Has) { HasCancel = Has; }
885 
886 public:
887   /// \brief Creates directive with a list of \a Clauses.
888   ///
889   /// \param C AST context.
890   /// \param StartLoc Starting location of the directive kind.
891   /// \param EndLoc Ending Location of the directive.
892   /// \param CollapsedNum Number of collapsed loops.
893   /// \param Clauses List of clauses.
894   /// \param AssociatedStmt Statement, associated with the directive.
895   /// \param Exprs Helper expressions for CodeGen.
896   /// \param HasCancel true if current directive has inner cancel directive.
897   ///
898   static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
899                                  SourceLocation EndLoc, unsigned CollapsedNum,
900                                  ArrayRef<OMPClause *> Clauses,
901                                  Stmt *AssociatedStmt, const HelperExprs &Exprs,
902                                  bool HasCancel);
903 
904   /// \brief Creates an empty directive with the place
905   /// for \a NumClauses clauses.
906   ///
907   /// \param C AST context.
908   /// \param CollapsedNum Number of collapsed nested loops.
909   /// \param NumClauses Number of clauses.
910   ///
911   static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
912                                       unsigned CollapsedNum, EmptyShell);
913 
914   /// \brief Return true if current directive has inner cancel directive.
hasCancel()915   bool hasCancel() const { return HasCancel; }
916 
classof(const Stmt * T)917   static bool classof(const Stmt *T) {
918     return T->getStmtClass() == OMPForDirectiveClass;
919   }
920 };
921 
922 /// \brief This represents '#pragma omp for simd' directive.
923 ///
924 /// \code
925 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
926 /// \endcode
927 /// In this example directive '#pragma omp for simd' has clauses 'private'
928 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
929 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
930 ///
931 class OMPForSimdDirective : public OMPLoopDirective {
932   friend class ASTStmtReader;
933   /// \brief Build directive with the given start and end location.
934   ///
935   /// \param StartLoc Starting location of the directive kind.
936   /// \param EndLoc Ending location of the directive.
937   /// \param CollapsedNum Number of collapsed nested loops.
938   /// \param NumClauses Number of clauses.
939   ///
OMPForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)940   OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
941                       unsigned CollapsedNum, unsigned NumClauses)
942       : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
943                          StartLoc, EndLoc, CollapsedNum, NumClauses) {}
944 
945   /// \brief Build an empty directive.
946   ///
947   /// \param CollapsedNum Number of collapsed nested loops.
948   /// \param NumClauses Number of clauses.
949   ///
OMPForSimdDirective(unsigned CollapsedNum,unsigned NumClauses)950   explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
951       : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
952                          SourceLocation(), SourceLocation(), CollapsedNum,
953                          NumClauses) {}
954 
955 public:
956   /// \brief Creates directive with a list of \a Clauses.
957   ///
958   /// \param C AST context.
959   /// \param StartLoc Starting location of the directive kind.
960   /// \param EndLoc Ending Location of the directive.
961   /// \param CollapsedNum Number of collapsed loops.
962   /// \param Clauses List of clauses.
963   /// \param AssociatedStmt Statement, associated with the directive.
964   /// \param Exprs Helper expressions for CodeGen.
965   ///
966   static OMPForSimdDirective *
967   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
968          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
969          Stmt *AssociatedStmt, const HelperExprs &Exprs);
970 
971   /// \brief Creates an empty directive with the place
972   /// for \a NumClauses clauses.
973   ///
974   /// \param C AST context.
975   /// \param CollapsedNum Number of collapsed nested loops.
976   /// \param NumClauses Number of clauses.
977   ///
978   static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
979                                           unsigned NumClauses,
980                                           unsigned CollapsedNum, EmptyShell);
981 
classof(const Stmt * T)982   static bool classof(const Stmt *T) {
983     return T->getStmtClass() == OMPForSimdDirectiveClass;
984   }
985 };
986 
987 /// \brief This represents '#pragma omp sections' directive.
988 ///
989 /// \code
990 /// #pragma omp sections private(a,b) reduction(+:c,d)
991 /// \endcode
992 /// In this example directive '#pragma omp sections' has clauses 'private' with
993 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
994 /// 'c' and 'd'.
995 ///
996 class OMPSectionsDirective : public OMPExecutableDirective {
997   friend class ASTStmtReader;
998 
999   /// \brief true if current directive has inner cancel directive.
1000   bool HasCancel;
1001 
1002   /// \brief Build directive with the given start and end location.
1003   ///
1004   /// \param StartLoc Starting location of the directive kind.
1005   /// \param EndLoc Ending location of the directive.
1006   /// \param NumClauses Number of clauses.
1007   ///
OMPSectionsDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1008   OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1009                        unsigned NumClauses)
1010       : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
1011                                StartLoc, EndLoc, NumClauses, 1),
1012         HasCancel(false) {}
1013 
1014   /// \brief Build an empty directive.
1015   ///
1016   /// \param NumClauses Number of clauses.
1017   ///
OMPSectionsDirective(unsigned NumClauses)1018   explicit OMPSectionsDirective(unsigned NumClauses)
1019       : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
1020                                SourceLocation(), SourceLocation(), NumClauses,
1021                                1),
1022         HasCancel(false) {}
1023 
1024   /// \brief Set cancel state.
setHasCancel(bool Has)1025   void setHasCancel(bool Has) { HasCancel = Has; }
1026 
1027 public:
1028   /// \brief Creates directive with a list of \a Clauses.
1029   ///
1030   /// \param C AST context.
1031   /// \param StartLoc Starting location of the directive kind.
1032   /// \param EndLoc Ending Location of the directive.
1033   /// \param Clauses List of clauses.
1034   /// \param AssociatedStmt Statement, associated with the directive.
1035   /// \param HasCancel true if current directive has inner directive.
1036   ///
1037   static OMPSectionsDirective *
1038   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1039          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
1040 
1041   /// \brief Creates an empty directive with the place for \a NumClauses
1042   /// clauses.
1043   ///
1044   /// \param C AST context.
1045   /// \param NumClauses Number of clauses.
1046   ///
1047   static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
1048                                            unsigned NumClauses, EmptyShell);
1049 
1050   /// \brief Return true if current directive has inner cancel directive.
hasCancel()1051   bool hasCancel() const { return HasCancel; }
1052 
classof(const Stmt * T)1053   static bool classof(const Stmt *T) {
1054     return T->getStmtClass() == OMPSectionsDirectiveClass;
1055   }
1056 };
1057 
1058 /// \brief This represents '#pragma omp section' directive.
1059 ///
1060 /// \code
1061 /// #pragma omp section
1062 /// \endcode
1063 ///
1064 class OMPSectionDirective : public OMPExecutableDirective {
1065   friend class ASTStmtReader;
1066 
1067   /// \brief true if current directive has inner cancel directive.
1068   bool HasCancel;
1069 
1070   /// \brief Build directive with the given start and end location.
1071   ///
1072   /// \param StartLoc Starting location of the directive kind.
1073   /// \param EndLoc Ending location of the directive.
1074   ///
OMPSectionDirective(SourceLocation StartLoc,SourceLocation EndLoc)1075   OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1076       : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
1077                                StartLoc, EndLoc, 0, 1),
1078         HasCancel(false) {}
1079 
1080   /// \brief Build an empty directive.
1081   ///
OMPSectionDirective()1082   explicit OMPSectionDirective()
1083       : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
1084                                SourceLocation(), SourceLocation(), 0, 1),
1085         HasCancel(false) {}
1086 
1087 public:
1088   /// \brief Creates directive.
1089   ///
1090   /// \param C AST context.
1091   /// \param StartLoc Starting location of the directive kind.
1092   /// \param EndLoc Ending Location of the directive.
1093   /// \param AssociatedStmt Statement, associated with the directive.
1094   /// \param HasCancel true if current directive has inner directive.
1095   ///
1096   static OMPSectionDirective *Create(const ASTContext &C,
1097                                      SourceLocation StartLoc,
1098                                      SourceLocation EndLoc,
1099                                      Stmt *AssociatedStmt, bool HasCancel);
1100 
1101   /// \brief Creates an empty directive.
1102   ///
1103   /// \param C AST context.
1104   ///
1105   static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1106 
1107   /// \brief Set cancel state.
setHasCancel(bool Has)1108   void setHasCancel(bool Has) { HasCancel = Has; }
1109 
1110   /// \brief Return true if current directive has inner cancel directive.
hasCancel()1111   bool hasCancel() const { return HasCancel; }
1112 
classof(const Stmt * T)1113   static bool classof(const Stmt *T) {
1114     return T->getStmtClass() == OMPSectionDirectiveClass;
1115   }
1116 };
1117 
1118 /// \brief This represents '#pragma omp single' directive.
1119 ///
1120 /// \code
1121 /// #pragma omp single private(a,b) copyprivate(c,d)
1122 /// \endcode
1123 /// In this example directive '#pragma omp single' has clauses 'private' with
1124 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
1125 ///
1126 class OMPSingleDirective : public OMPExecutableDirective {
1127   friend class ASTStmtReader;
1128   /// \brief Build directive with the given start and end location.
1129   ///
1130   /// \param StartLoc Starting location of the directive kind.
1131   /// \param EndLoc Ending location of the directive.
1132   /// \param NumClauses Number of clauses.
1133   ///
OMPSingleDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1134   OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1135                      unsigned NumClauses)
1136       : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
1137                                StartLoc, EndLoc, NumClauses, 1) {}
1138 
1139   /// \brief Build an empty directive.
1140   ///
1141   /// \param NumClauses Number of clauses.
1142   ///
OMPSingleDirective(unsigned NumClauses)1143   explicit OMPSingleDirective(unsigned NumClauses)
1144       : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
1145                                SourceLocation(), SourceLocation(), NumClauses,
1146                                1) {}
1147 
1148 public:
1149   /// \brief Creates directive with a list of \a Clauses.
1150   ///
1151   /// \param C AST context.
1152   /// \param StartLoc Starting location of the directive kind.
1153   /// \param EndLoc Ending Location of the directive.
1154   /// \param Clauses List of clauses.
1155   /// \param AssociatedStmt Statement, associated with the directive.
1156   ///
1157   static OMPSingleDirective *
1158   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1159          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1160 
1161   /// \brief Creates an empty directive with the place for \a NumClauses
1162   /// clauses.
1163   ///
1164   /// \param C AST context.
1165   /// \param NumClauses Number of clauses.
1166   ///
1167   static OMPSingleDirective *CreateEmpty(const ASTContext &C,
1168                                          unsigned NumClauses, EmptyShell);
1169 
classof(const Stmt * T)1170   static bool classof(const Stmt *T) {
1171     return T->getStmtClass() == OMPSingleDirectiveClass;
1172   }
1173 };
1174 
1175 /// \brief This represents '#pragma omp master' directive.
1176 ///
1177 /// \code
1178 /// #pragma omp master
1179 /// \endcode
1180 ///
1181 class OMPMasterDirective : public OMPExecutableDirective {
1182   friend class ASTStmtReader;
1183   /// \brief 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   ///
OMPMasterDirective(SourceLocation StartLoc,SourceLocation EndLoc)1188   OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1189       : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
1190                                StartLoc, EndLoc, 0, 1) {}
1191 
1192   /// \brief Build an empty directive.
1193   ///
OMPMasterDirective()1194   explicit OMPMasterDirective()
1195       : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
1196                                SourceLocation(), SourceLocation(), 0, 1) {}
1197 
1198 public:
1199   /// \brief Creates directive.
1200   ///
1201   /// \param C AST context.
1202   /// \param StartLoc Starting location of the directive kind.
1203   /// \param EndLoc Ending Location of the directive.
1204   /// \param AssociatedStmt Statement, associated with the directive.
1205   ///
1206   static OMPMasterDirective *Create(const ASTContext &C,
1207                                     SourceLocation StartLoc,
1208                                     SourceLocation EndLoc,
1209                                     Stmt *AssociatedStmt);
1210 
1211   /// \brief Creates an empty directive.
1212   ///
1213   /// \param C AST context.
1214   ///
1215   static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1216 
classof(const Stmt * T)1217   static bool classof(const Stmt *T) {
1218     return T->getStmtClass() == OMPMasterDirectiveClass;
1219   }
1220 };
1221 
1222 /// \brief This represents '#pragma omp critical' directive.
1223 ///
1224 /// \code
1225 /// #pragma omp critical
1226 /// \endcode
1227 ///
1228 class OMPCriticalDirective : public OMPExecutableDirective {
1229   friend class ASTStmtReader;
1230   /// \brief Name of the directive.
1231   DeclarationNameInfo DirName;
1232   /// \brief Build directive with the given start and end location.
1233   ///
1234   /// \param Name Name of the directive.
1235   /// \param StartLoc Starting location of the directive kind.
1236   /// \param EndLoc Ending location of the directive.
1237   /// \param NumClauses Number of clauses.
1238   ///
OMPCriticalDirective(const DeclarationNameInfo & Name,SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1239   OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
1240                        SourceLocation EndLoc, unsigned NumClauses)
1241       : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
1242                                StartLoc, EndLoc, NumClauses, 1),
1243         DirName(Name) {}
1244 
1245   /// \brief Build an empty directive.
1246   ///
1247   /// \param NumClauses Number of clauses.
1248   ///
OMPCriticalDirective(unsigned NumClauses)1249   explicit OMPCriticalDirective(unsigned NumClauses)
1250       : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
1251                                SourceLocation(), SourceLocation(), NumClauses,
1252                                1),
1253         DirName() {}
1254 
1255   /// \brief Set name of the directive.
1256   ///
1257   /// \param Name Name of the directive.
1258   ///
setDirectiveName(const DeclarationNameInfo & Name)1259   void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
1260 
1261 public:
1262   /// \brief Creates directive.
1263   ///
1264   /// \param C AST context.
1265   /// \param Name Name of the directive.
1266   /// \param StartLoc Starting location of the directive kind.
1267   /// \param EndLoc Ending Location of the directive.
1268   /// \param Clauses List of clauses.
1269   /// \param AssociatedStmt Statement, associated with the directive.
1270   ///
1271   static OMPCriticalDirective *
1272   Create(const ASTContext &C, const DeclarationNameInfo &Name,
1273          SourceLocation StartLoc, SourceLocation EndLoc,
1274          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1275 
1276   /// \brief Creates an empty directive.
1277   ///
1278   /// \param C AST context.
1279   /// \param NumClauses Number of clauses.
1280   ///
1281   static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
1282                                            unsigned NumClauses, EmptyShell);
1283 
1284   /// \brief Return name of the directive.
1285   ///
getDirectiveName()1286   DeclarationNameInfo getDirectiveName() const { return DirName; }
1287 
classof(const Stmt * T)1288   static bool classof(const Stmt *T) {
1289     return T->getStmtClass() == OMPCriticalDirectiveClass;
1290   }
1291 };
1292 
1293 /// \brief This represents '#pragma omp parallel for' directive.
1294 ///
1295 /// \code
1296 /// #pragma omp parallel for private(a,b) reduction(+:c,d)
1297 /// \endcode
1298 /// In this example directive '#pragma omp parallel for' has clauses 'private'
1299 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
1300 /// variables 'c' and 'd'.
1301 ///
1302 class OMPParallelForDirective : public OMPLoopDirective {
1303   friend class ASTStmtReader;
1304 
1305   /// \brief true if current region has inner cancel directive.
1306   bool HasCancel;
1307 
1308   /// \brief Build directive with the given start and end location.
1309   ///
1310   /// \param StartLoc Starting location of the directive kind.
1311   /// \param EndLoc Ending location of the directive.
1312   /// \param CollapsedNum Number of collapsed nested loops.
1313   /// \param NumClauses Number of clauses.
1314   ///
OMPParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)1315   OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1316                           unsigned CollapsedNum, unsigned NumClauses)
1317       : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
1318                          StartLoc, EndLoc, CollapsedNum, NumClauses),
1319         HasCancel(false) {}
1320 
1321   /// \brief Build an empty directive.
1322   ///
1323   /// \param CollapsedNum Number of collapsed nested loops.
1324   /// \param NumClauses Number of clauses.
1325   ///
OMPParallelForDirective(unsigned CollapsedNum,unsigned NumClauses)1326   explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
1327       : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
1328                          SourceLocation(), SourceLocation(), CollapsedNum,
1329                          NumClauses),
1330         HasCancel(false) {}
1331 
1332   /// \brief Set cancel state.
setHasCancel(bool Has)1333   void setHasCancel(bool Has) { HasCancel = Has; }
1334 
1335 public:
1336   /// \brief Creates directive with a list of \a Clauses.
1337   ///
1338   /// \param C AST context.
1339   /// \param StartLoc Starting location of the directive kind.
1340   /// \param EndLoc Ending Location of the directive.
1341   /// \param CollapsedNum Number of collapsed loops.
1342   /// \param Clauses List of clauses.
1343   /// \param AssociatedStmt Statement, associated with the directive.
1344   /// \param Exprs Helper expressions for CodeGen.
1345   /// \param HasCancel true if current directive has inner cancel directive.
1346   ///
1347   static OMPParallelForDirective *
1348   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1349          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1350          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
1351 
1352   /// \brief Creates an empty directive with the place
1353   /// for \a NumClauses clauses.
1354   ///
1355   /// \param C AST context.
1356   /// \param CollapsedNum Number of collapsed nested loops.
1357   /// \param NumClauses Number of clauses.
1358   ///
1359   static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
1360                                               unsigned NumClauses,
1361                                               unsigned CollapsedNum,
1362                                               EmptyShell);
1363 
1364   /// \brief Return true if current directive has inner cancel directive.
hasCancel()1365   bool hasCancel() const { return HasCancel; }
1366 
classof(const Stmt * T)1367   static bool classof(const Stmt *T) {
1368     return T->getStmtClass() == OMPParallelForDirectiveClass;
1369   }
1370 };
1371 
1372 /// \brief This represents '#pragma omp parallel for simd' directive.
1373 ///
1374 /// \code
1375 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
1376 /// \endcode
1377 /// In this example directive '#pragma omp parallel for simd' has clauses
1378 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
1379 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and
1380 /// 'd'.
1381 ///
1382 class OMPParallelForSimdDirective : public OMPLoopDirective {
1383   friend class ASTStmtReader;
1384   /// \brief Build directive with the given start and end location.
1385   ///
1386   /// \param StartLoc Starting location of the directive kind.
1387   /// \param EndLoc Ending location of the directive.
1388   /// \param CollapsedNum Number of collapsed nested loops.
1389   /// \param NumClauses Number of clauses.
1390   ///
OMPParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)1391   OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1392                               unsigned CollapsedNum, unsigned NumClauses)
1393       : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
1394                          OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum,
1395                          NumClauses) {}
1396 
1397   /// \brief Build an empty directive.
1398   ///
1399   /// \param CollapsedNum Number of collapsed nested loops.
1400   /// \param NumClauses Number of clauses.
1401   ///
OMPParallelForSimdDirective(unsigned CollapsedNum,unsigned NumClauses)1402   explicit OMPParallelForSimdDirective(unsigned CollapsedNum,
1403                                        unsigned NumClauses)
1404       : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
1405                          OMPD_parallel_for_simd, SourceLocation(),
1406                          SourceLocation(), CollapsedNum, NumClauses) {}
1407 
1408 public:
1409   /// \brief Creates directive with a list of \a Clauses.
1410   ///
1411   /// \param C AST context.
1412   /// \param StartLoc Starting location of the directive kind.
1413   /// \param EndLoc Ending Location of the directive.
1414   /// \param CollapsedNum Number of collapsed loops.
1415   /// \param Clauses List of clauses.
1416   /// \param AssociatedStmt Statement, associated with the directive.
1417   /// \param Exprs Helper expressions for CodeGen.
1418   ///
1419   static OMPParallelForSimdDirective *
1420   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1421          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1422          Stmt *AssociatedStmt, const HelperExprs &Exprs);
1423 
1424   /// \brief Creates an empty directive with the place
1425   /// for \a NumClauses clauses.
1426   ///
1427   /// \param C AST context.
1428   /// \param CollapsedNum Number of collapsed nested loops.
1429   /// \param NumClauses Number of clauses.
1430   ///
1431   static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
1432                                                   unsigned NumClauses,
1433                                                   unsigned CollapsedNum,
1434                                                   EmptyShell);
1435 
classof(const Stmt * T)1436   static bool classof(const Stmt *T) {
1437     return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
1438   }
1439 };
1440 
1441 /// \brief This represents '#pragma omp parallel sections' directive.
1442 ///
1443 /// \code
1444 /// #pragma omp parallel sections private(a,b) reduction(+:c,d)
1445 /// \endcode
1446 /// In this example directive '#pragma omp parallel sections' has clauses
1447 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
1448 /// and variables 'c' and 'd'.
1449 ///
1450 class OMPParallelSectionsDirective : public OMPExecutableDirective {
1451   friend class ASTStmtReader;
1452 
1453   /// \brief true if current directive has inner cancel directive.
1454   bool HasCancel;
1455 
1456   /// \brief Build directive with the given start and end location.
1457   ///
1458   /// \param StartLoc Starting location of the directive kind.
1459   /// \param EndLoc Ending location of the directive.
1460   /// \param NumClauses Number of clauses.
1461   ///
OMPParallelSectionsDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1462   OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1463                                unsigned NumClauses)
1464       : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
1465                                OMPD_parallel_sections, StartLoc, EndLoc,
1466                                NumClauses, 1),
1467         HasCancel(false) {}
1468 
1469   /// \brief Build an empty directive.
1470   ///
1471   /// \param NumClauses Number of clauses.
1472   ///
OMPParallelSectionsDirective(unsigned NumClauses)1473   explicit OMPParallelSectionsDirective(unsigned NumClauses)
1474       : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
1475                                OMPD_parallel_sections, SourceLocation(),
1476                                SourceLocation(), NumClauses, 1),
1477         HasCancel(false) {}
1478 
1479   /// \brief Set cancel state.
setHasCancel(bool Has)1480   void setHasCancel(bool Has) { HasCancel = Has; }
1481 
1482 public:
1483   /// \brief Creates directive with a list of \a Clauses.
1484   ///
1485   /// \param C AST context.
1486   /// \param StartLoc Starting location of the directive kind.
1487   /// \param EndLoc Ending Location of the directive.
1488   /// \param Clauses List of clauses.
1489   /// \param AssociatedStmt Statement, associated with the directive.
1490   /// \param HasCancel true if current directive has inner cancel directive.
1491   ///
1492   static OMPParallelSectionsDirective *
1493   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1494          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
1495 
1496   /// \brief Creates an empty directive with the place for \a NumClauses
1497   /// clauses.
1498   ///
1499   /// \param C AST context.
1500   /// \param NumClauses Number of clauses.
1501   ///
1502   static OMPParallelSectionsDirective *
1503   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
1504 
1505   /// \brief Return true if current directive has inner cancel directive.
hasCancel()1506   bool hasCancel() const { return HasCancel; }
1507 
classof(const Stmt * T)1508   static bool classof(const Stmt *T) {
1509     return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
1510   }
1511 };
1512 
1513 /// \brief This represents '#pragma omp task' directive.
1514 ///
1515 /// \code
1516 /// #pragma omp task private(a,b) final(d)
1517 /// \endcode
1518 /// In this example directive '#pragma omp task' has clauses 'private' with the
1519 /// variables 'a' and 'b' and 'final' with condition 'd'.
1520 ///
1521 class OMPTaskDirective : public OMPExecutableDirective {
1522   friend class ASTStmtReader;
1523   /// \brief true if this directive has inner cancel directive.
1524   bool HasCancel;
1525 
1526   /// \brief Build directive with the given start and end location.
1527   ///
1528   /// \param StartLoc Starting location of the directive kind.
1529   /// \param EndLoc Ending location of the directive.
1530   /// \param NumClauses Number of clauses.
1531   ///
OMPTaskDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1532   OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1533                    unsigned NumClauses)
1534       : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
1535                                EndLoc, NumClauses, 1),
1536         HasCancel(false) {}
1537 
1538   /// \brief Build an empty directive.
1539   ///
1540   /// \param NumClauses Number of clauses.
1541   ///
OMPTaskDirective(unsigned NumClauses)1542   explicit OMPTaskDirective(unsigned NumClauses)
1543       : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
1544                                SourceLocation(), SourceLocation(), NumClauses,
1545                                1),
1546         HasCancel(false) {}
1547 
1548   /// \brief Set cancel state.
setHasCancel(bool Has)1549   void setHasCancel(bool Has) { HasCancel = Has; }
1550 
1551 public:
1552   /// \brief Creates directive with a list of \a Clauses.
1553   ///
1554   /// \param C AST context.
1555   /// \param StartLoc Starting location of the directive kind.
1556   /// \param EndLoc Ending Location of the directive.
1557   /// \param Clauses List of clauses.
1558   /// \param AssociatedStmt Statement, associated with the directive.
1559   /// \param HasCancel true, if current directive has inner cancel directive.
1560   ///
1561   static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1562                                   SourceLocation EndLoc,
1563                                   ArrayRef<OMPClause *> Clauses,
1564                                   Stmt *AssociatedStmt, bool HasCancel);
1565 
1566   /// \brief Creates an empty directive with the place for \a NumClauses
1567   /// clauses.
1568   ///
1569   /// \param C AST context.
1570   /// \param NumClauses Number of clauses.
1571   ///
1572   static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1573                                        EmptyShell);
1574 
1575   /// \brief Return true if current directive has inner cancel directive.
hasCancel()1576   bool hasCancel() const { return HasCancel; }
1577 
classof(const Stmt * T)1578   static bool classof(const Stmt *T) {
1579     return T->getStmtClass() == OMPTaskDirectiveClass;
1580   }
1581 };
1582 
1583 /// \brief This represents '#pragma omp taskyield' directive.
1584 ///
1585 /// \code
1586 /// #pragma omp taskyield
1587 /// \endcode
1588 ///
1589 class OMPTaskyieldDirective : public OMPExecutableDirective {
1590   friend class ASTStmtReader;
1591   /// \brief Build directive with the given start and end location.
1592   ///
1593   /// \param StartLoc Starting location of the directive kind.
1594   /// \param EndLoc Ending location of the directive.
1595   ///
OMPTaskyieldDirective(SourceLocation StartLoc,SourceLocation EndLoc)1596   OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1597       : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
1598                                StartLoc, EndLoc, 0, 0) {}
1599 
1600   /// \brief Build an empty directive.
1601   ///
OMPTaskyieldDirective()1602   explicit OMPTaskyieldDirective()
1603       : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
1604                                SourceLocation(), SourceLocation(), 0, 0) {}
1605 
1606 public:
1607   /// \brief Creates directive.
1608   ///
1609   /// \param C AST context.
1610   /// \param StartLoc Starting location of the directive kind.
1611   /// \param EndLoc Ending Location of the directive.
1612   ///
1613   static OMPTaskyieldDirective *
1614   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1615 
1616   /// \brief Creates an empty directive.
1617   ///
1618   /// \param C AST context.
1619   ///
1620   static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1621 
classof(const Stmt * T)1622   static bool classof(const Stmt *T) {
1623     return T->getStmtClass() == OMPTaskyieldDirectiveClass;
1624   }
1625 };
1626 
1627 /// \brief This represents '#pragma omp barrier' directive.
1628 ///
1629 /// \code
1630 /// #pragma omp barrier
1631 /// \endcode
1632 ///
1633 class OMPBarrierDirective : public OMPExecutableDirective {
1634   friend class ASTStmtReader;
1635   /// \brief Build directive with the given start and end location.
1636   ///
1637   /// \param StartLoc Starting location of the directive kind.
1638   /// \param EndLoc Ending location of the directive.
1639   ///
OMPBarrierDirective(SourceLocation StartLoc,SourceLocation EndLoc)1640   OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1641       : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
1642                                StartLoc, EndLoc, 0, 0) {}
1643 
1644   /// \brief Build an empty directive.
1645   ///
OMPBarrierDirective()1646   explicit OMPBarrierDirective()
1647       : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
1648                                SourceLocation(), SourceLocation(), 0, 0) {}
1649 
1650 public:
1651   /// \brief Creates directive.
1652   ///
1653   /// \param C AST context.
1654   /// \param StartLoc Starting location of the directive kind.
1655   /// \param EndLoc Ending Location of the directive.
1656   ///
1657   static OMPBarrierDirective *
1658   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1659 
1660   /// \brief Creates an empty directive.
1661   ///
1662   /// \param C AST context.
1663   ///
1664   static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1665 
classof(const Stmt * T)1666   static bool classof(const Stmt *T) {
1667     return T->getStmtClass() == OMPBarrierDirectiveClass;
1668   }
1669 };
1670 
1671 /// \brief This represents '#pragma omp taskwait' directive.
1672 ///
1673 /// \code
1674 /// #pragma omp taskwait
1675 /// \endcode
1676 ///
1677 class OMPTaskwaitDirective : public OMPExecutableDirective {
1678   friend class ASTStmtReader;
1679   /// \brief Build directive with the given start and end location.
1680   ///
1681   /// \param StartLoc Starting location of the directive kind.
1682   /// \param EndLoc Ending location of the directive.
1683   ///
OMPTaskwaitDirective(SourceLocation StartLoc,SourceLocation EndLoc)1684   OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1685       : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
1686                                StartLoc, EndLoc, 0, 0) {}
1687 
1688   /// \brief Build an empty directive.
1689   ///
OMPTaskwaitDirective()1690   explicit OMPTaskwaitDirective()
1691       : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
1692                                SourceLocation(), SourceLocation(), 0, 0) {}
1693 
1694 public:
1695   /// \brief Creates directive.
1696   ///
1697   /// \param C AST context.
1698   /// \param StartLoc Starting location of the directive kind.
1699   /// \param EndLoc Ending Location of the directive.
1700   ///
1701   static OMPTaskwaitDirective *
1702   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1703 
1704   /// \brief Creates an empty directive.
1705   ///
1706   /// \param C AST context.
1707   ///
1708   static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1709 
classof(const Stmt * T)1710   static bool classof(const Stmt *T) {
1711     return T->getStmtClass() == OMPTaskwaitDirectiveClass;
1712   }
1713 };
1714 
1715 /// \brief This represents '#pragma omp taskgroup' directive.
1716 ///
1717 /// \code
1718 /// #pragma omp taskgroup
1719 /// \endcode
1720 ///
1721 class OMPTaskgroupDirective : public OMPExecutableDirective {
1722   friend class ASTStmtReader;
1723   /// \brief Build directive with the given start and end location.
1724   ///
1725   /// \param StartLoc Starting location of the directive kind.
1726   /// \param EndLoc Ending location of the directive.
1727   ///
OMPTaskgroupDirective(SourceLocation StartLoc,SourceLocation EndLoc)1728   OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1729       : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
1730                                StartLoc, EndLoc, 0, 1) {}
1731 
1732   /// \brief Build an empty directive.
1733   ///
OMPTaskgroupDirective()1734   explicit OMPTaskgroupDirective()
1735       : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
1736                                SourceLocation(), SourceLocation(), 0, 1) {}
1737 
1738 public:
1739   /// \brief Creates directive.
1740   ///
1741   /// \param C AST context.
1742   /// \param StartLoc Starting location of the directive kind.
1743   /// \param EndLoc Ending Location of the directive.
1744   /// \param AssociatedStmt Statement, associated with the directive.
1745   ///
1746   static OMPTaskgroupDirective *Create(const ASTContext &C,
1747                                        SourceLocation StartLoc,
1748                                        SourceLocation EndLoc,
1749                                        Stmt *AssociatedStmt);
1750 
1751   /// \brief Creates an empty directive.
1752   ///
1753   /// \param C AST context.
1754   ///
1755   static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1756 
classof(const Stmt * T)1757   static bool classof(const Stmt *T) {
1758     return T->getStmtClass() == OMPTaskgroupDirectiveClass;
1759   }
1760 };
1761 
1762 /// \brief This represents '#pragma omp flush' directive.
1763 ///
1764 /// \code
1765 /// #pragma omp flush(a,b)
1766 /// \endcode
1767 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
1768 /// and 'b'.
1769 /// 'omp flush' directive does not have clauses but have an optional list of
1770 /// variables to flush. This list of variables is stored within some fake clause
1771 /// FlushClause.
1772 class OMPFlushDirective : public OMPExecutableDirective {
1773   friend class ASTStmtReader;
1774   /// \brief Build directive with the given start and end location.
1775   ///
1776   /// \param StartLoc Starting location of the directive kind.
1777   /// \param EndLoc Ending location of the directive.
1778   /// \param NumClauses Number of clauses.
1779   ///
OMPFlushDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1780   OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1781                     unsigned NumClauses)
1782       : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
1783                                StartLoc, EndLoc, NumClauses, 0) {}
1784 
1785   /// \brief Build an empty directive.
1786   ///
1787   /// \param NumClauses Number of clauses.
1788   ///
OMPFlushDirective(unsigned NumClauses)1789   explicit OMPFlushDirective(unsigned NumClauses)
1790       : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
1791                                SourceLocation(), SourceLocation(), NumClauses,
1792                                0) {}
1793 
1794 public:
1795   /// \brief Creates directive with a list of \a Clauses.
1796   ///
1797   /// \param C AST context.
1798   /// \param StartLoc Starting location of the directive kind.
1799   /// \param EndLoc Ending Location of the directive.
1800   /// \param Clauses List of clauses (only single OMPFlushClause clause is
1801   /// allowed).
1802   ///
1803   static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1804                                    SourceLocation EndLoc,
1805                                    ArrayRef<OMPClause *> Clauses);
1806 
1807   /// \brief Creates an empty directive with the place for \a NumClauses
1808   /// clauses.
1809   ///
1810   /// \param C AST context.
1811   /// \param NumClauses Number of clauses.
1812   ///
1813   static OMPFlushDirective *CreateEmpty(const ASTContext &C,
1814                                         unsigned NumClauses, EmptyShell);
1815 
classof(const Stmt * T)1816   static bool classof(const Stmt *T) {
1817     return T->getStmtClass() == OMPFlushDirectiveClass;
1818   }
1819 };
1820 
1821 /// \brief This represents '#pragma omp ordered' directive.
1822 ///
1823 /// \code
1824 /// #pragma omp ordered
1825 /// \endcode
1826 ///
1827 class OMPOrderedDirective : public OMPExecutableDirective {
1828   friend class ASTStmtReader;
1829   /// \brief Build directive with the given start and end location.
1830   ///
1831   /// \param StartLoc Starting location of the directive kind.
1832   /// \param EndLoc Ending location of the directive.
1833   /// \param NumClauses Number of clauses.
1834   ///
OMPOrderedDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1835   OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1836                       unsigned NumClauses)
1837       : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
1838                                StartLoc, EndLoc, NumClauses, 1) {}
1839 
1840   /// \brief Build an empty directive.
1841   ///
1842   /// \param NumClauses Number of clauses.
1843   ///
OMPOrderedDirective(unsigned NumClauses)1844   explicit OMPOrderedDirective(unsigned NumClauses)
1845       : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
1846                                SourceLocation(), SourceLocation(), NumClauses,
1847                                1) {}
1848 
1849 public:
1850   /// \brief Creates directive.
1851   ///
1852   /// \param C AST context.
1853   /// \param StartLoc Starting location of the directive kind.
1854   /// \param EndLoc Ending Location of the directive.
1855   /// \param Clauses List of clauses.
1856   /// \param AssociatedStmt Statement, associated with the directive.
1857   ///
1858   static OMPOrderedDirective *
1859   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1860          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1861 
1862   /// \brief Creates an empty directive.
1863   ///
1864   /// \param C AST context.
1865   /// \param NumClauses Number of clauses.
1866   ///
1867   static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
1868                                           unsigned NumClauses, EmptyShell);
1869 
classof(const Stmt * T)1870   static bool classof(const Stmt *T) {
1871     return T->getStmtClass() == OMPOrderedDirectiveClass;
1872   }
1873 };
1874 
1875 /// \brief This represents '#pragma omp atomic' directive.
1876 ///
1877 /// \code
1878 /// #pragma omp atomic capture
1879 /// \endcode
1880 /// In this example directive '#pragma omp atomic' has clause 'capture'.
1881 ///
1882 class OMPAtomicDirective : public OMPExecutableDirective {
1883   friend class ASTStmtReader;
1884   /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
1885   /// have atomic expressions of forms
1886   /// \code
1887   /// x = x binop expr;
1888   /// x = expr binop x;
1889   /// \endcode
1890   /// This field is true for the first form of the expression and false for the
1891   /// second. Required for correct codegen of non-associative operations (like
1892   /// << or >>).
1893   bool IsXLHSInRHSPart;
1894   /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
1895   /// have atomic expressions of forms
1896   /// \code
1897   /// v = x; <update x>;
1898   /// <update x>; v = x;
1899   /// \endcode
1900   /// This field is true for the first(postfix) form of the expression and false
1901   /// otherwise.
1902   bool IsPostfixUpdate;
1903 
1904   /// \brief Build directive with the given start and end location.
1905   ///
1906   /// \param StartLoc Starting location of the directive kind.
1907   /// \param EndLoc Ending location of the directive.
1908   /// \param NumClauses Number of clauses.
1909   ///
OMPAtomicDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1910   OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1911                      unsigned NumClauses)
1912       : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
1913                                StartLoc, EndLoc, NumClauses, 5),
1914         IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
1915 
1916   /// \brief Build an empty directive.
1917   ///
1918   /// \param NumClauses Number of clauses.
1919   ///
OMPAtomicDirective(unsigned NumClauses)1920   explicit OMPAtomicDirective(unsigned NumClauses)
1921       : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
1922                                SourceLocation(), SourceLocation(), NumClauses,
1923                                5),
1924         IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
1925 
1926   /// \brief Set 'x' part of the associated expression/statement.
setX(Expr * X)1927   void setX(Expr *X) { *std::next(child_begin()) = X; }
1928   /// \brief Set helper expression of the form
1929   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1930   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
setUpdateExpr(Expr * UE)1931   void setUpdateExpr(Expr *UE) { *std::next(child_begin(), 2) = UE; }
1932   /// \brief Set 'v' part of the associated expression/statement.
setV(Expr * V)1933   void setV(Expr *V) { *std::next(child_begin(), 3) = V; }
1934   /// \brief Set 'expr' part of the associated expression/statement.
setExpr(Expr * E)1935   void setExpr(Expr *E) { *std::next(child_begin(), 4) = E; }
1936 
1937 public:
1938   /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
1939   /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
1940   /// detailed description of 'x', 'v' and 'expr').
1941   ///
1942   /// \param C AST context.
1943   /// \param StartLoc Starting location of the directive kind.
1944   /// \param EndLoc Ending Location of the directive.
1945   /// \param Clauses List of clauses.
1946   /// \param AssociatedStmt Statement, associated with the directive.
1947   /// \param X 'x' part of the associated expression/statement.
1948   /// \param V 'v' part of the associated expression/statement.
1949   /// \param E 'expr' part of the associated expression/statement.
1950   /// \param UE Helper expression of the form
1951   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1952   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1953   /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the
1954   /// second.
1955   /// \param IsPostfixUpdate true if original value of 'x' must be stored in
1956   /// 'v', not an updated one.
1957   static OMPAtomicDirective *
1958   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1959          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
1960          Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate);
1961 
1962   /// \brief Creates an empty directive with the place for \a NumClauses
1963   /// clauses.
1964   ///
1965   /// \param C AST context.
1966   /// \param NumClauses Number of clauses.
1967   ///
1968   static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
1969                                          unsigned NumClauses, EmptyShell);
1970 
1971   /// \brief Get 'x' part of the associated expression/statement.
getX()1972   Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); }
getX()1973   const Expr *getX() const {
1974     return cast_or_null<Expr>(*std::next(child_begin()));
1975   }
1976   /// \brief Get helper expression of the form
1977   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1978   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
getUpdateExpr()1979   Expr *getUpdateExpr() {
1980     return cast_or_null<Expr>(*std::next(child_begin(), 2));
1981   }
getUpdateExpr()1982   const Expr *getUpdateExpr() const {
1983     return cast_or_null<Expr>(*std::next(child_begin(), 2));
1984   }
1985   /// \brief Return true if helper update expression has form
1986   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
1987   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
isXLHSInRHSPart()1988   bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
1989   /// \brief Return true if 'v' expression must be updated to original value of
1990   /// 'x', false if 'v' must be updated to the new value of 'x'.
isPostfixUpdate()1991   bool isPostfixUpdate() const { return IsPostfixUpdate; }
1992   /// \brief Get 'v' part of the associated expression/statement.
getV()1993   Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); }
getV()1994   const Expr *getV() const {
1995     return cast_or_null<Expr>(*std::next(child_begin(), 3));
1996   }
1997   /// \brief Get 'expr' part of the associated expression/statement.
getExpr()1998   Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 4)); }
getExpr()1999   const Expr *getExpr() const {
2000     return cast_or_null<Expr>(*std::next(child_begin(), 4));
2001   }
2002 
classof(const Stmt * T)2003   static bool classof(const Stmt *T) {
2004     return T->getStmtClass() == OMPAtomicDirectiveClass;
2005   }
2006 };
2007 
2008 /// \brief This represents '#pragma omp target' directive.
2009 ///
2010 /// \code
2011 /// #pragma omp target if(a)
2012 /// \endcode
2013 /// In this example directive '#pragma omp target' has clause 'if' with
2014 /// condition 'a'.
2015 ///
2016 class OMPTargetDirective : public OMPExecutableDirective {
2017   friend class ASTStmtReader;
2018   /// \brief Build directive with the given start and end location.
2019   ///
2020   /// \param StartLoc Starting location of the directive kind.
2021   /// \param EndLoc Ending location of the directive.
2022   /// \param NumClauses Number of clauses.
2023   ///
OMPTargetDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)2024   OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2025                      unsigned NumClauses)
2026       : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
2027                                StartLoc, EndLoc, NumClauses, 1) {}
2028 
2029   /// \brief Build an empty directive.
2030   ///
2031   /// \param NumClauses Number of clauses.
2032   ///
OMPTargetDirective(unsigned NumClauses)2033   explicit OMPTargetDirective(unsigned NumClauses)
2034       : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
2035                                SourceLocation(), SourceLocation(), NumClauses,
2036                                1) {}
2037 
2038 public:
2039   /// \brief Creates directive with a list of \a Clauses.
2040   ///
2041   /// \param C AST context.
2042   /// \param StartLoc Starting location of the directive kind.
2043   /// \param EndLoc Ending Location of the directive.
2044   /// \param Clauses List of clauses.
2045   /// \param AssociatedStmt Statement, associated with the directive.
2046   ///
2047   static OMPTargetDirective *
2048   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2049          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2050 
2051   /// \brief Creates an empty directive with the place for \a NumClauses
2052   /// clauses.
2053   ///
2054   /// \param C AST context.
2055   /// \param NumClauses Number of clauses.
2056   ///
2057   static OMPTargetDirective *CreateEmpty(const ASTContext &C,
2058                                          unsigned NumClauses, EmptyShell);
2059 
classof(const Stmt * T)2060   static bool classof(const Stmt *T) {
2061     return T->getStmtClass() == OMPTargetDirectiveClass;
2062   }
2063 };
2064 
2065 /// \brief This represents '#pragma omp target data' directive.
2066 ///
2067 /// \code
2068 /// #pragma omp target data device(0) if(a) map(b[:])
2069 /// \endcode
2070 /// In this example directive '#pragma omp target data' has clauses 'device'
2071 /// with the value '0', 'if' with condition 'a' and 'map' with array
2072 /// section 'b[:]'.
2073 ///
2074 class OMPTargetDataDirective : public OMPExecutableDirective {
2075   friend class ASTStmtReader;
2076   /// \brief Build directive with the given start and end location.
2077   ///
2078   /// \param StartLoc Starting location of the directive kind.
2079   /// \param EndLoc Ending Location of the directive.
2080   /// \param NumClauses The number of clauses.
2081   ///
OMPTargetDataDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)2082   OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2083                          unsigned NumClauses)
2084       : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
2085                                OMPD_target_data, StartLoc, EndLoc, NumClauses,
2086                                1) {}
2087 
2088   /// \brief Build an empty directive.
2089   ///
2090   /// \param NumClauses Number of clauses.
2091   ///
OMPTargetDataDirective(unsigned NumClauses)2092   explicit OMPTargetDataDirective(unsigned NumClauses)
2093       : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
2094                                OMPD_target_data, SourceLocation(),
2095                                SourceLocation(), NumClauses, 1) {}
2096 
2097 public:
2098   /// \brief Creates directive with a list of \a Clauses.
2099   ///
2100   /// \param C AST context.
2101   /// \param StartLoc Starting location of the directive kind.
2102   /// \param EndLoc Ending Location of the directive.
2103   /// \param Clauses List of clauses.
2104   /// \param AssociatedStmt Statement, associated with the directive.
2105   ///
2106   static OMPTargetDataDirective *
2107   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2108          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2109 
2110   /// \brief Creates an empty directive with the place for \a N clauses.
2111   ///
2112   /// \param C AST context.
2113   /// \param N The number of clauses.
2114   ///
2115   static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
2116                                              EmptyShell);
2117 
classof(const Stmt * T)2118   static bool classof(const Stmt *T) {
2119     return T->getStmtClass() == OMPTargetDataDirectiveClass;
2120   }
2121 };
2122 
2123 /// \brief This represents '#pragma omp target enter data' directive.
2124 ///
2125 /// \code
2126 /// #pragma omp target enter data device(0) if(a) map(b[:])
2127 /// \endcode
2128 /// In this example directive '#pragma omp target enter data' has clauses
2129 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
2130 /// section 'b[:]'.
2131 ///
2132 class OMPTargetEnterDataDirective : public OMPExecutableDirective {
2133   friend class ASTStmtReader;
2134   /// \brief Build directive with the given start and end location.
2135   ///
2136   /// \param StartLoc Starting location of the directive kind.
2137   /// \param EndLoc Ending Location of the directive.
2138   /// \param NumClauses The number of clauses.
2139   ///
OMPTargetEnterDataDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)2140   OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2141                               unsigned NumClauses)
2142       : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
2143                                OMPD_target_enter_data, StartLoc, EndLoc,
2144                                NumClauses, /*NumChildren=*/0) {}
2145 
2146   /// \brief Build an empty directive.
2147   ///
2148   /// \param NumClauses Number of clauses.
2149   ///
OMPTargetEnterDataDirective(unsigned NumClauses)2150   explicit OMPTargetEnterDataDirective(unsigned NumClauses)
2151       : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
2152                                OMPD_target_enter_data, SourceLocation(),
2153                                SourceLocation(), NumClauses,
2154                                /*NumChildren=*/0) {}
2155 
2156 public:
2157   /// \brief Creates directive with a list of \a Clauses.
2158   ///
2159   /// \param C AST context.
2160   /// \param StartLoc Starting location of the directive kind.
2161   /// \param EndLoc Ending Location of the directive.
2162   /// \param Clauses List of clauses.
2163   ///
2164   static OMPTargetEnterDataDirective *Create(const ASTContext &C,
2165                                              SourceLocation StartLoc,
2166                                              SourceLocation EndLoc,
2167                                              ArrayRef<OMPClause *> Clauses);
2168 
2169   /// \brief Creates an empty directive with the place for \a N clauses.
2170   ///
2171   /// \param C AST context.
2172   /// \param N The number of clauses.
2173   ///
2174   static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C,
2175                                                   unsigned N, EmptyShell);
2176 
classof(const Stmt * T)2177   static bool classof(const Stmt *T) {
2178     return T->getStmtClass() == OMPTargetEnterDataDirectiveClass;
2179   }
2180 };
2181 
2182 /// \brief This represents '#pragma omp target exit data' directive.
2183 ///
2184 /// \code
2185 /// #pragma omp target exit data device(0) if(a) map(b[:])
2186 /// \endcode
2187 /// In this example directive '#pragma omp target exit data' has clauses
2188 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
2189 /// section 'b[:]'.
2190 ///
2191 class OMPTargetExitDataDirective : public OMPExecutableDirective {
2192   friend class ASTStmtReader;
2193   /// \brief Build directive with the given start and end location.
2194   ///
2195   /// \param StartLoc Starting location of the directive kind.
2196   /// \param EndLoc Ending Location of the directive.
2197   /// \param NumClauses The number of clauses.
2198   ///
OMPTargetExitDataDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)2199   OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2200                              unsigned NumClauses)
2201       : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
2202                                OMPD_target_exit_data, StartLoc, EndLoc,
2203                                NumClauses, /*NumChildren=*/0) {}
2204 
2205   /// \brief Build an empty directive.
2206   ///
2207   /// \param NumClauses Number of clauses.
2208   ///
OMPTargetExitDataDirective(unsigned NumClauses)2209   explicit OMPTargetExitDataDirective(unsigned NumClauses)
2210       : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
2211                                OMPD_target_exit_data, SourceLocation(),
2212                                SourceLocation(), NumClauses,
2213                                /*NumChildren=*/0) {}
2214 
2215 public:
2216   /// \brief Creates directive with a list of \a Clauses.
2217   ///
2218   /// \param C AST context.
2219   /// \param StartLoc Starting location of the directive kind.
2220   /// \param EndLoc Ending Location of the directive.
2221   /// \param Clauses List of clauses.
2222   ///
2223   static OMPTargetExitDataDirective *Create(const ASTContext &C,
2224                                             SourceLocation StartLoc,
2225                                             SourceLocation EndLoc,
2226                                             ArrayRef<OMPClause *> Clauses);
2227 
2228   /// \brief Creates an empty directive with the place for \a N clauses.
2229   ///
2230   /// \param C AST context.
2231   /// \param N The number of clauses.
2232   ///
2233   static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
2234                                                  unsigned N, EmptyShell);
2235 
classof(const Stmt * T)2236   static bool classof(const Stmt *T) {
2237     return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
2238   }
2239 };
2240 
2241 /// \brief This represents '#pragma omp target parallel' directive.
2242 ///
2243 /// \code
2244 /// #pragma omp target parallel if(a)
2245 /// \endcode
2246 /// In this example directive '#pragma omp target parallel' has clause 'if' with
2247 /// condition 'a'.
2248 ///
2249 class OMPTargetParallelDirective : public OMPExecutableDirective {
2250   friend class ASTStmtReader;
2251   /// \brief Build directive with the given start and end location.
2252   ///
2253   /// \param StartLoc Starting location of the directive kind.
2254   /// \param EndLoc Ending location of the directive.
2255   /// \param NumClauses Number of clauses.
2256   ///
OMPTargetParallelDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)2257   OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2258                              unsigned NumClauses)
2259       : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass,
2260                                OMPD_target_parallel, StartLoc, EndLoc,
2261                                NumClauses, /*NumChildren=*/1) {}
2262 
2263   /// \brief Build an empty directive.
2264   ///
2265   /// \param NumClauses Number of clauses.
2266   ///
OMPTargetParallelDirective(unsigned NumClauses)2267   explicit OMPTargetParallelDirective(unsigned NumClauses)
2268       : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass,
2269                                OMPD_target_parallel, SourceLocation(),
2270                                SourceLocation(), NumClauses,
2271                                /*NumChildren=*/1) {}
2272 
2273 public:
2274   /// \brief Creates directive with a list of \a Clauses.
2275   ///
2276   /// \param C AST context.
2277   /// \param StartLoc Starting location of the directive kind.
2278   /// \param EndLoc Ending Location of the directive.
2279   /// \param Clauses List of clauses.
2280   /// \param AssociatedStmt Statement, associated with the directive.
2281   ///
2282   static OMPTargetParallelDirective *
2283   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2284          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2285 
2286   /// \brief Creates an empty directive with the place for \a NumClauses
2287   /// clauses.
2288   ///
2289   /// \param C AST context.
2290   /// \param NumClauses Number of clauses.
2291   ///
2292   static OMPTargetParallelDirective *
2293   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
2294 
classof(const Stmt * T)2295   static bool classof(const Stmt *T) {
2296     return T->getStmtClass() == OMPTargetParallelDirectiveClass;
2297   }
2298 };
2299 
2300 /// \brief This represents '#pragma omp target parallel for' directive.
2301 ///
2302 /// \code
2303 /// #pragma omp target parallel for private(a,b) reduction(+:c,d)
2304 /// \endcode
2305 /// In this example directive '#pragma omp target parallel for' has clauses
2306 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
2307 /// and variables 'c' and 'd'.
2308 ///
2309 class OMPTargetParallelForDirective : public OMPLoopDirective {
2310   friend class ASTStmtReader;
2311 
2312   /// \brief true if current region has inner cancel directive.
2313   bool HasCancel;
2314 
2315   /// \brief Build directive with the given start and end location.
2316   ///
2317   /// \param StartLoc Starting location of the directive kind.
2318   /// \param EndLoc Ending location of the directive.
2319   /// \param CollapsedNum Number of collapsed nested loops.
2320   /// \param NumClauses Number of clauses.
2321   ///
OMPTargetParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)2322   OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2323                                 unsigned CollapsedNum, unsigned NumClauses)
2324       : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass,
2325                          OMPD_target_parallel_for, StartLoc, EndLoc,
2326                          CollapsedNum, NumClauses),
2327         HasCancel(false) {}
2328 
2329   /// \brief Build an empty directive.
2330   ///
2331   /// \param CollapsedNum Number of collapsed nested loops.
2332   /// \param NumClauses Number of clauses.
2333   ///
OMPTargetParallelForDirective(unsigned CollapsedNum,unsigned NumClauses)2334   explicit OMPTargetParallelForDirective(unsigned CollapsedNum,
2335                                          unsigned NumClauses)
2336       : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass,
2337                          OMPD_target_parallel_for, SourceLocation(),
2338                          SourceLocation(), CollapsedNum, NumClauses),
2339         HasCancel(false) {}
2340 
2341   /// \brief Set cancel state.
setHasCancel(bool Has)2342   void setHasCancel(bool Has) { HasCancel = Has; }
2343 
2344 public:
2345   /// \brief Creates directive with a list of \a Clauses.
2346   ///
2347   /// \param C AST context.
2348   /// \param StartLoc Starting location of the directive kind.
2349   /// \param EndLoc Ending Location of the directive.
2350   /// \param CollapsedNum Number of collapsed loops.
2351   /// \param Clauses List of clauses.
2352   /// \param AssociatedStmt Statement, associated with the directive.
2353   /// \param Exprs Helper expressions for CodeGen.
2354   /// \param HasCancel true if current directive has inner cancel directive.
2355   ///
2356   static OMPTargetParallelForDirective *
2357   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2358          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2359          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
2360 
2361   /// \brief Creates an empty directive with the place
2362   /// for \a NumClauses clauses.
2363   ///
2364   /// \param C AST context.
2365   /// \param CollapsedNum Number of collapsed nested loops.
2366   /// \param NumClauses Number of clauses.
2367   ///
2368   static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C,
2369                                                     unsigned NumClauses,
2370                                                     unsigned CollapsedNum,
2371                                                     EmptyShell);
2372 
2373   /// \brief Return true if current directive has inner cancel directive.
hasCancel()2374   bool hasCancel() const { return HasCancel; }
2375 
classof(const Stmt * T)2376   static bool classof(const Stmt *T) {
2377     return T->getStmtClass() == OMPTargetParallelForDirectiveClass;
2378   }
2379 };
2380 
2381 /// \brief This represents '#pragma omp teams' directive.
2382 ///
2383 /// \code
2384 /// #pragma omp teams if(a)
2385 /// \endcode
2386 /// In this example directive '#pragma omp teams' has clause 'if' with
2387 /// condition 'a'.
2388 ///
2389 class OMPTeamsDirective : public OMPExecutableDirective {
2390   friend class ASTStmtReader;
2391   /// \brief Build directive with the given start and end location.
2392   ///
2393   /// \param StartLoc Starting location of the directive kind.
2394   /// \param EndLoc Ending location of the directive.
2395   /// \param NumClauses Number of clauses.
2396   ///
OMPTeamsDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)2397   OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2398                     unsigned NumClauses)
2399       : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
2400                                StartLoc, EndLoc, NumClauses, 1) {}
2401 
2402   /// \brief Build an empty directive.
2403   ///
2404   /// \param NumClauses Number of clauses.
2405   ///
OMPTeamsDirective(unsigned NumClauses)2406   explicit OMPTeamsDirective(unsigned NumClauses)
2407       : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
2408                                SourceLocation(), SourceLocation(), NumClauses,
2409                                1) {}
2410 
2411 public:
2412   /// \brief Creates directive with a list of \a Clauses.
2413   ///
2414   /// \param C AST context.
2415   /// \param StartLoc Starting location of the directive kind.
2416   /// \param EndLoc Ending Location of the directive.
2417   /// \param Clauses List of clauses.
2418   /// \param AssociatedStmt Statement, associated with the directive.
2419   ///
2420   static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2421                                    SourceLocation EndLoc,
2422                                    ArrayRef<OMPClause *> Clauses,
2423                                    Stmt *AssociatedStmt);
2424 
2425   /// \brief Creates an empty directive with the place for \a NumClauses
2426   /// clauses.
2427   ///
2428   /// \param C AST context.
2429   /// \param NumClauses Number of clauses.
2430   ///
2431   static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
2432                                         unsigned NumClauses, EmptyShell);
2433 
classof(const Stmt * T)2434   static bool classof(const Stmt *T) {
2435     return T->getStmtClass() == OMPTeamsDirectiveClass;
2436   }
2437 };
2438 
2439 /// \brief This represents '#pragma omp cancellation point' directive.
2440 ///
2441 /// \code
2442 /// #pragma omp cancellation point for
2443 /// \endcode
2444 ///
2445 /// In this example a cancellation point is created for innermost 'for' region.
2446 class OMPCancellationPointDirective : public OMPExecutableDirective {
2447   friend class ASTStmtReader;
2448   OpenMPDirectiveKind CancelRegion;
2449   /// \brief Build directive with the given start and end location.
2450   ///
2451   /// \param StartLoc Starting location of the directive kind.
2452   /// \param EndLoc Ending location of the directive.
2453   ///
OMPCancellationPointDirective(SourceLocation StartLoc,SourceLocation EndLoc)2454   OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2455       : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
2456                                OMPD_cancellation_point, StartLoc, EndLoc, 0, 0),
2457         CancelRegion(OMPD_unknown) {}
2458 
2459   /// \brief Build an empty directive.
2460   ///
OMPCancellationPointDirective()2461   explicit OMPCancellationPointDirective()
2462       : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
2463                                OMPD_cancellation_point, SourceLocation(),
2464                                SourceLocation(), 0, 0),
2465         CancelRegion(OMPD_unknown) {}
2466 
2467   /// \brief Set cancel region for current cancellation point.
2468   /// \param CR Cancellation region.
setCancelRegion(OpenMPDirectiveKind CR)2469   void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
2470 
2471 public:
2472   /// \brief Creates directive.
2473   ///
2474   /// \param C AST context.
2475   /// \param StartLoc Starting location of the directive kind.
2476   /// \param EndLoc Ending Location of the directive.
2477   ///
2478   static OMPCancellationPointDirective *
2479   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2480          OpenMPDirectiveKind CancelRegion);
2481 
2482   /// \brief Creates an empty directive.
2483   ///
2484   /// \param C AST context.
2485   ///
2486   static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
2487                                                     EmptyShell);
2488 
2489   /// \brief Get cancellation region for the current cancellation point.
getCancelRegion()2490   OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
2491 
classof(const Stmt * T)2492   static bool classof(const Stmt *T) {
2493     return T->getStmtClass() == OMPCancellationPointDirectiveClass;
2494   }
2495 };
2496 
2497 /// \brief This represents '#pragma omp cancel' directive.
2498 ///
2499 /// \code
2500 /// #pragma omp cancel for
2501 /// \endcode
2502 ///
2503 /// In this example a cancel is created for innermost 'for' region.
2504 class OMPCancelDirective : public OMPExecutableDirective {
2505   friend class ASTStmtReader;
2506   OpenMPDirectiveKind CancelRegion;
2507   /// \brief Build directive with the given start and end location.
2508   ///
2509   /// \param StartLoc Starting location of the directive kind.
2510   /// \param EndLoc Ending location of the directive.
2511   /// \param NumClauses Number of clauses.
2512   ///
OMPCancelDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)2513   OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2514                      unsigned NumClauses)
2515       : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
2516                                StartLoc, EndLoc, NumClauses, 0),
2517         CancelRegion(OMPD_unknown) {}
2518 
2519   /// \brief Build an empty directive.
2520   ///
2521   /// \param NumClauses Number of clauses.
OMPCancelDirective(unsigned NumClauses)2522   explicit OMPCancelDirective(unsigned NumClauses)
2523       : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
2524                                SourceLocation(), SourceLocation(), NumClauses,
2525                                0),
2526         CancelRegion(OMPD_unknown) {}
2527 
2528   /// \brief Set cancel region for current cancellation point.
2529   /// \param CR Cancellation region.
setCancelRegion(OpenMPDirectiveKind CR)2530   void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
2531 
2532 public:
2533   /// \brief Creates directive.
2534   ///
2535   /// \param C AST context.
2536   /// \param StartLoc Starting location of the directive kind.
2537   /// \param EndLoc Ending Location of the directive.
2538   /// \param Clauses List of clauses.
2539   ///
2540   static OMPCancelDirective *
2541   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2542          ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
2543 
2544   /// \brief Creates an empty directive.
2545   ///
2546   /// \param C AST context.
2547   /// \param NumClauses Number of clauses.
2548   ///
2549   static OMPCancelDirective *CreateEmpty(const ASTContext &C,
2550                                          unsigned NumClauses, EmptyShell);
2551 
2552   /// \brief Get cancellation region for the current cancellation point.
getCancelRegion()2553   OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
2554 
classof(const Stmt * T)2555   static bool classof(const Stmt *T) {
2556     return T->getStmtClass() == OMPCancelDirectiveClass;
2557   }
2558 };
2559 
2560 /// \brief This represents '#pragma omp taskloop' directive.
2561 ///
2562 /// \code
2563 /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
2564 /// \endcode
2565 /// In this example directive '#pragma omp taskloop' has clauses 'private'
2566 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
2567 /// 'num_tasks' with expression 'num'.
2568 ///
2569 class OMPTaskLoopDirective : public OMPLoopDirective {
2570   friend class ASTStmtReader;
2571   /// \brief Build directive with the given start and end location.
2572   ///
2573   /// \param StartLoc Starting location of the directive kind.
2574   /// \param EndLoc Ending location of the directive.
2575   /// \param CollapsedNum Number of collapsed nested loops.
2576   /// \param NumClauses Number of clauses.
2577   ///
OMPTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)2578   OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2579                        unsigned CollapsedNum, unsigned NumClauses)
2580       : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
2581                          StartLoc, EndLoc, CollapsedNum, NumClauses) {}
2582 
2583   /// \brief Build an empty directive.
2584   ///
2585   /// \param CollapsedNum Number of collapsed nested loops.
2586   /// \param NumClauses Number of clauses.
2587   ///
OMPTaskLoopDirective(unsigned CollapsedNum,unsigned NumClauses)2588   explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses)
2589       : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
2590                          SourceLocation(), SourceLocation(), CollapsedNum,
2591                          NumClauses) {}
2592 
2593 public:
2594   /// \brief Creates directive with a list of \a Clauses.
2595   ///
2596   /// \param C AST context.
2597   /// \param StartLoc Starting location of the directive kind.
2598   /// \param EndLoc Ending Location of the directive.
2599   /// \param CollapsedNum Number of collapsed loops.
2600   /// \param Clauses List of clauses.
2601   /// \param AssociatedStmt Statement, associated with the directive.
2602   /// \param Exprs Helper expressions for CodeGen.
2603   ///
2604   static OMPTaskLoopDirective *
2605   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2606          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2607          Stmt *AssociatedStmt, const HelperExprs &Exprs);
2608 
2609   /// \brief Creates an empty directive with the place
2610   /// for \a NumClauses clauses.
2611   ///
2612   /// \param C AST context.
2613   /// \param CollapsedNum Number of collapsed nested loops.
2614   /// \param NumClauses Number of clauses.
2615   ///
2616   static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
2617                                            unsigned NumClauses,
2618                                            unsigned CollapsedNum, EmptyShell);
2619 
classof(const Stmt * T)2620   static bool classof(const Stmt *T) {
2621     return T->getStmtClass() == OMPTaskLoopDirectiveClass;
2622   }
2623 };
2624 
2625 /// \brief This represents '#pragma omp taskloop simd' directive.
2626 ///
2627 /// \code
2628 /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
2629 /// \endcode
2630 /// In this example directive '#pragma omp taskloop simd' has clauses 'private'
2631 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
2632 /// 'num_tasks' with expression 'num'.
2633 ///
2634 class OMPTaskLoopSimdDirective : public OMPLoopDirective {
2635   friend class ASTStmtReader;
2636   /// \brief Build directive with the given start and end location.
2637   ///
2638   /// \param StartLoc Starting location of the directive kind.
2639   /// \param EndLoc Ending location of the directive.
2640   /// \param CollapsedNum Number of collapsed nested loops.
2641   /// \param NumClauses Number of clauses.
2642   ///
OMPTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)2643   OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2644                            unsigned CollapsedNum, unsigned NumClauses)
2645       : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
2646                          OMPD_taskloop_simd, StartLoc, EndLoc, CollapsedNum,
2647                          NumClauses) {}
2648 
2649   /// \brief Build an empty directive.
2650   ///
2651   /// \param CollapsedNum Number of collapsed nested loops.
2652   /// \param NumClauses Number of clauses.
2653   ///
OMPTaskLoopSimdDirective(unsigned CollapsedNum,unsigned NumClauses)2654   explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
2655       : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
2656                          OMPD_taskloop_simd, SourceLocation(), SourceLocation(),
2657                          CollapsedNum, NumClauses) {}
2658 
2659 public:
2660   /// \brief Creates directive with a list of \a Clauses.
2661   ///
2662   /// \param C AST context.
2663   /// \param StartLoc Starting location of the directive kind.
2664   /// \param EndLoc Ending Location of the directive.
2665   /// \param CollapsedNum Number of collapsed loops.
2666   /// \param Clauses List of clauses.
2667   /// \param AssociatedStmt Statement, associated with the directive.
2668   /// \param Exprs Helper expressions for CodeGen.
2669   ///
2670   static OMPTaskLoopSimdDirective *
2671   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2672          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2673          Stmt *AssociatedStmt, const HelperExprs &Exprs);
2674 
2675   /// \brief Creates an empty directive with the place
2676   /// for \a NumClauses clauses.
2677   ///
2678   /// \param C AST context.
2679   /// \param CollapsedNum Number of collapsed nested loops.
2680   /// \param NumClauses Number of clauses.
2681   ///
2682   static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
2683                                                unsigned NumClauses,
2684                                                unsigned CollapsedNum,
2685                                                EmptyShell);
2686 
classof(const Stmt * T)2687   static bool classof(const Stmt *T) {
2688     return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
2689   }
2690 };
2691 
2692 /// \brief This represents '#pragma omp distribute' directive.
2693 ///
2694 /// \code
2695 /// #pragma omp distribute private(a,b)
2696 /// \endcode
2697 /// In this example directive '#pragma omp distribute' has clauses 'private'
2698 /// with the variables 'a' and 'b'
2699 ///
2700 class OMPDistributeDirective : public OMPLoopDirective {
2701   friend class ASTStmtReader;
2702 
2703   /// \brief Build directive with the given start and end location.
2704   ///
2705   /// \param StartLoc Starting location of the directive kind.
2706   /// \param EndLoc Ending location of the directive.
2707   /// \param CollapsedNum Number of collapsed nested loops.
2708   /// \param NumClauses Number of clauses.
2709   ///
OMPDistributeDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)2710   OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2711                          unsigned CollapsedNum, unsigned NumClauses)
2712       : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
2713                          StartLoc, EndLoc, CollapsedNum, NumClauses)
2714         {}
2715 
2716   /// \brief Build an empty directive.
2717   ///
2718   /// \param CollapsedNum Number of collapsed nested loops.
2719   /// \param NumClauses Number of clauses.
2720   ///
OMPDistributeDirective(unsigned CollapsedNum,unsigned NumClauses)2721   explicit OMPDistributeDirective(unsigned CollapsedNum, unsigned NumClauses)
2722       : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
2723                          SourceLocation(), SourceLocation(), CollapsedNum,
2724                          NumClauses)
2725         {}
2726 
2727 public:
2728   /// \brief Creates directive with a list of \a Clauses.
2729   ///
2730   /// \param C AST context.
2731   /// \param StartLoc Starting location of the directive kind.
2732   /// \param EndLoc Ending Location of the directive.
2733   /// \param CollapsedNum Number of collapsed loops.
2734   /// \param Clauses List of clauses.
2735   /// \param AssociatedStmt Statement, associated with the directive.
2736   /// \param Exprs Helper expressions for CodeGen.
2737   ///
2738   static OMPDistributeDirective *
2739   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2740          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2741          Stmt *AssociatedStmt, const HelperExprs &Exprs);
2742 
2743   /// \brief Creates an empty directive with the place
2744   /// for \a NumClauses clauses.
2745   ///
2746   /// \param C AST context.
2747   /// \param CollapsedNum Number of collapsed nested loops.
2748   /// \param NumClauses Number of clauses.
2749   ///
2750   static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
2751                                              unsigned NumClauses,
2752                                              unsigned CollapsedNum, EmptyShell);
2753 
classof(const Stmt * T)2754   static bool classof(const Stmt *T) {
2755     return T->getStmtClass() == OMPDistributeDirectiveClass;
2756   }
2757 };
2758 
2759 /// \brief This represents '#pragma omp target update' directive.
2760 ///
2761 /// \code
2762 /// #pragma omp target update to(a) from(b) device(1)
2763 /// \endcode
2764 /// In this example directive '#pragma omp target update' has clause 'to' with
2765 /// argument 'a', clause 'from' with argument 'b' and clause 'device' with
2766 /// argument '1'.
2767 ///
2768 class OMPTargetUpdateDirective : public OMPExecutableDirective {
2769   friend class ASTStmtReader;
2770   /// \brief Build directive with the given start and end location.
2771   ///
2772   /// \param StartLoc Starting location of the directive kind.
2773   /// \param EndLoc Ending Location of the directive.
2774   /// \param NumClauses The number of clauses.
2775   ///
OMPTargetUpdateDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)2776   OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2777                            unsigned NumClauses)
2778       : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
2779                                OMPD_target_update, StartLoc, EndLoc, NumClauses,
2780                                0) {}
2781 
2782   /// \brief Build an empty directive.
2783   ///
2784   /// \param NumClauses Number of clauses.
2785   ///
OMPTargetUpdateDirective(unsigned NumClauses)2786   explicit OMPTargetUpdateDirective(unsigned NumClauses)
2787       : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
2788                                OMPD_target_update, SourceLocation(),
2789                                SourceLocation(), NumClauses, 0) {}
2790 
2791 public:
2792   /// \brief Creates directive with a list of \a Clauses.
2793   ///
2794   /// \param C AST context.
2795   /// \param StartLoc Starting location of the directive kind.
2796   /// \param EndLoc Ending Location of the directive.
2797   /// \param Clauses List of clauses.
2798   ///
2799   static OMPTargetUpdateDirective *Create(const ASTContext &C,
2800                                           SourceLocation StartLoc,
2801                                           SourceLocation EndLoc,
2802                                           ArrayRef<OMPClause *> Clauses);
2803 
2804   /// \brief Creates an empty directive with the place for \a NumClauses
2805   /// clauses.
2806   ///
2807   /// \param C AST context.
2808   /// \param NumClauses The number of clauses.
2809   ///
2810   static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C,
2811                                                unsigned NumClauses, EmptyShell);
2812 
classof(const Stmt * T)2813   static bool classof(const Stmt *T) {
2814     return T->getStmtClass() == OMPTargetUpdateDirectiveClass;
2815   }
2816 };
2817 
2818 /// \brief This represents '#pragma omp distribute parallel for' composite
2819 ///  directive.
2820 ///
2821 /// \code
2822 /// #pragma omp distribute parallel for private(a,b)
2823 /// \endcode
2824 /// In this example directive '#pragma omp distribute parallel for' has clause
2825 /// 'private' with the variables 'a' and 'b'
2826 ///
2827 class OMPDistributeParallelForDirective : public OMPLoopDirective {
2828   friend class ASTStmtReader;
2829 
2830   /// \brief Build directive with the given start and end location.
2831   ///
2832   /// \param StartLoc Starting location of the directive kind.
2833   /// \param EndLoc Ending location of the directive.
2834   /// \param CollapsedNum Number of collapsed nested loops.
2835   /// \param NumClauses Number of clauses.
2836   ///
OMPDistributeParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)2837   OMPDistributeParallelForDirective(SourceLocation StartLoc,
2838                                     SourceLocation EndLoc,
2839                                     unsigned CollapsedNum, unsigned NumClauses)
2840       : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass,
2841                          OMPD_distribute_parallel_for, StartLoc, EndLoc,
2842                          CollapsedNum, NumClauses) {}
2843 
2844   /// \brief Build an empty directive.
2845   ///
2846   /// \param CollapsedNum Number of collapsed nested loops.
2847   /// \param NumClauses Number of clauses.
2848   ///
OMPDistributeParallelForDirective(unsigned CollapsedNum,unsigned NumClauses)2849   explicit OMPDistributeParallelForDirective(unsigned CollapsedNum,
2850                                              unsigned NumClauses)
2851       : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass,
2852                          OMPD_distribute_parallel_for, SourceLocation(),
2853                          SourceLocation(), CollapsedNum, NumClauses) {}
2854 
2855 public:
2856   /// \brief Creates directive with a list of \a Clauses.
2857   ///
2858   /// \param C AST context.
2859   /// \param StartLoc Starting location of the directive kind.
2860   /// \param EndLoc Ending Location of the directive.
2861   /// \param CollapsedNum Number of collapsed loops.
2862   /// \param Clauses List of clauses.
2863   /// \param AssociatedStmt Statement, associated with the directive.
2864   /// \param Exprs Helper expressions for CodeGen.
2865   ///
2866   static OMPDistributeParallelForDirective *
2867   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2868          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2869          Stmt *AssociatedStmt, const HelperExprs &Exprs);
2870 
2871   /// \brief Creates an empty directive with the place
2872   /// for \a NumClauses clauses.
2873   ///
2874   /// \param C AST context.
2875   /// \param CollapsedNum Number of collapsed nested loops.
2876   /// \param NumClauses Number of clauses.
2877   ///
2878   static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C,
2879                                                         unsigned NumClauses,
2880                                                         unsigned CollapsedNum,
2881                                                         EmptyShell);
2882 
classof(const Stmt * T)2883   static bool classof(const Stmt *T) {
2884     return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
2885   }
2886 };
2887 
2888 /// This represents '#pragma omp distribute parallel for simd' composite
2889 /// directive.
2890 ///
2891 /// \code
2892 /// #pragma omp distribute parallel for simd private(x)
2893 /// \endcode
2894 /// In this example directive '#pragma omp distribute parallel for simd' has
2895 /// clause 'private' with the variables 'x'
2896 ///
2897 class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective {
2898   friend class ASTStmtReader;
2899 
2900   /// Build directive with the given start and end location.
2901   ///
2902   /// \param StartLoc Starting location of the directive kind.
2903   /// \param EndLoc Ending location of the directive.
2904   /// \param CollapsedNum Number of collapsed nested loops.
2905   /// \param NumClauses Number of clauses.
2906   ///
OMPDistributeParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)2907   OMPDistributeParallelForSimdDirective(SourceLocation StartLoc,
2908                                         SourceLocation EndLoc,
2909                                         unsigned CollapsedNum,
2910                                         unsigned NumClauses)
2911       : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass,
2912                          OMPD_distribute_parallel_for_simd, StartLoc,
2913                          EndLoc, CollapsedNum, NumClauses) {}
2914 
2915   /// Build an empty directive.
2916   ///
2917   /// \param CollapsedNum Number of collapsed nested loops.
2918   /// \param NumClauses Number of clauses.
2919   ///
OMPDistributeParallelForSimdDirective(unsigned CollapsedNum,unsigned NumClauses)2920   explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum,
2921                                                  unsigned NumClauses)
2922       : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass,
2923                          OMPD_distribute_parallel_for_simd,
2924                          SourceLocation(), SourceLocation(), CollapsedNum,
2925                          NumClauses) {}
2926 
2927 public:
2928   /// Creates directive with a list of \a Clauses.
2929   ///
2930   /// \param C AST context.
2931   /// \param StartLoc Starting location of the directive kind.
2932   /// \param EndLoc Ending Location of the directive.
2933   /// \param CollapsedNum Number of collapsed loops.
2934   /// \param Clauses List of clauses.
2935   /// \param AssociatedStmt Statement, associated with the directive.
2936   /// \param Exprs Helper expressions for CodeGen.
2937   ///
2938   static OMPDistributeParallelForSimdDirective *Create(
2939       const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2940       unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2941       Stmt *AssociatedStmt, const HelperExprs &Exprs);
2942 
2943   /// Creates an empty directive with the place for \a NumClauses clauses.
2944   ///
2945   /// \param C AST context.
2946   /// \param CollapsedNum Number of collapsed nested loops.
2947   /// \param NumClauses Number of clauses.
2948   ///
2949   static OMPDistributeParallelForSimdDirective *CreateEmpty(
2950       const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
2951       EmptyShell);
2952 
classof(const Stmt * T)2953   static bool classof(const Stmt *T) {
2954     return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass;
2955   }
2956 };
2957 
2958 /// This represents '#pragma omp distribute simd' composite directive.
2959 ///
2960 /// \code
2961 /// #pragma omp distribute simd private(x)
2962 /// \endcode
2963 /// In this example directive '#pragma omp distribute simd' has clause
2964 /// 'private' with the variables 'x'
2965 ///
2966 class OMPDistributeSimdDirective final : public OMPLoopDirective {
2967   friend class ASTStmtReader;
2968 
2969   /// Build directive with the given start and end location.
2970   ///
2971   /// \param StartLoc Starting location of the directive kind.
2972   /// \param EndLoc Ending location of the directive.
2973   /// \param CollapsedNum Number of collapsed nested loops.
2974   /// \param NumClauses Number of clauses.
2975   ///
OMPDistributeSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)2976   OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2977                              unsigned CollapsedNum, unsigned NumClauses)
2978       : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass,
2979                          OMPD_distribute_simd, StartLoc, EndLoc, CollapsedNum,
2980                          NumClauses) {}
2981 
2982   /// Build an empty directive.
2983   ///
2984   /// \param CollapsedNum Number of collapsed nested loops.
2985   /// \param NumClauses Number of clauses.
2986   ///
OMPDistributeSimdDirective(unsigned CollapsedNum,unsigned NumClauses)2987   explicit OMPDistributeSimdDirective(unsigned CollapsedNum,
2988                                       unsigned NumClauses)
2989       : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass,
2990                          OMPD_distribute_simd, SourceLocation(),
2991                          SourceLocation(), CollapsedNum, NumClauses) {}
2992 
2993 public:
2994   /// Creates directive with a list of \a Clauses.
2995   ///
2996   /// \param C AST context.
2997   /// \param StartLoc Starting location of the directive kind.
2998   /// \param EndLoc Ending Location of the directive.
2999   /// \param CollapsedNum Number of collapsed loops.
3000   /// \param Clauses List of clauses.
3001   /// \param AssociatedStmt Statement, associated with the directive.
3002   /// \param Exprs Helper expressions for CodeGen.
3003   ///
3004   static OMPDistributeSimdDirective *
3005   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3006          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3007          Stmt *AssociatedStmt, const HelperExprs &Exprs);
3008 
3009   /// Creates an empty directive with the place for \a NumClauses clauses.
3010   ///
3011   /// \param C AST context.
3012   /// \param CollapsedNum Number of collapsed nested loops.
3013   /// \param NumClauses Number of clauses.
3014   ///
3015   static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C,
3016                                                  unsigned NumClauses,
3017                                                  unsigned CollapsedNum,
3018                                                  EmptyShell);
3019 
classof(const Stmt * T)3020   static bool classof(const Stmt *T) {
3021     return T->getStmtClass() == OMPDistributeSimdDirectiveClass;
3022   }
3023 };
3024 
3025 /// This represents '#pragma omp target parallel for simd' directive.
3026 ///
3027 /// \code
3028 /// #pragma omp target parallel for simd private(a) map(b) safelen(c)
3029 /// \endcode
3030 /// In this example directive '#pragma omp target parallel for simd' has clauses
3031 /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen'
3032 /// with the variable 'c'.
3033 ///
3034 class OMPTargetParallelForSimdDirective final : public OMPLoopDirective {
3035   friend class ASTStmtReader;
3036 
3037   /// Build directive with the given start and end location.
3038   ///
3039   /// \param StartLoc Starting location of the directive kind.
3040   /// \param EndLoc Ending location of the directive.
3041   /// \param CollapsedNum Number of collapsed nested loops.
3042   /// \param NumClauses Number of clauses.
3043   ///
OMPTargetParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)3044   OMPTargetParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
3045                                 unsigned CollapsedNum, unsigned NumClauses)
3046       : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass,
3047                          OMPD_target_parallel_for_simd, StartLoc, EndLoc,
3048                          CollapsedNum, NumClauses) {}
3049 
3050   /// Build an empty directive.
3051   ///
3052   /// \param CollapsedNum Number of collapsed nested loops.
3053   /// \param NumClauses Number of clauses.
3054   ///
OMPTargetParallelForSimdDirective(unsigned CollapsedNum,unsigned NumClauses)3055   explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum,
3056                                              unsigned NumClauses)
3057       : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass,
3058                          OMPD_target_parallel_for_simd, SourceLocation(),
3059                          SourceLocation(), CollapsedNum, NumClauses) {}
3060 
3061 public:
3062   /// Creates directive with a list of \a Clauses.
3063   ///
3064   /// \param C AST context.
3065   /// \param StartLoc Starting location of the directive kind.
3066   /// \param EndLoc Ending Location of the directive.
3067   /// \param CollapsedNum Number of collapsed loops.
3068   /// \param Clauses List of clauses.
3069   /// \param AssociatedStmt Statement, associated with the directive.
3070   /// \param Exprs Helper expressions for CodeGen.
3071   ///
3072   static OMPTargetParallelForSimdDirective *
3073   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
3074          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
3075          Stmt *AssociatedStmt, const HelperExprs &Exprs);
3076 
3077   /// Creates an empty directive with the place for \a NumClauses clauses.
3078   ///
3079   /// \param C AST context.
3080   /// \param CollapsedNum Number of collapsed nested loops.
3081   /// \param NumClauses Number of clauses.
3082   ///
3083   static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C,
3084                                                         unsigned NumClauses,
3085                                                         unsigned CollapsedNum,
3086                                                         EmptyShell);
3087 
classof(const Stmt * T)3088   static bool classof(const Stmt *T) {
3089     return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
3090   }
3091 };
3092 
3093 } // end namespace clang
3094 
3095 #endif
3096