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::RoundUpToAlignment(sizeof(T),
74                                                llvm::alignOf<OMPClause *>())) {}
75 
76   /// \brief Sets the list of variables for this clause.
77   ///
78   /// \param Clauses The list of clauses for the directive.
79   ///
80   void setClauses(ArrayRef<OMPClause *> Clauses);
81 
82   /// \brief Set the associated statement for the directive.
83   ///
84   /// /param S Associated statement.
85   ///
setAssociatedStmt(Stmt * S)86   void setAssociatedStmt(Stmt *S) {
87     assert(hasAssociatedStmt() && "no associated statement.");
88     *child_begin() = S;
89   }
90 
91 public:
92   /// \brief Iterates over a filtered subrange of clauses applied to a
93   /// directive.
94   ///
95   /// This iterator visits only clauses of type SpecificClause.
96   template <typename SpecificClause>
97   class specific_clause_iterator
98       : public llvm::iterator_adaptor_base<
99             specific_clause_iterator<SpecificClause>,
100             ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag,
101             const SpecificClause *, ptrdiff_t, const SpecificClause *,
102             const SpecificClause *> {
103     ArrayRef<OMPClause *>::const_iterator End;
104 
SkipToNextClause()105     void SkipToNextClause() {
106       while (this->I != End && !isa<SpecificClause>(*this->I))
107         ++this->I;
108     }
109 
110   public:
specific_clause_iterator(ArrayRef<OMPClause * > Clauses)111     explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses)
112         : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()),
113           End(Clauses.end()) {
114       SkipToNextClause();
115     }
116 
117     const SpecificClause *operator*() const {
118       return cast<SpecificClause>(*this->I);
119     }
120     const SpecificClause *operator->() const { return **this; }
121 
122     specific_clause_iterator &operator++() {
123       ++this->I;
124       SkipToNextClause();
125       return *this;
126     }
127   };
128 
129   template <typename SpecificClause>
130   static llvm::iterator_range<specific_clause_iterator<SpecificClause>>
getClausesOfKind(ArrayRef<OMPClause * > Clauses)131   getClausesOfKind(ArrayRef<OMPClause *> Clauses) {
132     return {specific_clause_iterator<SpecificClause>(Clauses),
133             specific_clause_iterator<SpecificClause>(
134                 llvm::makeArrayRef(Clauses.end(), 0))};
135   }
136 
137   template <typename SpecificClause>
138   llvm::iterator_range<specific_clause_iterator<SpecificClause>>
getClausesOfKind()139   getClausesOfKind() const {
140     return getClausesOfKind<SpecificClause>(clauses());
141   }
142 
143   /// Gets a single clause of the specified kind associated with the
144   /// current directive iff there is only one clause of this kind (and assertion
145   /// is fired if there is more than one clause is associated with the
146   /// directive). Returns nullptr if no clause of this kind is associated with
147   /// the directive.
148   template <typename SpecificClause>
getSingleClause()149   const SpecificClause *getSingleClause() const {
150     auto Clauses = getClausesOfKind<SpecificClause>();
151 
152     if (Clauses.begin() != Clauses.end()) {
153       assert(std::next(Clauses.begin()) == Clauses.end() &&
154              "There are at least 2 clauses of the specified kind");
155       return *Clauses.begin();
156     }
157     return nullptr;
158   }
159 
160   /// Returns true if the current directive has one or more clauses of a
161   /// specific kind.
162   template <typename SpecificClause>
hasClausesOfKind()163   bool hasClausesOfKind() const {
164     auto Clauses = getClausesOfKind<SpecificClause>();
165     return Clauses.begin() != Clauses.end();
166   }
167 
168   /// \brief Returns starting location of directive kind.
getLocStart()169   SourceLocation getLocStart() const { return StartLoc; }
170   /// \brief Returns ending location of directive.
getLocEnd()171   SourceLocation getLocEnd() const { return EndLoc; }
172 
173   /// \brief Set starting location of directive kind.
174   ///
175   /// \param Loc New starting location of directive.
176   ///
setLocStart(SourceLocation Loc)177   void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
178   /// \brief Set ending location of directive.
179   ///
180   /// \param Loc New ending location of directive.
181   ///
setLocEnd(SourceLocation Loc)182   void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
183 
184   /// \brief Get number of clauses.
getNumClauses()185   unsigned getNumClauses() const { return NumClauses; }
186 
187   /// \brief Returns specified clause.
188   ///
189   /// \param i Number of clause.
190   ///
getClause(unsigned i)191   OMPClause *getClause(unsigned i) const { return clauses()[i]; }
192 
193   /// \brief Returns true if directive has associated statement.
hasAssociatedStmt()194   bool hasAssociatedStmt() const { return NumChildren > 0; }
195 
196   /// \brief Returns statement associated with the directive.
getAssociatedStmt()197   Stmt *getAssociatedStmt() const {
198     assert(hasAssociatedStmt() && "no associated statement.");
199     return const_cast<Stmt *>(*child_begin());
200   }
201 
getDirectiveKind()202   OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
203 
classof(const Stmt * S)204   static bool classof(const Stmt *S) {
205     return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
206            S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
207   }
208 
children()209   child_range children() {
210     if (!hasAssociatedStmt())
211       return child_range(child_iterator(), child_iterator());
212     Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
213     return child_range(ChildStorage, ChildStorage + NumChildren);
214   }
215 
clauses()216   ArrayRef<OMPClause *> clauses() { return getClauses(); }
217 
clauses()218   ArrayRef<OMPClause *> clauses() const {
219     return const_cast<OMPExecutableDirective *>(this)->getClauses();
220   }
221 };
222 
223 /// \brief This represents '#pragma omp parallel' directive.
224 ///
225 /// \code
226 /// #pragma omp parallel private(a,b) reduction(+: c,d)
227 /// \endcode
228 /// In this example directive '#pragma omp parallel' has clauses 'private'
229 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
230 /// variables 'c' and 'd'.
231 ///
232 class OMPParallelDirective : public OMPExecutableDirective {
233   friend class ASTStmtReader;
234   /// \brief true if the construct has inner cancel directive.
235   bool HasCancel;
236 
237   /// \brief Build directive with the given start and end location.
238   ///
239   /// \param StartLoc Starting location of the directive (directive keyword).
240   /// \param EndLoc Ending Location of the directive.
241   ///
OMPParallelDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)242   OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
243                        unsigned NumClauses)
244       : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
245                                StartLoc, EndLoc, NumClauses, 1),
246         HasCancel(false) {}
247 
248   /// \brief Build an empty directive.
249   ///
250   /// \param NumClauses Number of clauses.
251   ///
OMPParallelDirective(unsigned NumClauses)252   explicit OMPParallelDirective(unsigned NumClauses)
253       : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
254                                SourceLocation(), SourceLocation(), NumClauses,
255                                1),
256         HasCancel(false) {}
257 
258   /// \brief Set cancel state.
setHasCancel(bool Has)259   void setHasCancel(bool Has) { HasCancel = Has; }
260 
261 public:
262   /// \brief Creates directive with a list of \a Clauses.
263   ///
264   /// \param C AST context.
265   /// \param StartLoc Starting location of the directive kind.
266   /// \param EndLoc Ending Location of the directive.
267   /// \param Clauses List of clauses.
268   /// \param AssociatedStmt Statement associated with the directive.
269   /// \param HasCancel true if this directive has inner cancel directive.
270   ///
271   static OMPParallelDirective *
272   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
273          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
274 
275   /// \brief Creates an empty directive with the place for \a N clauses.
276   ///
277   /// \param C AST context.
278   /// \param NumClauses Number of clauses.
279   ///
280   static OMPParallelDirective *CreateEmpty(const ASTContext &C,
281                                            unsigned NumClauses, EmptyShell);
282 
283   /// \brief Return true if current directive has inner cancel directive.
hasCancel()284   bool hasCancel() const { return HasCancel; }
285 
classof(const Stmt * T)286   static bool classof(const Stmt *T) {
287     return T->getStmtClass() == OMPParallelDirectiveClass;
288   }
289 };
290 
291 /// \brief This is a common base class for loop directives ('omp simd', 'omp
292 /// for', 'omp for simd' etc.). It is responsible for the loop code generation.
293 ///
294 class OMPLoopDirective : public OMPExecutableDirective {
295   friend class ASTStmtReader;
296   /// \brief Number of collapsed loops as specified by 'collapse' clause.
297   unsigned CollapsedNum;
298 
299   /// \brief Offsets to the stored exprs.
300   /// This enumeration contains offsets to all the pointers to children
301   /// expressions stored in OMPLoopDirective.
302   /// The first 9 children are nesessary for all the loop directives, and
303   /// the next 7 are specific to the worksharing ones.
304   /// After the fixed children, three arrays of length CollapsedNum are
305   /// allocated: loop counters, their updates and final values.
306   ///
307   enum {
308     AssociatedStmtOffset = 0,
309     IterationVariableOffset = 1,
310     LastIterationOffset = 2,
311     CalcLastIterationOffset = 3,
312     PreConditionOffset = 4,
313     CondOffset = 5,
314     InitOffset = 6,
315     IncOffset = 7,
316     // The '...End' enumerators do not correspond to child expressions - they
317     // specify the offset to the end (and start of the following counters/
318     // updates/finals arrays).
319     DefaultEnd = 8,
320     // The following 7 exprs are used by worksharing loops only.
321     IsLastIterVariableOffset = 8,
322     LowerBoundVariableOffset = 9,
323     UpperBoundVariableOffset = 10,
324     StrideVariableOffset = 11,
325     EnsureUpperBoundOffset = 12,
326     NextLowerBoundOffset = 13,
327     NextUpperBoundOffset = 14,
328     // Offset to the end (and start of the following counters/updates/finals
329     // arrays) for worksharing loop directives.
330     WorksharingEnd = 15,
331   };
332 
333   /// \brief Get the counters storage.
getCounters()334   MutableArrayRef<Expr *> getCounters() {
335     Expr **Storage = reinterpret_cast<Expr **>(
336         &(*(std::next(child_begin(), getArraysOffset(getDirectiveKind())))));
337     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
338   }
339 
340   /// \brief Get the private counters storage.
getPrivateCounters()341   MutableArrayRef<Expr *> getPrivateCounters() {
342     Expr **Storage = reinterpret_cast<Expr **>(&*std::next(
343         child_begin(), getArraysOffset(getDirectiveKind()) + CollapsedNum));
344     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
345   }
346 
347   /// \brief Get the updates storage.
getInits()348   MutableArrayRef<Expr *> getInits() {
349     Expr **Storage = reinterpret_cast<Expr **>(
350         &*std::next(child_begin(),
351                     getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum));
352     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
353   }
354 
355   /// \brief Get the updates storage.
getUpdates()356   MutableArrayRef<Expr *> getUpdates() {
357     Expr **Storage = reinterpret_cast<Expr **>(
358         &*std::next(child_begin(),
359                     getArraysOffset(getDirectiveKind()) + 3 * CollapsedNum));
360     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
361   }
362 
363   /// \brief Get the final counter updates storage.
getFinals()364   MutableArrayRef<Expr *> getFinals() {
365     Expr **Storage = reinterpret_cast<Expr **>(
366         &*std::next(child_begin(),
367                     getArraysOffset(getDirectiveKind()) + 4 * CollapsedNum));
368     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
369   }
370 
371 protected:
372   /// \brief Build instance of loop directive of class \a Kind.
373   ///
374   /// \param SC Statement class.
375   /// \param Kind Kind of OpenMP directive.
376   /// \param StartLoc Starting location of the directive (directive keyword).
377   /// \param EndLoc Ending location of the directive.
378   /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
379   /// \param NumClauses Number of clauses.
380   /// \param NumSpecialChildren Number of additional directive-specific stmts.
381   ///
382   template <typename T>
383   OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind,
384                    SourceLocation StartLoc, SourceLocation EndLoc,
385                    unsigned CollapsedNum, unsigned NumClauses,
386                    unsigned NumSpecialChildren = 0)
387       : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses,
388                                numLoopChildren(CollapsedNum, Kind) +
389                                    NumSpecialChildren),
390         CollapsedNum(CollapsedNum) {}
391 
392   /// \brief Offset to the start of children expression arrays.
getArraysOffset(OpenMPDirectiveKind Kind)393   static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
394     return (isOpenMPWorksharingDirective(Kind) ||
395             isOpenMPTaskLoopDirective(Kind) ||
396             isOpenMPDistributeDirective(Kind))
397                ? WorksharingEnd
398                : DefaultEnd;
399   }
400 
401   /// \brief Children number.
numLoopChildren(unsigned CollapsedNum,OpenMPDirectiveKind Kind)402   static unsigned numLoopChildren(unsigned CollapsedNum,
403                                   OpenMPDirectiveKind Kind) {
404     return getArraysOffset(Kind) + 5 * CollapsedNum; // Counters,
405                                                      // PrivateCounters, Inits,
406                                                      // Updates and Finals
407   }
408 
setIterationVariable(Expr * IV)409   void setIterationVariable(Expr *IV) {
410     *std::next(child_begin(), IterationVariableOffset) = IV;
411   }
setLastIteration(Expr * LI)412   void setLastIteration(Expr *LI) {
413     *std::next(child_begin(), LastIterationOffset) = LI;
414   }
setCalcLastIteration(Expr * CLI)415   void setCalcLastIteration(Expr *CLI) {
416     *std::next(child_begin(), CalcLastIterationOffset) = CLI;
417   }
setPreCond(Expr * PC)418   void setPreCond(Expr *PC) {
419     *std::next(child_begin(), PreConditionOffset) = PC;
420   }
setCond(Expr * Cond)421   void setCond(Expr *Cond) {
422     *std::next(child_begin(), CondOffset) = Cond;
423   }
setInit(Expr * Init)424   void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; }
setInc(Expr * Inc)425   void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; }
setIsLastIterVariable(Expr * IL)426   void setIsLastIterVariable(Expr *IL) {
427     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
428             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
429             isOpenMPDistributeDirective(getDirectiveKind())) &&
430            "expected worksharing loop directive");
431     *std::next(child_begin(), IsLastIterVariableOffset) = IL;
432   }
setLowerBoundVariable(Expr * LB)433   void setLowerBoundVariable(Expr *LB) {
434     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
435             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
436             isOpenMPDistributeDirective(getDirectiveKind())) &&
437            "expected worksharing loop directive");
438     *std::next(child_begin(), LowerBoundVariableOffset) = LB;
439   }
setUpperBoundVariable(Expr * UB)440   void setUpperBoundVariable(Expr *UB) {
441     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
442             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
443             isOpenMPDistributeDirective(getDirectiveKind())) &&
444            "expected worksharing loop directive");
445     *std::next(child_begin(), UpperBoundVariableOffset) = UB;
446   }
setStrideVariable(Expr * ST)447   void setStrideVariable(Expr *ST) {
448     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
449             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
450             isOpenMPDistributeDirective(getDirectiveKind())) &&
451            "expected worksharing loop directive");
452     *std::next(child_begin(), StrideVariableOffset) = ST;
453   }
setEnsureUpperBound(Expr * EUB)454   void setEnsureUpperBound(Expr *EUB) {
455     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
456             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
457             isOpenMPDistributeDirective(getDirectiveKind())) &&
458            "expected worksharing loop directive");
459     *std::next(child_begin(), EnsureUpperBoundOffset) = EUB;
460   }
setNextLowerBound(Expr * NLB)461   void setNextLowerBound(Expr *NLB) {
462     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
463             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
464             isOpenMPDistributeDirective(getDirectiveKind())) &&
465            "expected worksharing loop directive");
466     *std::next(child_begin(), NextLowerBoundOffset) = NLB;
467   }
setNextUpperBound(Expr * NUB)468   void setNextUpperBound(Expr *NUB) {
469     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
470             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
471             isOpenMPDistributeDirective(getDirectiveKind())) &&
472            "expected worksharing loop directive");
473     *std::next(child_begin(), NextUpperBoundOffset) = NUB;
474   }
475   void setCounters(ArrayRef<Expr *> A);
476   void setPrivateCounters(ArrayRef<Expr *> A);
477   void setInits(ArrayRef<Expr *> A);
478   void setUpdates(ArrayRef<Expr *> A);
479   void setFinals(ArrayRef<Expr *> A);
480 
481 public:
482   /// \brief The expressions built for the OpenMP loop CodeGen for the
483   /// whole collapsed loop nest.
484   struct HelperExprs {
485     /// \brief Loop iteration variable.
486     Expr *IterationVarRef;
487     /// \brief Loop last iteration number.
488     Expr *LastIteration;
489     /// \brief Loop number of iterations.
490     Expr *NumIterations;
491     /// \brief Calculation of last iteration.
492     Expr *CalcLastIteration;
493     /// \brief Loop pre-condition.
494     Expr *PreCond;
495     /// \brief Loop condition.
496     Expr *Cond;
497     /// \brief Loop iteration variable init.
498     Expr *Init;
499     /// \brief Loop increment.
500     Expr *Inc;
501     /// \brief IsLastIteration - local flag variable passed to runtime.
502     Expr *IL;
503     /// \brief LowerBound - local variable passed to runtime.
504     Expr *LB;
505     /// \brief UpperBound - local variable passed to runtime.
506     Expr *UB;
507     /// \brief Stride - local variable passed to runtime.
508     Expr *ST;
509     /// \brief EnsureUpperBound -- expression LB = min(LB, NumIterations).
510     Expr *EUB;
511     /// \brief Update of LowerBound for statically sheduled 'omp for' loops.
512     Expr *NLB;
513     /// \brief Update of UpperBound for statically sheduled 'omp for' loops.
514     Expr *NUB;
515     /// \brief Counters Loop counters.
516     SmallVector<Expr *, 4> Counters;
517     /// \brief PrivateCounters Loop counters.
518     SmallVector<Expr *, 4> PrivateCounters;
519     /// \brief Expressions for loop counters inits for CodeGen.
520     SmallVector<Expr *, 4> Inits;
521     /// \brief Expressions for loop counters update for CodeGen.
522     SmallVector<Expr *, 4> Updates;
523     /// \brief Final loop counter values for GodeGen.
524     SmallVector<Expr *, 4> Finals;
525 
526     /// \brief Check if all the expressions are built (does not check the
527     /// worksharing ones).
builtAllHelperExprs528     bool builtAll() {
529       return IterationVarRef != nullptr && LastIteration != nullptr &&
530              NumIterations != nullptr && PreCond != nullptr &&
531              Cond != nullptr && Init != nullptr && Inc != nullptr;
532     }
533 
534     /// \brief Initialize all the fields to null.
535     /// \param Size Number of elements in the counters/finals/updates arrays.
clearHelperExprs536     void clear(unsigned Size) {
537       IterationVarRef = nullptr;
538       LastIteration = nullptr;
539       CalcLastIteration = nullptr;
540       PreCond = nullptr;
541       Cond = nullptr;
542       Init = nullptr;
543       Inc = nullptr;
544       IL = nullptr;
545       LB = nullptr;
546       UB = nullptr;
547       ST = nullptr;
548       EUB = nullptr;
549       NLB = nullptr;
550       NUB = nullptr;
551       Counters.resize(Size);
552       PrivateCounters.resize(Size);
553       Inits.resize(Size);
554       Updates.resize(Size);
555       Finals.resize(Size);
556       for (unsigned i = 0; i < Size; ++i) {
557         Counters[i] = nullptr;
558         PrivateCounters[i] = nullptr;
559         Inits[i] = nullptr;
560         Updates[i] = nullptr;
561         Finals[i] = nullptr;
562       }
563     }
564   };
565 
566   /// \brief Get number of collapsed loops.
getCollapsedNumber()567   unsigned getCollapsedNumber() const { return CollapsedNum; }
568 
getIterationVariable()569   Expr *getIterationVariable() const {
570     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
571         *std::next(child_begin(), IterationVariableOffset)));
572   }
getLastIteration()573   Expr *getLastIteration() const {
574     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
575         *std::next(child_begin(), LastIterationOffset)));
576   }
getCalcLastIteration()577   Expr *getCalcLastIteration() const {
578     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
579         *std::next(child_begin(), CalcLastIterationOffset)));
580   }
getPreCond()581   Expr *getPreCond() const {
582     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
583         *std::next(child_begin(), PreConditionOffset)));
584   }
getCond()585   Expr *getCond() const {
586     return const_cast<Expr *>(
587         reinterpret_cast<const Expr *>(*std::next(child_begin(), CondOffset)));
588   }
getInit()589   Expr *getInit() const {
590     return const_cast<Expr *>(
591         reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset)));
592   }
getInc()593   Expr *getInc() const {
594     return const_cast<Expr *>(
595         reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset)));
596   }
getIsLastIterVariable()597   Expr *getIsLastIterVariable() const {
598     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
599             isOpenMPTaskLoopDirective(getDirectiveKind())) &&
600            "expected worksharing loop directive");
601     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
602         *std::next(child_begin(), IsLastIterVariableOffset)));
603   }
getLowerBoundVariable()604   Expr *getLowerBoundVariable() const {
605     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
606             isOpenMPTaskLoopDirective(getDirectiveKind())) &&
607            "expected worksharing loop directive");
608     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
609         *std::next(child_begin(), LowerBoundVariableOffset)));
610   }
getUpperBoundVariable()611   Expr *getUpperBoundVariable() const {
612     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
613             isOpenMPTaskLoopDirective(getDirectiveKind())) &&
614            "expected worksharing loop directive");
615     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
616         *std::next(child_begin(), UpperBoundVariableOffset)));
617   }
getStrideVariable()618   Expr *getStrideVariable() const {
619     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
620             isOpenMPTaskLoopDirective(getDirectiveKind())) &&
621            "expected worksharing loop directive");
622     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
623         *std::next(child_begin(), StrideVariableOffset)));
624   }
getEnsureUpperBound()625   Expr *getEnsureUpperBound() const {
626     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
627             isOpenMPTaskLoopDirective(getDirectiveKind())) &&
628            "expected worksharing loop directive");
629     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
630         *std::next(child_begin(), EnsureUpperBoundOffset)));
631   }
getNextLowerBound()632   Expr *getNextLowerBound() const {
633     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
634             isOpenMPTaskLoopDirective(getDirectiveKind())) &&
635            "expected worksharing loop directive");
636     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
637         *std::next(child_begin(), NextLowerBoundOffset)));
638   }
getNextUpperBound()639   Expr *getNextUpperBound() const {
640     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
641             isOpenMPTaskLoopDirective(getDirectiveKind())) &&
642            "expected worksharing loop directive");
643     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
644         *std::next(child_begin(), NextUpperBoundOffset)));
645   }
getBody()646   const Stmt *getBody() const {
647     // This relies on the loop form is already checked by Sema.
648     Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
649     Body = cast<ForStmt>(Body)->getBody();
650     for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
651       Body = Body->IgnoreContainers();
652       Body = cast<ForStmt>(Body)->getBody();
653     }
654     return Body;
655   }
656 
counters()657   ArrayRef<Expr *> counters() { return getCounters(); }
658 
counters()659   ArrayRef<Expr *> counters() const {
660     return const_cast<OMPLoopDirective *>(this)->getCounters();
661   }
662 
private_counters()663   ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
664 
private_counters()665   ArrayRef<Expr *> private_counters() const {
666     return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
667   }
668 
inits()669   ArrayRef<Expr *> inits() { return getInits(); }
670 
inits()671   ArrayRef<Expr *> inits() const {
672     return const_cast<OMPLoopDirective *>(this)->getInits();
673   }
674 
updates()675   ArrayRef<Expr *> updates() { return getUpdates(); }
676 
updates()677   ArrayRef<Expr *> updates() const {
678     return const_cast<OMPLoopDirective *>(this)->getUpdates();
679   }
680 
finals()681   ArrayRef<Expr *> finals() { return getFinals(); }
682 
finals()683   ArrayRef<Expr *> finals() const {
684     return const_cast<OMPLoopDirective *>(this)->getFinals();
685   }
686 
classof(const Stmt * T)687   static bool classof(const Stmt *T) {
688     return T->getStmtClass() == OMPSimdDirectiveClass ||
689            T->getStmtClass() == OMPForDirectiveClass ||
690            T->getStmtClass() == OMPForSimdDirectiveClass ||
691            T->getStmtClass() == OMPParallelForDirectiveClass ||
692            T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
693            T->getStmtClass() == OMPTaskLoopDirectiveClass ||
694            T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
695            T->getStmtClass() == OMPDistributeDirectiveClass;
696   }
697 };
698 
699 /// \brief This represents '#pragma omp simd' directive.
700 ///
701 /// \code
702 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
703 /// \endcode
704 /// In this example directive '#pragma omp simd' has clauses 'private'
705 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
706 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
707 ///
708 class OMPSimdDirective : public OMPLoopDirective {
709   friend class ASTStmtReader;
710   /// \brief Build directive with the given start and end location.
711   ///
712   /// \param StartLoc Starting location of the directive kind.
713   /// \param EndLoc Ending location of the directive.
714   /// \param CollapsedNum Number of collapsed nested loops.
715   /// \param NumClauses Number of clauses.
716   ///
OMPSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)717   OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
718                    unsigned CollapsedNum, unsigned NumClauses)
719       : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
720                          EndLoc, CollapsedNum, NumClauses) {}
721 
722   /// \brief Build an empty directive.
723   ///
724   /// \param CollapsedNum Number of collapsed nested loops.
725   /// \param NumClauses Number of clauses.
726   ///
OMPSimdDirective(unsigned CollapsedNum,unsigned NumClauses)727   explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
728       : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd,
729                          SourceLocation(), SourceLocation(), CollapsedNum,
730                          NumClauses) {}
731 
732 public:
733   /// \brief Creates directive with a list of \a Clauses.
734   ///
735   /// \param C AST context.
736   /// \param StartLoc Starting location of the directive kind.
737   /// \param EndLoc Ending Location of the directive.
738   /// \param CollapsedNum Number of collapsed loops.
739   /// \param Clauses List of clauses.
740   /// \param AssociatedStmt Statement, associated with the directive.
741   /// \param Exprs Helper expressions for CodeGen.
742   ///
743   static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
744                                   SourceLocation EndLoc, unsigned CollapsedNum,
745                                   ArrayRef<OMPClause *> Clauses,
746                                   Stmt *AssociatedStmt,
747                                   const HelperExprs &Exprs);
748 
749   /// \brief Creates an empty directive with the place
750   /// for \a NumClauses clauses.
751   ///
752   /// \param C AST context.
753   /// \param CollapsedNum Number of collapsed nested loops.
754   /// \param NumClauses Number of clauses.
755   ///
756   static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
757                                        unsigned CollapsedNum, EmptyShell);
758 
classof(const Stmt * T)759   static bool classof(const Stmt *T) {
760     return T->getStmtClass() == OMPSimdDirectiveClass;
761   }
762 };
763 
764 /// \brief This represents '#pragma omp for' directive.
765 ///
766 /// \code
767 /// #pragma omp for private(a,b) reduction(+:c,d)
768 /// \endcode
769 /// In this example directive '#pragma omp for' has clauses 'private' with the
770 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
771 /// and 'd'.
772 ///
773 class OMPForDirective : public OMPLoopDirective {
774   friend class ASTStmtReader;
775 
776   /// \brief true if current directive has inner cancel directive.
777   bool HasCancel;
778 
779   /// \brief Build directive with the given start and end location.
780   ///
781   /// \param StartLoc Starting location of the directive kind.
782   /// \param EndLoc Ending location of the directive.
783   /// \param CollapsedNum Number of collapsed nested loops.
784   /// \param NumClauses Number of clauses.
785   ///
OMPForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)786   OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
787                   unsigned CollapsedNum, unsigned NumClauses)
788       : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc,
789                          CollapsedNum, NumClauses),
790         HasCancel(false) {}
791 
792   /// \brief Build an empty directive.
793   ///
794   /// \param CollapsedNum Number of collapsed nested loops.
795   /// \param NumClauses Number of clauses.
796   ///
OMPForDirective(unsigned CollapsedNum,unsigned NumClauses)797   explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
798       : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(),
799                          SourceLocation(), CollapsedNum, NumClauses),
800         HasCancel(false) {}
801 
802   /// \brief Set cancel state.
setHasCancel(bool Has)803   void setHasCancel(bool Has) { HasCancel = Has; }
804 
805 public:
806   /// \brief Creates directive with a list of \a Clauses.
807   ///
808   /// \param C AST context.
809   /// \param StartLoc Starting location of the directive kind.
810   /// \param EndLoc Ending Location of the directive.
811   /// \param CollapsedNum Number of collapsed loops.
812   /// \param Clauses List of clauses.
813   /// \param AssociatedStmt Statement, associated with the directive.
814   /// \param Exprs Helper expressions for CodeGen.
815   /// \param HasCancel true if current directive has inner cancel directive.
816   ///
817   static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
818                                  SourceLocation EndLoc, unsigned CollapsedNum,
819                                  ArrayRef<OMPClause *> Clauses,
820                                  Stmt *AssociatedStmt, const HelperExprs &Exprs,
821                                  bool HasCancel);
822 
823   /// \brief Creates an empty directive with the place
824   /// for \a NumClauses clauses.
825   ///
826   /// \param C AST context.
827   /// \param CollapsedNum Number of collapsed nested loops.
828   /// \param NumClauses Number of clauses.
829   ///
830   static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
831                                       unsigned CollapsedNum, EmptyShell);
832 
833   /// \brief Return true if current directive has inner cancel directive.
hasCancel()834   bool hasCancel() const { return HasCancel; }
835 
classof(const Stmt * T)836   static bool classof(const Stmt *T) {
837     return T->getStmtClass() == OMPForDirectiveClass;
838   }
839 };
840 
841 /// \brief This represents '#pragma omp for simd' directive.
842 ///
843 /// \code
844 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
845 /// \endcode
846 /// In this example directive '#pragma omp for simd' has clauses 'private'
847 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
848 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
849 ///
850 class OMPForSimdDirective : public OMPLoopDirective {
851   friend class ASTStmtReader;
852   /// \brief Build directive with the given start and end location.
853   ///
854   /// \param StartLoc Starting location of the directive kind.
855   /// \param EndLoc Ending location of the directive.
856   /// \param CollapsedNum Number of collapsed nested loops.
857   /// \param NumClauses Number of clauses.
858   ///
OMPForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)859   OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
860                       unsigned CollapsedNum, unsigned NumClauses)
861       : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
862                          StartLoc, EndLoc, CollapsedNum, NumClauses) {}
863 
864   /// \brief Build an empty directive.
865   ///
866   /// \param CollapsedNum Number of collapsed nested loops.
867   /// \param NumClauses Number of clauses.
868   ///
OMPForSimdDirective(unsigned CollapsedNum,unsigned NumClauses)869   explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
870       : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
871                          SourceLocation(), SourceLocation(), CollapsedNum,
872                          NumClauses) {}
873 
874 public:
875   /// \brief Creates directive with a list of \a Clauses.
876   ///
877   /// \param C AST context.
878   /// \param StartLoc Starting location of the directive kind.
879   /// \param EndLoc Ending Location of the directive.
880   /// \param CollapsedNum Number of collapsed loops.
881   /// \param Clauses List of clauses.
882   /// \param AssociatedStmt Statement, associated with the directive.
883   /// \param Exprs Helper expressions for CodeGen.
884   ///
885   static OMPForSimdDirective *
886   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
887          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
888          Stmt *AssociatedStmt, const HelperExprs &Exprs);
889 
890   /// \brief Creates an empty directive with the place
891   /// for \a NumClauses clauses.
892   ///
893   /// \param C AST context.
894   /// \param CollapsedNum Number of collapsed nested loops.
895   /// \param NumClauses Number of clauses.
896   ///
897   static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
898                                           unsigned NumClauses,
899                                           unsigned CollapsedNum, EmptyShell);
900 
classof(const Stmt * T)901   static bool classof(const Stmt *T) {
902     return T->getStmtClass() == OMPForSimdDirectiveClass;
903   }
904 };
905 
906 /// \brief This represents '#pragma omp sections' directive.
907 ///
908 /// \code
909 /// #pragma omp sections private(a,b) reduction(+:c,d)
910 /// \endcode
911 /// In this example directive '#pragma omp sections' has clauses 'private' with
912 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
913 /// 'c' and 'd'.
914 ///
915 class OMPSectionsDirective : public OMPExecutableDirective {
916   friend class ASTStmtReader;
917 
918   /// \brief true if current directive has inner cancel directive.
919   bool HasCancel;
920 
921   /// \brief Build directive with the given start and end location.
922   ///
923   /// \param StartLoc Starting location of the directive kind.
924   /// \param EndLoc Ending location of the directive.
925   /// \param NumClauses Number of clauses.
926   ///
OMPSectionsDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)927   OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
928                        unsigned NumClauses)
929       : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
930                                StartLoc, EndLoc, NumClauses, 1),
931         HasCancel(false) {}
932 
933   /// \brief Build an empty directive.
934   ///
935   /// \param NumClauses Number of clauses.
936   ///
OMPSectionsDirective(unsigned NumClauses)937   explicit OMPSectionsDirective(unsigned NumClauses)
938       : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
939                                SourceLocation(), SourceLocation(), NumClauses,
940                                1),
941         HasCancel(false) {}
942 
943   /// \brief Set cancel state.
setHasCancel(bool Has)944   void setHasCancel(bool Has) { HasCancel = Has; }
945 
946 public:
947   /// \brief Creates directive with a list of \a Clauses.
948   ///
949   /// \param C AST context.
950   /// \param StartLoc Starting location of the directive kind.
951   /// \param EndLoc Ending Location of the directive.
952   /// \param Clauses List of clauses.
953   /// \param AssociatedStmt Statement, associated with the directive.
954   /// \param HasCancel true if current directive has inner directive.
955   ///
956   static OMPSectionsDirective *
957   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
958          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
959 
960   /// \brief Creates an empty directive with the place for \a NumClauses
961   /// clauses.
962   ///
963   /// \param C AST context.
964   /// \param NumClauses Number of clauses.
965   ///
966   static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
967                                            unsigned NumClauses, EmptyShell);
968 
969   /// \brief Return true if current directive has inner cancel directive.
hasCancel()970   bool hasCancel() const { return HasCancel; }
971 
classof(const Stmt * T)972   static bool classof(const Stmt *T) {
973     return T->getStmtClass() == OMPSectionsDirectiveClass;
974   }
975 };
976 
977 /// \brief This represents '#pragma omp section' directive.
978 ///
979 /// \code
980 /// #pragma omp section
981 /// \endcode
982 ///
983 class OMPSectionDirective : public OMPExecutableDirective {
984   friend class ASTStmtReader;
985 
986   /// \brief true if current directive has inner cancel directive.
987   bool HasCancel;
988 
989   /// \brief Build directive with the given start and end location.
990   ///
991   /// \param StartLoc Starting location of the directive kind.
992   /// \param EndLoc Ending location of the directive.
993   ///
OMPSectionDirective(SourceLocation StartLoc,SourceLocation EndLoc)994   OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
995       : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
996                                StartLoc, EndLoc, 0, 1),
997         HasCancel(false) {}
998 
999   /// \brief Build an empty directive.
1000   ///
OMPSectionDirective()1001   explicit OMPSectionDirective()
1002       : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
1003                                SourceLocation(), SourceLocation(), 0, 1),
1004         HasCancel(false) {}
1005 
1006 public:
1007   /// \brief Creates directive.
1008   ///
1009   /// \param C AST context.
1010   /// \param StartLoc Starting location of the directive kind.
1011   /// \param EndLoc Ending Location of the directive.
1012   /// \param AssociatedStmt Statement, associated with the directive.
1013   /// \param HasCancel true if current directive has inner directive.
1014   ///
1015   static OMPSectionDirective *Create(const ASTContext &C,
1016                                      SourceLocation StartLoc,
1017                                      SourceLocation EndLoc,
1018                                      Stmt *AssociatedStmt, bool HasCancel);
1019 
1020   /// \brief Creates an empty directive.
1021   ///
1022   /// \param C AST context.
1023   ///
1024   static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1025 
1026   /// \brief Set cancel state.
setHasCancel(bool Has)1027   void setHasCancel(bool Has) { HasCancel = Has; }
1028 
1029   /// \brief Return true if current directive has inner cancel directive.
hasCancel()1030   bool hasCancel() const { return HasCancel; }
1031 
classof(const Stmt * T)1032   static bool classof(const Stmt *T) {
1033     return T->getStmtClass() == OMPSectionDirectiveClass;
1034   }
1035 };
1036 
1037 /// \brief This represents '#pragma omp single' directive.
1038 ///
1039 /// \code
1040 /// #pragma omp single private(a,b) copyprivate(c,d)
1041 /// \endcode
1042 /// In this example directive '#pragma omp single' has clauses 'private' with
1043 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
1044 ///
1045 class OMPSingleDirective : public OMPExecutableDirective {
1046   friend class ASTStmtReader;
1047   /// \brief Build directive with the given start and end location.
1048   ///
1049   /// \param StartLoc Starting location of the directive kind.
1050   /// \param EndLoc Ending location of the directive.
1051   /// \param NumClauses Number of clauses.
1052   ///
OMPSingleDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1053   OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1054                      unsigned NumClauses)
1055       : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
1056                                StartLoc, EndLoc, NumClauses, 1) {}
1057 
1058   /// \brief Build an empty directive.
1059   ///
1060   /// \param NumClauses Number of clauses.
1061   ///
OMPSingleDirective(unsigned NumClauses)1062   explicit OMPSingleDirective(unsigned NumClauses)
1063       : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
1064                                SourceLocation(), SourceLocation(), NumClauses,
1065                                1) {}
1066 
1067 public:
1068   /// \brief Creates directive with a list of \a Clauses.
1069   ///
1070   /// \param C AST context.
1071   /// \param StartLoc Starting location of the directive kind.
1072   /// \param EndLoc Ending Location of the directive.
1073   /// \param Clauses List of clauses.
1074   /// \param AssociatedStmt Statement, associated with the directive.
1075   ///
1076   static OMPSingleDirective *
1077   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1078          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1079 
1080   /// \brief Creates an empty directive with the place for \a NumClauses
1081   /// clauses.
1082   ///
1083   /// \param C AST context.
1084   /// \param NumClauses Number of clauses.
1085   ///
1086   static OMPSingleDirective *CreateEmpty(const ASTContext &C,
1087                                          unsigned NumClauses, EmptyShell);
1088 
classof(const Stmt * T)1089   static bool classof(const Stmt *T) {
1090     return T->getStmtClass() == OMPSingleDirectiveClass;
1091   }
1092 };
1093 
1094 /// \brief This represents '#pragma omp master' directive.
1095 ///
1096 /// \code
1097 /// #pragma omp master
1098 /// \endcode
1099 ///
1100 class OMPMasterDirective : public OMPExecutableDirective {
1101   friend class ASTStmtReader;
1102   /// \brief Build directive with the given start and end location.
1103   ///
1104   /// \param StartLoc Starting location of the directive kind.
1105   /// \param EndLoc Ending location of the directive.
1106   ///
OMPMasterDirective(SourceLocation StartLoc,SourceLocation EndLoc)1107   OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1108       : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
1109                                StartLoc, EndLoc, 0, 1) {}
1110 
1111   /// \brief Build an empty directive.
1112   ///
OMPMasterDirective()1113   explicit OMPMasterDirective()
1114       : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
1115                                SourceLocation(), SourceLocation(), 0, 1) {}
1116 
1117 public:
1118   /// \brief Creates directive.
1119   ///
1120   /// \param C AST context.
1121   /// \param StartLoc Starting location of the directive kind.
1122   /// \param EndLoc Ending Location of the directive.
1123   /// \param AssociatedStmt Statement, associated with the directive.
1124   ///
1125   static OMPMasterDirective *Create(const ASTContext &C,
1126                                     SourceLocation StartLoc,
1127                                     SourceLocation EndLoc,
1128                                     Stmt *AssociatedStmt);
1129 
1130   /// \brief Creates an empty directive.
1131   ///
1132   /// \param C AST context.
1133   ///
1134   static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1135 
classof(const Stmt * T)1136   static bool classof(const Stmt *T) {
1137     return T->getStmtClass() == OMPMasterDirectiveClass;
1138   }
1139 };
1140 
1141 /// \brief This represents '#pragma omp critical' directive.
1142 ///
1143 /// \code
1144 /// #pragma omp critical
1145 /// \endcode
1146 ///
1147 class OMPCriticalDirective : public OMPExecutableDirective {
1148   friend class ASTStmtReader;
1149   /// \brief Name of the directive.
1150   DeclarationNameInfo DirName;
1151   /// \brief Build directive with the given start and end location.
1152   ///
1153   /// \param Name Name of the directive.
1154   /// \param StartLoc Starting location of the directive kind.
1155   /// \param EndLoc Ending location of the directive.
1156   /// \param NumClauses Number of clauses.
1157   ///
OMPCriticalDirective(const DeclarationNameInfo & Name,SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1158   OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
1159                        SourceLocation EndLoc, unsigned NumClauses)
1160       : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
1161                                StartLoc, EndLoc, NumClauses, 1),
1162         DirName(Name) {}
1163 
1164   /// \brief Build an empty directive.
1165   ///
1166   /// \param NumClauses Number of clauses.
1167   ///
OMPCriticalDirective(unsigned NumClauses)1168   explicit OMPCriticalDirective(unsigned NumClauses)
1169       : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
1170                                SourceLocation(), SourceLocation(), NumClauses,
1171                                1),
1172         DirName() {}
1173 
1174   /// \brief Set name of the directive.
1175   ///
1176   /// \param Name Name of the directive.
1177   ///
setDirectiveName(const DeclarationNameInfo & Name)1178   void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
1179 
1180 public:
1181   /// \brief Creates directive.
1182   ///
1183   /// \param C AST context.
1184   /// \param Name Name of the directive.
1185   /// \param StartLoc Starting location of the directive kind.
1186   /// \param EndLoc Ending Location of the directive.
1187   /// \param Clauses List of clauses.
1188   /// \param AssociatedStmt Statement, associated with the directive.
1189   ///
1190   static OMPCriticalDirective *
1191   Create(const ASTContext &C, const DeclarationNameInfo &Name,
1192          SourceLocation StartLoc, SourceLocation EndLoc,
1193          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1194 
1195   /// \brief Creates an empty directive.
1196   ///
1197   /// \param C AST context.
1198   /// \param NumClauses Number of clauses.
1199   ///
1200   static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
1201                                            unsigned NumClauses, EmptyShell);
1202 
1203   /// \brief Return name of the directive.
1204   ///
getDirectiveName()1205   DeclarationNameInfo getDirectiveName() const { return DirName; }
1206 
classof(const Stmt * T)1207   static bool classof(const Stmt *T) {
1208     return T->getStmtClass() == OMPCriticalDirectiveClass;
1209   }
1210 };
1211 
1212 /// \brief This represents '#pragma omp parallel for' directive.
1213 ///
1214 /// \code
1215 /// #pragma omp parallel for private(a,b) reduction(+:c,d)
1216 /// \endcode
1217 /// In this example directive '#pragma omp parallel for' has clauses 'private'
1218 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
1219 /// variables 'c' and 'd'.
1220 ///
1221 class OMPParallelForDirective : public OMPLoopDirective {
1222   friend class ASTStmtReader;
1223 
1224   /// \brief true if current region has inner cancel directive.
1225   bool HasCancel;
1226 
1227   /// \brief Build directive with the given start and end location.
1228   ///
1229   /// \param StartLoc Starting location of the directive kind.
1230   /// \param EndLoc Ending location of the directive.
1231   /// \param CollapsedNum Number of collapsed nested loops.
1232   /// \param NumClauses Number of clauses.
1233   ///
OMPParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)1234   OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1235                           unsigned CollapsedNum, unsigned NumClauses)
1236       : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
1237                          StartLoc, EndLoc, CollapsedNum, NumClauses),
1238         HasCancel(false) {}
1239 
1240   /// \brief Build an empty directive.
1241   ///
1242   /// \param CollapsedNum Number of collapsed nested loops.
1243   /// \param NumClauses Number of clauses.
1244   ///
OMPParallelForDirective(unsigned CollapsedNum,unsigned NumClauses)1245   explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
1246       : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
1247                          SourceLocation(), SourceLocation(), CollapsedNum,
1248                          NumClauses),
1249         HasCancel(false) {}
1250 
1251   /// \brief Set cancel state.
setHasCancel(bool Has)1252   void setHasCancel(bool Has) { HasCancel = Has; }
1253 
1254 public:
1255   /// \brief Creates directive with a list of \a Clauses.
1256   ///
1257   /// \param C AST context.
1258   /// \param StartLoc Starting location of the directive kind.
1259   /// \param EndLoc Ending Location of the directive.
1260   /// \param CollapsedNum Number of collapsed loops.
1261   /// \param Clauses List of clauses.
1262   /// \param AssociatedStmt Statement, associated with the directive.
1263   /// \param Exprs Helper expressions for CodeGen.
1264   /// \param HasCancel true if current directive has inner cancel directive.
1265   ///
1266   static OMPParallelForDirective *
1267   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1268          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1269          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
1270 
1271   /// \brief Creates an empty directive with the place
1272   /// for \a NumClauses clauses.
1273   ///
1274   /// \param C AST context.
1275   /// \param CollapsedNum Number of collapsed nested loops.
1276   /// \param NumClauses Number of clauses.
1277   ///
1278   static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
1279                                               unsigned NumClauses,
1280                                               unsigned CollapsedNum,
1281                                               EmptyShell);
1282 
1283   /// \brief Return true if current directive has inner cancel directive.
hasCancel()1284   bool hasCancel() const { return HasCancel; }
1285 
classof(const Stmt * T)1286   static bool classof(const Stmt *T) {
1287     return T->getStmtClass() == OMPParallelForDirectiveClass;
1288   }
1289 };
1290 
1291 /// \brief This represents '#pragma omp parallel for simd' directive.
1292 ///
1293 /// \code
1294 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
1295 /// \endcode
1296 /// In this example directive '#pragma omp parallel for simd' has clauses
1297 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
1298 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and
1299 /// 'd'.
1300 ///
1301 class OMPParallelForSimdDirective : public OMPLoopDirective {
1302   friend class ASTStmtReader;
1303   /// \brief Build directive with the given start and end location.
1304   ///
1305   /// \param StartLoc Starting location of the directive kind.
1306   /// \param EndLoc Ending location of the directive.
1307   /// \param CollapsedNum Number of collapsed nested loops.
1308   /// \param NumClauses Number of clauses.
1309   ///
OMPParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)1310   OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1311                               unsigned CollapsedNum, unsigned NumClauses)
1312       : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
1313                          OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum,
1314                          NumClauses) {}
1315 
1316   /// \brief Build an empty directive.
1317   ///
1318   /// \param CollapsedNum Number of collapsed nested loops.
1319   /// \param NumClauses Number of clauses.
1320   ///
OMPParallelForSimdDirective(unsigned CollapsedNum,unsigned NumClauses)1321   explicit OMPParallelForSimdDirective(unsigned CollapsedNum,
1322                                        unsigned NumClauses)
1323       : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
1324                          OMPD_parallel_for_simd, SourceLocation(),
1325                          SourceLocation(), CollapsedNum, NumClauses) {}
1326 
1327 public:
1328   /// \brief Creates directive with a list of \a Clauses.
1329   ///
1330   /// \param C AST context.
1331   /// \param StartLoc Starting location of the directive kind.
1332   /// \param EndLoc Ending Location of the directive.
1333   /// \param CollapsedNum Number of collapsed loops.
1334   /// \param Clauses List of clauses.
1335   /// \param AssociatedStmt Statement, associated with the directive.
1336   /// \param Exprs Helper expressions for CodeGen.
1337   ///
1338   static OMPParallelForSimdDirective *
1339   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1340          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1341          Stmt *AssociatedStmt, const HelperExprs &Exprs);
1342 
1343   /// \brief Creates an empty directive with the place
1344   /// for \a NumClauses clauses.
1345   ///
1346   /// \param C AST context.
1347   /// \param CollapsedNum Number of collapsed nested loops.
1348   /// \param NumClauses Number of clauses.
1349   ///
1350   static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
1351                                                   unsigned NumClauses,
1352                                                   unsigned CollapsedNum,
1353                                                   EmptyShell);
1354 
classof(const Stmt * T)1355   static bool classof(const Stmt *T) {
1356     return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
1357   }
1358 };
1359 
1360 /// \brief This represents '#pragma omp parallel sections' directive.
1361 ///
1362 /// \code
1363 /// #pragma omp parallel sections private(a,b) reduction(+:c,d)
1364 /// \endcode
1365 /// In this example directive '#pragma omp parallel sections' has clauses
1366 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
1367 /// and variables 'c' and 'd'.
1368 ///
1369 class OMPParallelSectionsDirective : public OMPExecutableDirective {
1370   friend class ASTStmtReader;
1371 
1372   /// \brief true if current directive has inner cancel directive.
1373   bool HasCancel;
1374 
1375   /// \brief Build directive with the given start and end location.
1376   ///
1377   /// \param StartLoc Starting location of the directive kind.
1378   /// \param EndLoc Ending location of the directive.
1379   /// \param NumClauses Number of clauses.
1380   ///
OMPParallelSectionsDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1381   OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1382                                unsigned NumClauses)
1383       : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
1384                                OMPD_parallel_sections, StartLoc, EndLoc,
1385                                NumClauses, 1),
1386         HasCancel(false) {}
1387 
1388   /// \brief Build an empty directive.
1389   ///
1390   /// \param NumClauses Number of clauses.
1391   ///
OMPParallelSectionsDirective(unsigned NumClauses)1392   explicit OMPParallelSectionsDirective(unsigned NumClauses)
1393       : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
1394                                OMPD_parallel_sections, SourceLocation(),
1395                                SourceLocation(), NumClauses, 1),
1396         HasCancel(false) {}
1397 
1398   /// \brief Set cancel state.
setHasCancel(bool Has)1399   void setHasCancel(bool Has) { HasCancel = Has; }
1400 
1401 public:
1402   /// \brief Creates directive with a list of \a Clauses.
1403   ///
1404   /// \param C AST context.
1405   /// \param StartLoc Starting location of the directive kind.
1406   /// \param EndLoc Ending Location of the directive.
1407   /// \param Clauses List of clauses.
1408   /// \param AssociatedStmt Statement, associated with the directive.
1409   /// \param HasCancel true if current directive has inner cancel directive.
1410   ///
1411   static OMPParallelSectionsDirective *
1412   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1413          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
1414 
1415   /// \brief Creates an empty directive with the place for \a NumClauses
1416   /// clauses.
1417   ///
1418   /// \param C AST context.
1419   /// \param NumClauses Number of clauses.
1420   ///
1421   static OMPParallelSectionsDirective *
1422   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
1423 
1424   /// \brief Return true if current directive has inner cancel directive.
hasCancel()1425   bool hasCancel() const { return HasCancel; }
1426 
classof(const Stmt * T)1427   static bool classof(const Stmt *T) {
1428     return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
1429   }
1430 };
1431 
1432 /// \brief This represents '#pragma omp task' directive.
1433 ///
1434 /// \code
1435 /// #pragma omp task private(a,b) final(d)
1436 /// \endcode
1437 /// In this example directive '#pragma omp task' has clauses 'private' with the
1438 /// variables 'a' and 'b' and 'final' with condition 'd'.
1439 ///
1440 class OMPTaskDirective : public OMPExecutableDirective {
1441   friend class ASTStmtReader;
1442   /// \brief true if this directive has inner cancel directive.
1443   bool HasCancel;
1444 
1445   /// \brief Build directive with the given start and end location.
1446   ///
1447   /// \param StartLoc Starting location of the directive kind.
1448   /// \param EndLoc Ending location of the directive.
1449   /// \param NumClauses Number of clauses.
1450   ///
OMPTaskDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1451   OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1452                    unsigned NumClauses)
1453       : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
1454                                EndLoc, NumClauses, 1),
1455         HasCancel(false) {}
1456 
1457   /// \brief Build an empty directive.
1458   ///
1459   /// \param NumClauses Number of clauses.
1460   ///
OMPTaskDirective(unsigned NumClauses)1461   explicit OMPTaskDirective(unsigned NumClauses)
1462       : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
1463                                SourceLocation(), SourceLocation(), NumClauses,
1464                                1),
1465         HasCancel(false) {}
1466 
1467   /// \brief Set cancel state.
setHasCancel(bool Has)1468   void setHasCancel(bool Has) { HasCancel = Has; }
1469 
1470 public:
1471   /// \brief Creates directive with a list of \a Clauses.
1472   ///
1473   /// \param C AST context.
1474   /// \param StartLoc Starting location of the directive kind.
1475   /// \param EndLoc Ending Location of the directive.
1476   /// \param Clauses List of clauses.
1477   /// \param AssociatedStmt Statement, associated with the directive.
1478   /// \param HasCancel true, if current directive has inner cancel directive.
1479   ///
1480   static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1481                                   SourceLocation EndLoc,
1482                                   ArrayRef<OMPClause *> Clauses,
1483                                   Stmt *AssociatedStmt, bool HasCancel);
1484 
1485   /// \brief Creates an empty directive with the place for \a NumClauses
1486   /// clauses.
1487   ///
1488   /// \param C AST context.
1489   /// \param NumClauses Number of clauses.
1490   ///
1491   static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1492                                        EmptyShell);
1493 
1494   /// \brief Return true if current directive has inner cancel directive.
hasCancel()1495   bool hasCancel() const { return HasCancel; }
1496 
classof(const Stmt * T)1497   static bool classof(const Stmt *T) {
1498     return T->getStmtClass() == OMPTaskDirectiveClass;
1499   }
1500 };
1501 
1502 /// \brief This represents '#pragma omp taskyield' directive.
1503 ///
1504 /// \code
1505 /// #pragma omp taskyield
1506 /// \endcode
1507 ///
1508 class OMPTaskyieldDirective : public OMPExecutableDirective {
1509   friend class ASTStmtReader;
1510   /// \brief Build directive with the given start and end location.
1511   ///
1512   /// \param StartLoc Starting location of the directive kind.
1513   /// \param EndLoc Ending location of the directive.
1514   ///
OMPTaskyieldDirective(SourceLocation StartLoc,SourceLocation EndLoc)1515   OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1516       : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
1517                                StartLoc, EndLoc, 0, 0) {}
1518 
1519   /// \brief Build an empty directive.
1520   ///
OMPTaskyieldDirective()1521   explicit OMPTaskyieldDirective()
1522       : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
1523                                SourceLocation(), SourceLocation(), 0, 0) {}
1524 
1525 public:
1526   /// \brief Creates directive.
1527   ///
1528   /// \param C AST context.
1529   /// \param StartLoc Starting location of the directive kind.
1530   /// \param EndLoc Ending Location of the directive.
1531   ///
1532   static OMPTaskyieldDirective *
1533   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1534 
1535   /// \brief Creates an empty directive.
1536   ///
1537   /// \param C AST context.
1538   ///
1539   static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1540 
classof(const Stmt * T)1541   static bool classof(const Stmt *T) {
1542     return T->getStmtClass() == OMPTaskyieldDirectiveClass;
1543   }
1544 };
1545 
1546 /// \brief This represents '#pragma omp barrier' directive.
1547 ///
1548 /// \code
1549 /// #pragma omp barrier
1550 /// \endcode
1551 ///
1552 class OMPBarrierDirective : public OMPExecutableDirective {
1553   friend class ASTStmtReader;
1554   /// \brief Build directive with the given start and end location.
1555   ///
1556   /// \param StartLoc Starting location of the directive kind.
1557   /// \param EndLoc Ending location of the directive.
1558   ///
OMPBarrierDirective(SourceLocation StartLoc,SourceLocation EndLoc)1559   OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1560       : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
1561                                StartLoc, EndLoc, 0, 0) {}
1562 
1563   /// \brief Build an empty directive.
1564   ///
OMPBarrierDirective()1565   explicit OMPBarrierDirective()
1566       : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
1567                                SourceLocation(), SourceLocation(), 0, 0) {}
1568 
1569 public:
1570   /// \brief Creates directive.
1571   ///
1572   /// \param C AST context.
1573   /// \param StartLoc Starting location of the directive kind.
1574   /// \param EndLoc Ending Location of the directive.
1575   ///
1576   static OMPBarrierDirective *
1577   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1578 
1579   /// \brief Creates an empty directive.
1580   ///
1581   /// \param C AST context.
1582   ///
1583   static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1584 
classof(const Stmt * T)1585   static bool classof(const Stmt *T) {
1586     return T->getStmtClass() == OMPBarrierDirectiveClass;
1587   }
1588 };
1589 
1590 /// \brief This represents '#pragma omp taskwait' directive.
1591 ///
1592 /// \code
1593 /// #pragma omp taskwait
1594 /// \endcode
1595 ///
1596 class OMPTaskwaitDirective : public OMPExecutableDirective {
1597   friend class ASTStmtReader;
1598   /// \brief Build directive with the given start and end location.
1599   ///
1600   /// \param StartLoc Starting location of the directive kind.
1601   /// \param EndLoc Ending location of the directive.
1602   ///
OMPTaskwaitDirective(SourceLocation StartLoc,SourceLocation EndLoc)1603   OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1604       : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
1605                                StartLoc, EndLoc, 0, 0) {}
1606 
1607   /// \brief Build an empty directive.
1608   ///
OMPTaskwaitDirective()1609   explicit OMPTaskwaitDirective()
1610       : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
1611                                SourceLocation(), SourceLocation(), 0, 0) {}
1612 
1613 public:
1614   /// \brief Creates directive.
1615   ///
1616   /// \param C AST context.
1617   /// \param StartLoc Starting location of the directive kind.
1618   /// \param EndLoc Ending Location of the directive.
1619   ///
1620   static OMPTaskwaitDirective *
1621   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1622 
1623   /// \brief Creates an empty directive.
1624   ///
1625   /// \param C AST context.
1626   ///
1627   static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1628 
classof(const Stmt * T)1629   static bool classof(const Stmt *T) {
1630     return T->getStmtClass() == OMPTaskwaitDirectiveClass;
1631   }
1632 };
1633 
1634 /// \brief This represents '#pragma omp taskgroup' directive.
1635 ///
1636 /// \code
1637 /// #pragma omp taskgroup
1638 /// \endcode
1639 ///
1640 class OMPTaskgroupDirective : public OMPExecutableDirective {
1641   friend class ASTStmtReader;
1642   /// \brief Build directive with the given start and end location.
1643   ///
1644   /// \param StartLoc Starting location of the directive kind.
1645   /// \param EndLoc Ending location of the directive.
1646   ///
OMPTaskgroupDirective(SourceLocation StartLoc,SourceLocation EndLoc)1647   OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1648       : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
1649                                StartLoc, EndLoc, 0, 1) {}
1650 
1651   /// \brief Build an empty directive.
1652   ///
OMPTaskgroupDirective()1653   explicit OMPTaskgroupDirective()
1654       : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
1655                                SourceLocation(), SourceLocation(), 0, 1) {}
1656 
1657 public:
1658   /// \brief Creates directive.
1659   ///
1660   /// \param C AST context.
1661   /// \param StartLoc Starting location of the directive kind.
1662   /// \param EndLoc Ending Location of the directive.
1663   /// \param AssociatedStmt Statement, associated with the directive.
1664   ///
1665   static OMPTaskgroupDirective *Create(const ASTContext &C,
1666                                        SourceLocation StartLoc,
1667                                        SourceLocation EndLoc,
1668                                        Stmt *AssociatedStmt);
1669 
1670   /// \brief Creates an empty directive.
1671   ///
1672   /// \param C AST context.
1673   ///
1674   static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1675 
classof(const Stmt * T)1676   static bool classof(const Stmt *T) {
1677     return T->getStmtClass() == OMPTaskgroupDirectiveClass;
1678   }
1679 };
1680 
1681 /// \brief This represents '#pragma omp flush' directive.
1682 ///
1683 /// \code
1684 /// #pragma omp flush(a,b)
1685 /// \endcode
1686 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
1687 /// and 'b'.
1688 /// 'omp flush' directive does not have clauses but have an optional list of
1689 /// variables to flush. This list of variables is stored within some fake clause
1690 /// FlushClause.
1691 class OMPFlushDirective : public OMPExecutableDirective {
1692   friend class ASTStmtReader;
1693   /// \brief Build directive with the given start and end location.
1694   ///
1695   /// \param StartLoc Starting location of the directive kind.
1696   /// \param EndLoc Ending location of the directive.
1697   /// \param NumClauses Number of clauses.
1698   ///
OMPFlushDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1699   OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1700                     unsigned NumClauses)
1701       : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
1702                                StartLoc, EndLoc, NumClauses, 0) {}
1703 
1704   /// \brief Build an empty directive.
1705   ///
1706   /// \param NumClauses Number of clauses.
1707   ///
OMPFlushDirective(unsigned NumClauses)1708   explicit OMPFlushDirective(unsigned NumClauses)
1709       : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
1710                                SourceLocation(), SourceLocation(), NumClauses,
1711                                0) {}
1712 
1713 public:
1714   /// \brief Creates directive with a list of \a Clauses.
1715   ///
1716   /// \param C AST context.
1717   /// \param StartLoc Starting location of the directive kind.
1718   /// \param EndLoc Ending Location of the directive.
1719   /// \param Clauses List of clauses (only single OMPFlushClause clause is
1720   /// allowed).
1721   ///
1722   static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1723                                    SourceLocation EndLoc,
1724                                    ArrayRef<OMPClause *> Clauses);
1725 
1726   /// \brief Creates an empty directive with the place for \a NumClauses
1727   /// clauses.
1728   ///
1729   /// \param C AST context.
1730   /// \param NumClauses Number of clauses.
1731   ///
1732   static OMPFlushDirective *CreateEmpty(const ASTContext &C,
1733                                         unsigned NumClauses, EmptyShell);
1734 
classof(const Stmt * T)1735   static bool classof(const Stmt *T) {
1736     return T->getStmtClass() == OMPFlushDirectiveClass;
1737   }
1738 };
1739 
1740 /// \brief This represents '#pragma omp ordered' directive.
1741 ///
1742 /// \code
1743 /// #pragma omp ordered
1744 /// \endcode
1745 ///
1746 class OMPOrderedDirective : public OMPExecutableDirective {
1747   friend class ASTStmtReader;
1748   /// \brief Build directive with the given start and end location.
1749   ///
1750   /// \param StartLoc Starting location of the directive kind.
1751   /// \param EndLoc Ending location of the directive.
1752   /// \param NumClauses Number of clauses.
1753   ///
OMPOrderedDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1754   OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1755                       unsigned NumClauses)
1756       : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
1757                                StartLoc, EndLoc, NumClauses, 1) {}
1758 
1759   /// \brief Build an empty directive.
1760   ///
1761   /// \param NumClauses Number of clauses.
1762   ///
OMPOrderedDirective(unsigned NumClauses)1763   explicit OMPOrderedDirective(unsigned NumClauses)
1764       : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
1765                                SourceLocation(), SourceLocation(), NumClauses,
1766                                1) {}
1767 
1768 public:
1769   /// \brief Creates directive.
1770   ///
1771   /// \param C AST context.
1772   /// \param StartLoc Starting location of the directive kind.
1773   /// \param EndLoc Ending Location of the directive.
1774   /// \param Clauses List of clauses.
1775   /// \param AssociatedStmt Statement, associated with the directive.
1776   ///
1777   static OMPOrderedDirective *
1778   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1779          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1780 
1781   /// \brief Creates an empty directive.
1782   ///
1783   /// \param C AST context.
1784   /// \param NumClauses Number of clauses.
1785   ///
1786   static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
1787                                           unsigned NumClauses, EmptyShell);
1788 
classof(const Stmt * T)1789   static bool classof(const Stmt *T) {
1790     return T->getStmtClass() == OMPOrderedDirectiveClass;
1791   }
1792 };
1793 
1794 /// \brief This represents '#pragma omp atomic' directive.
1795 ///
1796 /// \code
1797 /// #pragma omp atomic capture
1798 /// \endcode
1799 /// In this example directive '#pragma omp atomic' has clause 'capture'.
1800 ///
1801 class OMPAtomicDirective : public OMPExecutableDirective {
1802   friend class ASTStmtReader;
1803   /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
1804   /// have atomic expressions of forms
1805   /// \code
1806   /// x = x binop expr;
1807   /// x = expr binop x;
1808   /// \endcode
1809   /// This field is true for the first form of the expression and false for the
1810   /// second. Required for correct codegen of non-associative operations (like
1811   /// << or >>).
1812   bool IsXLHSInRHSPart;
1813   /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
1814   /// have atomic expressions of forms
1815   /// \code
1816   /// v = x; <update x>;
1817   /// <update x>; v = x;
1818   /// \endcode
1819   /// This field is true for the first(postfix) form of the expression and false
1820   /// otherwise.
1821   bool IsPostfixUpdate;
1822 
1823   /// \brief Build directive with the given start and end location.
1824   ///
1825   /// \param StartLoc Starting location of the directive kind.
1826   /// \param EndLoc Ending location of the directive.
1827   /// \param NumClauses Number of clauses.
1828   ///
OMPAtomicDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1829   OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1830                      unsigned NumClauses)
1831       : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
1832                                StartLoc, EndLoc, NumClauses, 5),
1833         IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
1834 
1835   /// \brief Build an empty directive.
1836   ///
1837   /// \param NumClauses Number of clauses.
1838   ///
OMPAtomicDirective(unsigned NumClauses)1839   explicit OMPAtomicDirective(unsigned NumClauses)
1840       : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
1841                                SourceLocation(), SourceLocation(), NumClauses,
1842                                5),
1843         IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
1844 
1845   /// \brief Set 'x' part of the associated expression/statement.
setX(Expr * X)1846   void setX(Expr *X) { *std::next(child_begin()) = X; }
1847   /// \brief Set helper expression of the form
1848   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1849   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
setUpdateExpr(Expr * UE)1850   void setUpdateExpr(Expr *UE) { *std::next(child_begin(), 2) = UE; }
1851   /// \brief Set 'v' part of the associated expression/statement.
setV(Expr * V)1852   void setV(Expr *V) { *std::next(child_begin(), 3) = V; }
1853   /// \brief Set 'expr' part of the associated expression/statement.
setExpr(Expr * E)1854   void setExpr(Expr *E) { *std::next(child_begin(), 4) = E; }
1855 
1856 public:
1857   /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
1858   /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
1859   /// detailed description of 'x', 'v' and 'expr').
1860   ///
1861   /// \param C AST context.
1862   /// \param StartLoc Starting location of the directive kind.
1863   /// \param EndLoc Ending Location of the directive.
1864   /// \param Clauses List of clauses.
1865   /// \param AssociatedStmt Statement, associated with the directive.
1866   /// \param X 'x' part of the associated expression/statement.
1867   /// \param V 'v' part of the associated expression/statement.
1868   /// \param E 'expr' part of the associated expression/statement.
1869   /// \param UE Helper expression of the form
1870   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1871   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1872   /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the
1873   /// second.
1874   /// \param IsPostfixUpdate true if original value of 'x' must be stored in
1875   /// 'v', not an updated one.
1876   static OMPAtomicDirective *
1877   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1878          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
1879          Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate);
1880 
1881   /// \brief Creates an empty directive with the place for \a NumClauses
1882   /// clauses.
1883   ///
1884   /// \param C AST context.
1885   /// \param NumClauses Number of clauses.
1886   ///
1887   static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
1888                                          unsigned NumClauses, EmptyShell);
1889 
1890   /// \brief Get 'x' part of the associated expression/statement.
getX()1891   Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); }
getX()1892   const Expr *getX() const {
1893     return cast_or_null<Expr>(*std::next(child_begin()));
1894   }
1895   /// \brief Get helper expression of the form
1896   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1897   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
getUpdateExpr()1898   Expr *getUpdateExpr() {
1899     return cast_or_null<Expr>(*std::next(child_begin(), 2));
1900   }
getUpdateExpr()1901   const Expr *getUpdateExpr() const {
1902     return cast_or_null<Expr>(*std::next(child_begin(), 2));
1903   }
1904   /// \brief Return true if helper update expression has form
1905   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
1906   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
isXLHSInRHSPart()1907   bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
1908   /// \brief Return true if 'v' expression must be updated to original value of
1909   /// 'x', false if 'v' must be updated to the new value of 'x'.
isPostfixUpdate()1910   bool isPostfixUpdate() const { return IsPostfixUpdate; }
1911   /// \brief Get 'v' part of the associated expression/statement.
getV()1912   Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); }
getV()1913   const Expr *getV() const {
1914     return cast_or_null<Expr>(*std::next(child_begin(), 3));
1915   }
1916   /// \brief Get 'expr' part of the associated expression/statement.
getExpr()1917   Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 4)); }
getExpr()1918   const Expr *getExpr() const {
1919     return cast_or_null<Expr>(*std::next(child_begin(), 4));
1920   }
1921 
classof(const Stmt * T)1922   static bool classof(const Stmt *T) {
1923     return T->getStmtClass() == OMPAtomicDirectiveClass;
1924   }
1925 };
1926 
1927 /// \brief This represents '#pragma omp target' directive.
1928 ///
1929 /// \code
1930 /// #pragma omp target if(a)
1931 /// \endcode
1932 /// In this example directive '#pragma omp target' has clause 'if' with
1933 /// condition 'a'.
1934 ///
1935 class OMPTargetDirective : public OMPExecutableDirective {
1936   friend class ASTStmtReader;
1937   /// \brief Build directive with the given start and end location.
1938   ///
1939   /// \param StartLoc Starting location of the directive kind.
1940   /// \param EndLoc Ending location of the directive.
1941   /// \param NumClauses Number of clauses.
1942   ///
OMPTargetDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1943   OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1944                      unsigned NumClauses)
1945       : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
1946                                StartLoc, EndLoc, NumClauses, 1) {}
1947 
1948   /// \brief Build an empty directive.
1949   ///
1950   /// \param NumClauses Number of clauses.
1951   ///
OMPTargetDirective(unsigned NumClauses)1952   explicit OMPTargetDirective(unsigned NumClauses)
1953       : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
1954                                SourceLocation(), SourceLocation(), NumClauses,
1955                                1) {}
1956 
1957 public:
1958   /// \brief Creates directive with a list of \a Clauses.
1959   ///
1960   /// \param C AST context.
1961   /// \param StartLoc Starting location of the directive kind.
1962   /// \param EndLoc Ending Location of the directive.
1963   /// \param Clauses List of clauses.
1964   /// \param AssociatedStmt Statement, associated with the directive.
1965   ///
1966   static OMPTargetDirective *
1967   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1968          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1969 
1970   /// \brief Creates an empty directive with the place for \a NumClauses
1971   /// clauses.
1972   ///
1973   /// \param C AST context.
1974   /// \param NumClauses Number of clauses.
1975   ///
1976   static OMPTargetDirective *CreateEmpty(const ASTContext &C,
1977                                          unsigned NumClauses, EmptyShell);
1978 
classof(const Stmt * T)1979   static bool classof(const Stmt *T) {
1980     return T->getStmtClass() == OMPTargetDirectiveClass;
1981   }
1982 };
1983 
1984 /// \brief This represents '#pragma omp target data' directive.
1985 ///
1986 /// \code
1987 /// #pragma omp target data device(0) if(a) map(b[:])
1988 /// \endcode
1989 /// In this example directive '#pragma omp target data' has clauses 'device'
1990 /// with the value '0', 'if' with condition 'a' and 'map' with array
1991 /// section 'b[:]'.
1992 ///
1993 class OMPTargetDataDirective : public OMPExecutableDirective {
1994   friend class ASTStmtReader;
1995   /// \brief Build directive with the given start and end location.
1996   ///
1997   /// \param StartLoc Starting location of the directive kind.
1998   /// \param EndLoc Ending Location of the directive.
1999   /// \param NumClauses The number of clauses.
2000   ///
OMPTargetDataDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)2001   OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2002                          unsigned NumClauses)
2003       : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
2004                                OMPD_target_data, StartLoc, EndLoc, NumClauses,
2005                                1) {}
2006 
2007   /// \brief Build an empty directive.
2008   ///
2009   /// \param NumClauses Number of clauses.
2010   ///
OMPTargetDataDirective(unsigned NumClauses)2011   explicit OMPTargetDataDirective(unsigned NumClauses)
2012       : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
2013                                OMPD_target_data, SourceLocation(),
2014                                SourceLocation(), NumClauses, 1) {}
2015 
2016 public:
2017   /// \brief Creates directive with a list of \a Clauses.
2018   ///
2019   /// \param C AST context.
2020   /// \param StartLoc Starting location of the directive kind.
2021   /// \param EndLoc Ending Location of the directive.
2022   /// \param Clauses List of clauses.
2023   /// \param AssociatedStmt Statement, associated with the directive.
2024   ///
2025   static OMPTargetDataDirective *
2026   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2027          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
2028 
2029   /// \brief Creates an empty directive with the place for \a N clauses.
2030   ///
2031   /// \param C AST context.
2032   /// \param N The number of clauses.
2033   ///
2034   static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
2035                                              EmptyShell);
2036 
classof(const Stmt * T)2037   static bool classof(const Stmt *T) {
2038     return T->getStmtClass() == OMPTargetDataDirectiveClass;
2039   }
2040 };
2041 
2042 /// \brief This represents '#pragma omp teams' directive.
2043 ///
2044 /// \code
2045 /// #pragma omp teams if(a)
2046 /// \endcode
2047 /// In this example directive '#pragma omp teams' has clause 'if' with
2048 /// condition 'a'.
2049 ///
2050 class OMPTeamsDirective : public OMPExecutableDirective {
2051   friend class ASTStmtReader;
2052   /// \brief Build directive with the given start and end location.
2053   ///
2054   /// \param StartLoc Starting location of the directive kind.
2055   /// \param EndLoc Ending location of the directive.
2056   /// \param NumClauses Number of clauses.
2057   ///
OMPTeamsDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)2058   OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2059                     unsigned NumClauses)
2060       : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
2061                                StartLoc, EndLoc, NumClauses, 1) {}
2062 
2063   /// \brief Build an empty directive.
2064   ///
2065   /// \param NumClauses Number of clauses.
2066   ///
OMPTeamsDirective(unsigned NumClauses)2067   explicit OMPTeamsDirective(unsigned NumClauses)
2068       : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
2069                                SourceLocation(), SourceLocation(), NumClauses,
2070                                1) {}
2071 
2072 public:
2073   /// \brief Creates directive with a list of \a Clauses.
2074   ///
2075   /// \param C AST context.
2076   /// \param StartLoc Starting location of the directive kind.
2077   /// \param EndLoc Ending Location of the directive.
2078   /// \param Clauses List of clauses.
2079   /// \param AssociatedStmt Statement, associated with the directive.
2080   ///
2081   static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
2082                                    SourceLocation EndLoc,
2083                                    ArrayRef<OMPClause *> Clauses,
2084                                    Stmt *AssociatedStmt);
2085 
2086   /// \brief Creates an empty directive with the place for \a NumClauses
2087   /// clauses.
2088   ///
2089   /// \param C AST context.
2090   /// \param NumClauses Number of clauses.
2091   ///
2092   static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
2093                                         unsigned NumClauses, EmptyShell);
2094 
classof(const Stmt * T)2095   static bool classof(const Stmt *T) {
2096     return T->getStmtClass() == OMPTeamsDirectiveClass;
2097   }
2098 };
2099 
2100 /// \brief This represents '#pragma omp cancellation point' directive.
2101 ///
2102 /// \code
2103 /// #pragma omp cancellation point for
2104 /// \endcode
2105 ///
2106 /// In this example a cancellation point is created for innermost 'for' region.
2107 class OMPCancellationPointDirective : public OMPExecutableDirective {
2108   friend class ASTStmtReader;
2109   OpenMPDirectiveKind CancelRegion;
2110   /// \brief Build directive with the given start and end location.
2111   ///
2112   /// \param StartLoc Starting location of the directive kind.
2113   /// \param EndLoc Ending location of the directive.
2114   ///
OMPCancellationPointDirective(SourceLocation StartLoc,SourceLocation EndLoc)2115   OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc)
2116       : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
2117                                OMPD_cancellation_point, StartLoc, EndLoc, 0, 0),
2118         CancelRegion(OMPD_unknown) {}
2119 
2120   /// \brief Build an empty directive.
2121   ///
OMPCancellationPointDirective()2122   explicit OMPCancellationPointDirective()
2123       : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
2124                                OMPD_cancellation_point, SourceLocation(),
2125                                SourceLocation(), 0, 0),
2126         CancelRegion(OMPD_unknown) {}
2127 
2128   /// \brief Set cancel region for current cancellation point.
2129   /// \param CR Cancellation region.
setCancelRegion(OpenMPDirectiveKind CR)2130   void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
2131 
2132 public:
2133   /// \brief Creates directive.
2134   ///
2135   /// \param C AST context.
2136   /// \param StartLoc Starting location of the directive kind.
2137   /// \param EndLoc Ending Location of the directive.
2138   ///
2139   static OMPCancellationPointDirective *
2140   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2141          OpenMPDirectiveKind CancelRegion);
2142 
2143   /// \brief Creates an empty directive.
2144   ///
2145   /// \param C AST context.
2146   ///
2147   static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
2148                                                     EmptyShell);
2149 
2150   /// \brief Get cancellation region for the current cancellation point.
getCancelRegion()2151   OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
2152 
classof(const Stmt * T)2153   static bool classof(const Stmt *T) {
2154     return T->getStmtClass() == OMPCancellationPointDirectiveClass;
2155   }
2156 };
2157 
2158 /// \brief This represents '#pragma omp cancel' directive.
2159 ///
2160 /// \code
2161 /// #pragma omp cancel for
2162 /// \endcode
2163 ///
2164 /// In this example a cancel is created for innermost 'for' region.
2165 class OMPCancelDirective : public OMPExecutableDirective {
2166   friend class ASTStmtReader;
2167   OpenMPDirectiveKind CancelRegion;
2168   /// \brief Build directive with the given start and end location.
2169   ///
2170   /// \param StartLoc Starting location of the directive kind.
2171   /// \param EndLoc Ending location of the directive.
2172   /// \param NumClauses Number of clauses.
2173   ///
OMPCancelDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)2174   OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2175                      unsigned NumClauses)
2176       : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
2177                                StartLoc, EndLoc, NumClauses, 0),
2178         CancelRegion(OMPD_unknown) {}
2179 
2180   /// \brief Build an empty directive.
2181   ///
2182   /// \param NumClauses Number of clauses.
OMPCancelDirective(unsigned NumClauses)2183   explicit OMPCancelDirective(unsigned NumClauses)
2184       : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
2185                                SourceLocation(), SourceLocation(), NumClauses,
2186                                0),
2187         CancelRegion(OMPD_unknown) {}
2188 
2189   /// \brief Set cancel region for current cancellation point.
2190   /// \param CR Cancellation region.
setCancelRegion(OpenMPDirectiveKind CR)2191   void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
2192 
2193 public:
2194   /// \brief Creates directive.
2195   ///
2196   /// \param C AST context.
2197   /// \param StartLoc Starting location of the directive kind.
2198   /// \param EndLoc Ending Location of the directive.
2199   /// \param Clauses List of clauses.
2200   ///
2201   static OMPCancelDirective *
2202   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2203          ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
2204 
2205   /// \brief Creates an empty directive.
2206   ///
2207   /// \param C AST context.
2208   /// \param NumClauses Number of clauses.
2209   ///
2210   static OMPCancelDirective *CreateEmpty(const ASTContext &C,
2211                                          unsigned NumClauses, EmptyShell);
2212 
2213   /// \brief Get cancellation region for the current cancellation point.
getCancelRegion()2214   OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
2215 
classof(const Stmt * T)2216   static bool classof(const Stmt *T) {
2217     return T->getStmtClass() == OMPCancelDirectiveClass;
2218   }
2219 };
2220 
2221 /// \brief This represents '#pragma omp taskloop' directive.
2222 ///
2223 /// \code
2224 /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
2225 /// \endcode
2226 /// In this example directive '#pragma omp taskloop' has clauses 'private'
2227 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
2228 /// 'num_tasks' with expression 'num'.
2229 ///
2230 class OMPTaskLoopDirective : public OMPLoopDirective {
2231   friend class ASTStmtReader;
2232   /// \brief Build directive with the given start and end location.
2233   ///
2234   /// \param StartLoc Starting location of the directive kind.
2235   /// \param EndLoc Ending location of the directive.
2236   /// \param CollapsedNum Number of collapsed nested loops.
2237   /// \param NumClauses Number of clauses.
2238   ///
OMPTaskLoopDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)2239   OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2240                        unsigned CollapsedNum, unsigned NumClauses)
2241       : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
2242                          StartLoc, EndLoc, CollapsedNum, NumClauses) {}
2243 
2244   /// \brief Build an empty directive.
2245   ///
2246   /// \param CollapsedNum Number of collapsed nested loops.
2247   /// \param NumClauses Number of clauses.
2248   ///
OMPTaskLoopDirective(unsigned CollapsedNum,unsigned NumClauses)2249   explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses)
2250       : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
2251                          SourceLocation(), SourceLocation(), CollapsedNum,
2252                          NumClauses) {}
2253 
2254 public:
2255   /// \brief Creates directive with a list of \a Clauses.
2256   ///
2257   /// \param C AST context.
2258   /// \param StartLoc Starting location of the directive kind.
2259   /// \param EndLoc Ending Location of the directive.
2260   /// \param CollapsedNum Number of collapsed loops.
2261   /// \param Clauses List of clauses.
2262   /// \param AssociatedStmt Statement, associated with the directive.
2263   /// \param Exprs Helper expressions for CodeGen.
2264   ///
2265   static OMPTaskLoopDirective *
2266   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2267          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2268          Stmt *AssociatedStmt, const HelperExprs &Exprs);
2269 
2270   /// \brief Creates an empty directive with the place
2271   /// for \a NumClauses clauses.
2272   ///
2273   /// \param C AST context.
2274   /// \param CollapsedNum Number of collapsed nested loops.
2275   /// \param NumClauses Number of clauses.
2276   ///
2277   static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
2278                                            unsigned NumClauses,
2279                                            unsigned CollapsedNum, EmptyShell);
2280 
classof(const Stmt * T)2281   static bool classof(const Stmt *T) {
2282     return T->getStmtClass() == OMPTaskLoopDirectiveClass;
2283   }
2284 };
2285 
2286 /// \brief This represents '#pragma omp taskloop simd' directive.
2287 ///
2288 /// \code
2289 /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
2290 /// \endcode
2291 /// In this example directive '#pragma omp taskloop simd' has clauses 'private'
2292 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
2293 /// 'num_tasks' with expression 'num'.
2294 ///
2295 class OMPTaskLoopSimdDirective : public OMPLoopDirective {
2296   friend class ASTStmtReader;
2297   /// \brief Build directive with the given start and end location.
2298   ///
2299   /// \param StartLoc Starting location of the directive kind.
2300   /// \param EndLoc Ending location of the directive.
2301   /// \param CollapsedNum Number of collapsed nested loops.
2302   /// \param NumClauses Number of clauses.
2303   ///
OMPTaskLoopSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)2304   OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2305                            unsigned CollapsedNum, unsigned NumClauses)
2306       : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
2307                          OMPD_taskloop_simd, StartLoc, EndLoc, CollapsedNum,
2308                          NumClauses) {}
2309 
2310   /// \brief Build an empty directive.
2311   ///
2312   /// \param CollapsedNum Number of collapsed nested loops.
2313   /// \param NumClauses Number of clauses.
2314   ///
OMPTaskLoopSimdDirective(unsigned CollapsedNum,unsigned NumClauses)2315   explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
2316       : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
2317                          OMPD_taskloop_simd, SourceLocation(), SourceLocation(),
2318                          CollapsedNum, NumClauses) {}
2319 
2320 public:
2321   /// \brief Creates directive with a list of \a Clauses.
2322   ///
2323   /// \param C AST context.
2324   /// \param StartLoc Starting location of the directive kind.
2325   /// \param EndLoc Ending Location of the directive.
2326   /// \param CollapsedNum Number of collapsed loops.
2327   /// \param Clauses List of clauses.
2328   /// \param AssociatedStmt Statement, associated with the directive.
2329   /// \param Exprs Helper expressions for CodeGen.
2330   ///
2331   static OMPTaskLoopSimdDirective *
2332   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2333          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2334          Stmt *AssociatedStmt, const HelperExprs &Exprs);
2335 
2336   /// \brief Creates an empty directive with the place
2337   /// for \a NumClauses clauses.
2338   ///
2339   /// \param C AST context.
2340   /// \param CollapsedNum Number of collapsed nested loops.
2341   /// \param NumClauses Number of clauses.
2342   ///
2343   static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
2344                                                unsigned NumClauses,
2345                                                unsigned CollapsedNum,
2346                                                EmptyShell);
2347 
classof(const Stmt * T)2348   static bool classof(const Stmt *T) {
2349     return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
2350   }
2351 };
2352 
2353 /// \brief This represents '#pragma omp distribute' directive.
2354 ///
2355 /// \code
2356 /// #pragma omp distribute private(a,b)
2357 /// \endcode
2358 /// In this example directive '#pragma omp distribute' has clauses 'private'
2359 /// with the variables 'a' and 'b'
2360 ///
2361 class OMPDistributeDirective : public OMPLoopDirective {
2362   friend class ASTStmtReader;
2363 
2364   /// \brief Build directive with the given start and end location.
2365   ///
2366   /// \param StartLoc Starting location of the directive kind.
2367   /// \param EndLoc Ending location of the directive.
2368   /// \param CollapsedNum Number of collapsed nested loops.
2369   /// \param NumClauses Number of clauses.
2370   ///
OMPDistributeDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)2371   OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
2372                          unsigned CollapsedNum, unsigned NumClauses)
2373       : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
2374                          StartLoc, EndLoc, CollapsedNum, NumClauses)
2375         {}
2376 
2377   /// \brief Build an empty directive.
2378   ///
2379   /// \param CollapsedNum Number of collapsed nested loops.
2380   /// \param NumClauses Number of clauses.
2381   ///
OMPDistributeDirective(unsigned CollapsedNum,unsigned NumClauses)2382   explicit OMPDistributeDirective(unsigned CollapsedNum, unsigned NumClauses)
2383       : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
2384                          SourceLocation(), SourceLocation(), CollapsedNum,
2385                          NumClauses)
2386         {}
2387 
2388 public:
2389   /// \brief Creates directive with a list of \a Clauses.
2390   ///
2391   /// \param C AST context.
2392   /// \param StartLoc Starting location of the directive kind.
2393   /// \param EndLoc Ending Location of the directive.
2394   /// \param CollapsedNum Number of collapsed loops.
2395   /// \param Clauses List of clauses.
2396   /// \param AssociatedStmt Statement, associated with the directive.
2397   /// \param Exprs Helper expressions for CodeGen.
2398     ///
2399   static OMPDistributeDirective *
2400   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
2401          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
2402          Stmt *AssociatedStmt, const HelperExprs &Exprs);
2403 
2404   /// \brief Creates an empty directive with the place
2405   /// for \a NumClauses clauses.
2406   ///
2407   /// \param C AST context.
2408   /// \param CollapsedNum Number of collapsed nested loops.
2409   /// \param NumClauses Number of clauses.
2410   ///
2411   static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
2412                                              unsigned NumClauses,
2413                                              unsigned CollapsedNum, EmptyShell);
2414 
classof(const Stmt * T)2415   static bool classof(const Stmt *T) {
2416     return T->getStmtClass() == OMPDistributeDirectiveClass;
2417   }
2418 };
2419 
2420 } // end namespace clang
2421 
2422 #endif
2423