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 those declarations that meet some run-time
96   /// criteria.
97   template <class FilterPredicate> class filtered_clause_iterator {
98   protected:
99     ArrayRef<OMPClause *>::const_iterator Current;
100     ArrayRef<OMPClause *>::const_iterator End;
101     FilterPredicate Pred;
SkipToNextClause()102     void SkipToNextClause() {
103       while (Current != End && !Pred(*Current))
104         ++Current;
105     }
106 
107   public:
108     typedef const OMPClause *value_type;
filtered_clause_iterator()109     filtered_clause_iterator() : Current(), End() {}
filtered_clause_iterator(ArrayRef<OMPClause * > Arr,FilterPredicate Pred)110     filtered_clause_iterator(ArrayRef<OMPClause *> Arr, FilterPredicate Pred)
111         : Current(Arr.begin()), End(Arr.end()), Pred(Pred) {
112       SkipToNextClause();
113     }
114     value_type operator*() const { return *Current; }
115     value_type operator->() const { return *Current; }
116     filtered_clause_iterator &operator++() {
117       ++Current;
118       SkipToNextClause();
119       return *this;
120     }
121 
122     filtered_clause_iterator operator++(int) {
123       filtered_clause_iterator tmp(*this);
124       ++(*this);
125       return tmp;
126     }
127 
128     bool operator!() { return Current == End; }
129     operator bool() { return Current != End; }
empty()130     bool empty() const { return Current == End; }
131   };
132 
133   /// \brief A filter to iterate over 'linear' clauses using a C++ range
134   /// for loop.
135   struct linear_filter : public filtered_clause_iterator<
136                              std::function<bool(const OMPClause *)> > {
linear_filterlinear_filter137     linear_filter(ArrayRef<OMPClause *> Arr)
138         : filtered_clause_iterator(Arr, [](const OMPClause *C)->bool {
139             return C->getClauseKind() == OMPC_linear;
140           }) {}
141     const OMPLinearClause *operator*() const {
142       return cast<OMPLinearClause>(*Current);
143     }
144     const OMPLinearClause *operator->() const {
145       return cast<OMPLinearClause>(*Current);
146     }
beginlinear_filter147     friend linear_filter begin(const linear_filter &range) { return range; }
endlinear_filter148     friend linear_filter end(const linear_filter &range) {
149       return linear_filter(ArrayRef<OMPClause *>(range.End, range.End));
150     }
151   };
152 
153   /// \brief Gets a single clause of the specified kind \a K associated with the
154   /// current directive iff there is only one clause of this kind (and assertion
155   /// is fired if there is more than one clause is associated with the
156   /// directive). Returns nullptr if no clause of kind \a K is associated with
157   /// the directive.
158   const OMPClause *getSingleClause(OpenMPClauseKind K) const;
159 
160   /// \brief Returns starting location of directive kind.
getLocStart()161   SourceLocation getLocStart() const { return StartLoc; }
162   /// \brief Returns ending location of directive.
getLocEnd()163   SourceLocation getLocEnd() const { return EndLoc; }
164 
165   /// \brief Set starting location of directive kind.
166   ///
167   /// \param Loc New starting location of directive.
168   ///
setLocStart(SourceLocation Loc)169   void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
170   /// \brief Set ending location of directive.
171   ///
172   /// \param Loc New ending location of directive.
173   ///
setLocEnd(SourceLocation Loc)174   void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
175 
176   /// \brief Get number of clauses.
getNumClauses()177   unsigned getNumClauses() const { return NumClauses; }
178 
179   /// \brief Returns specified clause.
180   ///
181   /// \param i Number of clause.
182   ///
getClause(unsigned i)183   OMPClause *getClause(unsigned i) const { return clauses()[i]; }
184 
185   /// \brief Returns true if directive has associated statement.
hasAssociatedStmt()186   bool hasAssociatedStmt() const { return NumChildren > 0; }
187 
188   /// \brief Returns statement associated with the directive.
getAssociatedStmt()189   Stmt *getAssociatedStmt() const {
190     assert(hasAssociatedStmt() && "no associated statement.");
191     return const_cast<Stmt *>(*child_begin());
192   }
193 
getDirectiveKind()194   OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
195 
classof(const Stmt * S)196   static bool classof(const Stmt *S) {
197     return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
198            S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
199   }
200 
children()201   child_range children() {
202     if (!hasAssociatedStmt())
203       return child_range();
204     Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
205     return child_range(ChildStorage, ChildStorage + NumChildren);
206   }
207 
clauses()208   ArrayRef<OMPClause *> clauses() { return getClauses(); }
209 
clauses()210   ArrayRef<OMPClause *> clauses() const {
211     return const_cast<OMPExecutableDirective *>(this)->getClauses();
212   }
213 };
214 
215 /// \brief This represents '#pragma omp parallel' directive.
216 ///
217 /// \code
218 /// #pragma omp parallel private(a,b) reduction(+: c,d)
219 /// \endcode
220 /// In this example directive '#pragma omp parallel' has clauses 'private'
221 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
222 /// variables 'c' and 'd'.
223 ///
224 class OMPParallelDirective : public OMPExecutableDirective {
225   /// \brief Build directive with the given start and end location.
226   ///
227   /// \param StartLoc Starting location of the directive (directive keyword).
228   /// \param EndLoc Ending Location of the directive.
229   ///
OMPParallelDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)230   OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
231                        unsigned NumClauses)
232       : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
233                                StartLoc, EndLoc, NumClauses, 1) {}
234 
235   /// \brief Build an empty directive.
236   ///
237   /// \param NumClauses Number of clauses.
238   ///
OMPParallelDirective(unsigned NumClauses)239   explicit OMPParallelDirective(unsigned NumClauses)
240       : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
241                                SourceLocation(), SourceLocation(), NumClauses,
242                                1) {}
243 
244 public:
245   /// \brief Creates directive with a list of \a Clauses.
246   ///
247   /// \param C AST context.
248   /// \param StartLoc Starting location of the directive kind.
249   /// \param EndLoc Ending Location of the directive.
250   /// \param Clauses List of clauses.
251   /// \param AssociatedStmt Statement associated with the directive.
252   ///
253   static OMPParallelDirective *
254   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
255          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
256 
257   /// \brief Creates an empty directive with the place for \a N clauses.
258   ///
259   /// \param C AST context.
260   /// \param NumClauses Number of clauses.
261   ///
262   static OMPParallelDirective *CreateEmpty(const ASTContext &C,
263                                            unsigned NumClauses, EmptyShell);
264 
classof(const Stmt * T)265   static bool classof(const Stmt *T) {
266     return T->getStmtClass() == OMPParallelDirectiveClass;
267   }
268 };
269 
270 /// \brief This is a common base class for loop directives ('omp simd', 'omp
271 /// for', 'omp for simd' etc.). It is responsible for the loop code generation.
272 ///
273 class OMPLoopDirective : public OMPExecutableDirective {
274   friend class ASTStmtReader;
275   /// \brief Number of collapsed loops as specified by 'collapse' clause.
276   unsigned CollapsedNum;
277 
278   /// \brief Offsets to the stored exprs.
279   /// This enumeration contains offsets to all the pointers to children
280   /// expressions stored in OMPLoopDirective.
281   /// The first 9 children are nesessary for all the loop directives, and
282   /// the next 7 are specific to the worksharing ones.
283   /// After the fixed children, three arrays of length CollapsedNum are
284   /// allocated: loop counters, their updates and final values.
285   ///
286   enum {
287     AssociatedStmtOffset = 0,
288     IterationVariableOffset = 1,
289     LastIterationOffset = 2,
290     CalcLastIterationOffset = 3,
291     PreConditionOffset = 4,
292     CondOffset = 5,
293     SeparatedCondOffset = 6,
294     InitOffset = 7,
295     IncOffset = 8,
296     // The '...End' enumerators do not correspond to child expressions - they
297     // specify the offset to the end (and start of the following counters/
298     // updates/finals arrays).
299     DefaultEnd = 9,
300     // The following 7 exprs are used by worksharing loops only.
301     IsLastIterVariableOffset = 9,
302     LowerBoundVariableOffset = 10,
303     UpperBoundVariableOffset = 11,
304     StrideVariableOffset = 12,
305     EnsureUpperBoundOffset = 13,
306     NextLowerBoundOffset = 14,
307     NextUpperBoundOffset = 15,
308     // Offset to the end (and start of the following counters/updates/finals
309     // arrays) for worksharing loop directives.
310     WorksharingEnd = 16,
311   };
312 
313   /// \brief Get the counters storage.
getCounters()314   MutableArrayRef<Expr *> getCounters() {
315     Expr **Storage = reinterpret_cast<Expr **>(
316         &(*(std::next(child_begin(), getArraysOffset(getDirectiveKind())))));
317     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
318   }
319 
320   /// \brief Get the updates storage.
getUpdates()321   MutableArrayRef<Expr *> getUpdates() {
322     Expr **Storage = reinterpret_cast<Expr **>(
323         &*std::next(child_begin(),
324                     getArraysOffset(getDirectiveKind()) + CollapsedNum));
325     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
326   }
327 
328   /// \brief Get the final counter updates storage.
getFinals()329   MutableArrayRef<Expr *> getFinals() {
330     Expr **Storage = reinterpret_cast<Expr **>(
331         &*std::next(child_begin(),
332                     getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum));
333     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
334   }
335 
336 protected:
337   /// \brief Build instance of loop directive of class \a Kind.
338   ///
339   /// \param SC Statement class.
340   /// \param Kind Kind of OpenMP directive.
341   /// \param StartLoc Starting location of the directive (directive keyword).
342   /// \param EndLoc Ending location of the directive.
343   /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
344   /// \param NumClauses Number of clauses.
345   /// \param NumSpecialChildren Number of additional directive-specific stmts.
346   ///
347   template <typename T>
348   OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind,
349                    SourceLocation StartLoc, SourceLocation EndLoc,
350                    unsigned CollapsedNum, unsigned NumClauses,
351                    unsigned NumSpecialChildren = 0)
352       : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses,
353                                numLoopChildren(CollapsedNum, Kind) +
354                                    NumSpecialChildren),
355         CollapsedNum(CollapsedNum) {}
356 
357   /// \brief Offset to the start of children expression arrays.
getArraysOffset(OpenMPDirectiveKind Kind)358   static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
359     return isOpenMPWorksharingDirective(Kind) ? WorksharingEnd
360                                               : DefaultEnd;
361   }
362 
363   /// \brief Children number.
numLoopChildren(unsigned CollapsedNum,OpenMPDirectiveKind Kind)364   static unsigned numLoopChildren(unsigned CollapsedNum,
365                                   OpenMPDirectiveKind Kind) {
366     return getArraysOffset(Kind) +
367            3 * CollapsedNum; // Counters, Updates and Finals
368   }
369 
setIterationVariable(Expr * IV)370   void setIterationVariable(Expr *IV) {
371     *std::next(child_begin(), IterationVariableOffset) = IV;
372   }
setLastIteration(Expr * LI)373   void setLastIteration(Expr *LI) {
374     *std::next(child_begin(), LastIterationOffset) = LI;
375   }
setCalcLastIteration(Expr * CLI)376   void setCalcLastIteration(Expr *CLI) {
377     *std::next(child_begin(), CalcLastIterationOffset) = CLI;
378   }
setPreCond(Expr * PC)379   void setPreCond(Expr *PC) {
380     *std::next(child_begin(), PreConditionOffset) = PC;
381   }
setCond(Expr * Cond,Expr * SeparatedCond)382   void setCond(Expr *Cond, Expr *SeparatedCond) {
383     *std::next(child_begin(), CondOffset) = Cond;
384     *std::next(child_begin(), SeparatedCondOffset) = SeparatedCond;
385   }
setInit(Expr * Init)386   void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; }
setInc(Expr * Inc)387   void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; }
setIsLastIterVariable(Expr * IL)388   void setIsLastIterVariable(Expr *IL) {
389     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
390            "expected worksharing loop directive");
391     *std::next(child_begin(), IsLastIterVariableOffset) = IL;
392   }
setLowerBoundVariable(Expr * LB)393   void setLowerBoundVariable(Expr *LB) {
394     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
395            "expected worksharing loop directive");
396     *std::next(child_begin(), LowerBoundVariableOffset) = LB;
397   }
setUpperBoundVariable(Expr * UB)398   void setUpperBoundVariable(Expr *UB) {
399     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
400            "expected worksharing loop directive");
401     *std::next(child_begin(), UpperBoundVariableOffset) = UB;
402   }
setStrideVariable(Expr * ST)403   void setStrideVariable(Expr *ST) {
404     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
405            "expected worksharing loop directive");
406     *std::next(child_begin(), StrideVariableOffset) = ST;
407   }
setEnsureUpperBound(Expr * EUB)408   void setEnsureUpperBound(Expr *EUB) {
409     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
410            "expected worksharing loop directive");
411     *std::next(child_begin(), EnsureUpperBoundOffset) = EUB;
412   }
setNextLowerBound(Expr * NLB)413   void setNextLowerBound(Expr *NLB) {
414     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
415            "expected worksharing loop directive");
416     *std::next(child_begin(), NextLowerBoundOffset) = NLB;
417   }
setNextUpperBound(Expr * NUB)418   void setNextUpperBound(Expr *NUB) {
419     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
420            "expected worksharing loop directive");
421     *std::next(child_begin(), NextUpperBoundOffset) = NUB;
422   }
423   void setCounters(ArrayRef<Expr *> A);
424   void setUpdates(ArrayRef<Expr *> A);
425   void setFinals(ArrayRef<Expr *> A);
426 
427 public:
428   /// \brief The expressions built for the OpenMP loop CodeGen for the
429   /// whole collapsed loop nest.
430   struct HelperExprs {
431     /// \brief Loop iteration variable.
432     Expr *IterationVarRef;
433     /// \brief Loop last iteration number.
434     Expr *LastIteration;
435     /// \brief Loop number of iterations.
436     Expr *NumIterations;
437     /// \brief Calculation of last iteration.
438     Expr *CalcLastIteration;
439     /// \brief Loop pre-condition.
440     Expr *PreCond;
441     /// \brief Loop condition.
442     Expr *Cond;
443     /// \brief A condition with 1 iteration separated.
444     Expr *SeparatedCond;
445     /// \brief Loop iteration variable init.
446     Expr *Init;
447     /// \brief Loop increment.
448     Expr *Inc;
449     /// \brief IsLastIteration - local flag variable passed to runtime.
450     Expr *IL;
451     /// \brief LowerBound - local variable passed to runtime.
452     Expr *LB;
453     /// \brief UpperBound - local variable passed to runtime.
454     Expr *UB;
455     /// \brief Stride - local variable passed to runtime.
456     Expr *ST;
457     /// \brief EnsureUpperBound -- expression LB = min(LB, NumIterations).
458     Expr *EUB;
459     /// \brief Update of LowerBound for statically sheduled 'omp for' loops.
460     Expr *NLB;
461     /// \brief Update of UpperBound for statically sheduled 'omp for' loops.
462     Expr *NUB;
463     /// \brief Counters Loop counters.
464     SmallVector<Expr *, 4> Counters;
465     /// \brief Expressions for loop counters update for CodeGen.
466     SmallVector<Expr *, 4> Updates;
467     /// \brief Final loop counter values for GodeGen.
468     SmallVector<Expr *, 4> Finals;
469 
470     /// \brief Check if all the expressions are built (does not check the
471     /// worksharing ones).
builtAllHelperExprs472     bool builtAll() {
473       return IterationVarRef != nullptr && LastIteration != nullptr &&
474              NumIterations != nullptr && PreCond != nullptr &&
475              Cond != nullptr && SeparatedCond != nullptr && Init != nullptr &&
476              Inc != nullptr;
477     }
478 
479     /// \brief Initialize all the fields to null.
480     /// \param Size Number of elements in the counters/finals/updates arrays.
clearHelperExprs481     void clear(unsigned Size) {
482       IterationVarRef = nullptr;
483       LastIteration = nullptr;
484       CalcLastIteration = nullptr;
485       PreCond = nullptr;
486       Cond = nullptr;
487       SeparatedCond = nullptr;
488       Init = nullptr;
489       Inc = nullptr;
490       IL = nullptr;
491       LB = nullptr;
492       UB = nullptr;
493       ST = nullptr;
494       EUB = nullptr;
495       NLB = nullptr;
496       NUB = nullptr;
497       Counters.resize(Size);
498       Updates.resize(Size);
499       Finals.resize(Size);
500       for (unsigned i = 0; i < Size; ++i) {
501         Counters[i] = nullptr;
502         Updates[i] = nullptr;
503         Finals[i] = nullptr;
504       }
505     }
506   };
507 
508   /// \brief Get number of collapsed loops.
getCollapsedNumber()509   unsigned getCollapsedNumber() const { return CollapsedNum; }
510 
getIterationVariable()511   Expr *getIterationVariable() const {
512     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
513         *std::next(child_begin(), IterationVariableOffset)));
514   }
getLastIteration()515   Expr *getLastIteration() const {
516     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
517         *std::next(child_begin(), LastIterationOffset)));
518   }
getCalcLastIteration()519   Expr *getCalcLastIteration() const {
520     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
521         *std::next(child_begin(), CalcLastIterationOffset)));
522   }
getPreCond()523   Expr *getPreCond() const {
524     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
525         *std::next(child_begin(), PreConditionOffset)));
526   }
getCond(bool SeparateIter)527   Expr *getCond(bool SeparateIter) const {
528     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
529         *std::next(child_begin(),
530                    (SeparateIter ? SeparatedCondOffset : CondOffset))));
531   }
getInit()532   Expr *getInit() const {
533     return const_cast<Expr *>(
534         reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset)));
535   }
getInc()536   Expr *getInc() const {
537     return const_cast<Expr *>(
538         reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset)));
539   }
getIsLastIterVariable()540   Expr *getIsLastIterVariable() const {
541     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
542            "expected worksharing loop directive");
543     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
544         *std::next(child_begin(), IsLastIterVariableOffset)));
545   }
getLowerBoundVariable()546   Expr *getLowerBoundVariable() const {
547     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
548            "expected worksharing loop directive");
549     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
550         *std::next(child_begin(), LowerBoundVariableOffset)));
551   }
getUpperBoundVariable()552   Expr *getUpperBoundVariable() const {
553     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
554            "expected worksharing loop directive");
555     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
556         *std::next(child_begin(), UpperBoundVariableOffset)));
557   }
getStrideVariable()558   Expr *getStrideVariable() const {
559     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
560            "expected worksharing loop directive");
561     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
562         *std::next(child_begin(), StrideVariableOffset)));
563   }
getEnsureUpperBound()564   Expr *getEnsureUpperBound() const {
565     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
566            "expected worksharing loop directive");
567     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
568         *std::next(child_begin(), EnsureUpperBoundOffset)));
569   }
getNextLowerBound()570   Expr *getNextLowerBound() const {
571     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
572            "expected worksharing loop directive");
573     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
574         *std::next(child_begin(), NextLowerBoundOffset)));
575   }
getNextUpperBound()576   Expr *getNextUpperBound() const {
577     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
578            "expected worksharing loop directive");
579     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
580         *std::next(child_begin(), NextUpperBoundOffset)));
581   }
getBody()582   const Stmt *getBody() const {
583     // This relies on the loop form is already checked by Sema.
584     Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
585     Body = cast<ForStmt>(Body)->getBody();
586     for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
587       Body = Body->IgnoreContainers();
588       Body = cast<ForStmt>(Body)->getBody();
589     }
590     return Body;
591   }
592 
counters()593   ArrayRef<Expr *> counters() { return getCounters(); }
594 
counters()595   ArrayRef<Expr *> counters() const {
596     return const_cast<OMPLoopDirective *>(this)->getCounters();
597   }
598 
updates()599   ArrayRef<Expr *> updates() { return getUpdates(); }
600 
updates()601   ArrayRef<Expr *> updates() const {
602     return const_cast<OMPLoopDirective *>(this)->getUpdates();
603   }
604 
finals()605   ArrayRef<Expr *> finals() { return getFinals(); }
606 
finals()607   ArrayRef<Expr *> finals() const {
608     return const_cast<OMPLoopDirective *>(this)->getFinals();
609   }
610 
classof(const Stmt * T)611   static bool classof(const Stmt *T) {
612     return T->getStmtClass() == OMPSimdDirectiveClass ||
613            T->getStmtClass() == OMPForDirectiveClass ||
614            T->getStmtClass() == OMPForSimdDirectiveClass ||
615            T->getStmtClass() == OMPParallelForDirectiveClass ||
616            T->getStmtClass() == OMPParallelForSimdDirectiveClass;
617   }
618 };
619 
620 /// \brief This represents '#pragma omp simd' directive.
621 ///
622 /// \code
623 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
624 /// \endcode
625 /// In this example directive '#pragma omp simd' has clauses 'private'
626 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
627 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
628 ///
629 class OMPSimdDirective : public OMPLoopDirective {
630   friend class ASTStmtReader;
631   /// \brief Build directive with the given start and end location.
632   ///
633   /// \param StartLoc Starting location of the directive kind.
634   /// \param EndLoc Ending location of the directive.
635   /// \param CollapsedNum Number of collapsed nested loops.
636   /// \param NumClauses Number of clauses.
637   ///
OMPSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)638   OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
639                    unsigned CollapsedNum, unsigned NumClauses)
640       : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
641                          EndLoc, CollapsedNum, NumClauses) {}
642 
643   /// \brief Build an empty directive.
644   ///
645   /// \param CollapsedNum Number of collapsed nested loops.
646   /// \param NumClauses Number of clauses.
647   ///
OMPSimdDirective(unsigned CollapsedNum,unsigned NumClauses)648   explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
649       : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd,
650                          SourceLocation(), SourceLocation(), CollapsedNum,
651                          NumClauses) {}
652 
653 public:
654   /// \brief Creates directive with a list of \a Clauses.
655   ///
656   /// \param C AST context.
657   /// \param StartLoc Starting location of the directive kind.
658   /// \param EndLoc Ending Location of the directive.
659   /// \param CollapsedNum Number of collapsed loops.
660   /// \param Clauses List of clauses.
661   /// \param AssociatedStmt Statement, associated with the directive.
662   /// \param Exprs Helper expressions for CodeGen.
663   ///
664   static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
665                                   SourceLocation EndLoc, unsigned CollapsedNum,
666                                   ArrayRef<OMPClause *> Clauses,
667                                   Stmt *AssociatedStmt,
668                                   const HelperExprs &Exprs);
669 
670   /// \brief Creates an empty directive with the place
671   /// for \a NumClauses clauses.
672   ///
673   /// \param C AST context.
674   /// \param CollapsedNum Number of collapsed nested loops.
675   /// \param NumClauses Number of clauses.
676   ///
677   static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
678                                        unsigned CollapsedNum, EmptyShell);
679 
classof(const Stmt * T)680   static bool classof(const Stmt *T) {
681     return T->getStmtClass() == OMPSimdDirectiveClass;
682   }
683 };
684 
685 /// \brief This represents '#pragma omp for' directive.
686 ///
687 /// \code
688 /// #pragma omp for private(a,b) reduction(+:c,d)
689 /// \endcode
690 /// In this example directive '#pragma omp for' has clauses 'private' with the
691 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
692 /// and 'd'.
693 ///
694 class OMPForDirective : public OMPLoopDirective {
695   friend class ASTStmtReader;
696   /// \brief Build directive with the given start and end location.
697   ///
698   /// \param StartLoc Starting location of the directive kind.
699   /// \param EndLoc Ending location of the directive.
700   /// \param CollapsedNum Number of collapsed nested loops.
701   /// \param NumClauses Number of clauses.
702   ///
OMPForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)703   OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
704                   unsigned CollapsedNum, unsigned NumClauses)
705       : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc,
706                          CollapsedNum, NumClauses) {}
707 
708   /// \brief Build an empty directive.
709   ///
710   /// \param CollapsedNum Number of collapsed nested loops.
711   /// \param NumClauses Number of clauses.
712   ///
OMPForDirective(unsigned CollapsedNum,unsigned NumClauses)713   explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
714       : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(),
715                          SourceLocation(), CollapsedNum, NumClauses) {}
716 
717 public:
718   /// \brief Creates directive with a list of \a Clauses.
719   ///
720   /// \param C AST context.
721   /// \param StartLoc Starting location of the directive kind.
722   /// \param EndLoc Ending Location of the directive.
723   /// \param CollapsedNum Number of collapsed loops.
724   /// \param Clauses List of clauses.
725   /// \param AssociatedStmt Statement, associated with the directive.
726   /// \param Exprs Helper expressions for CodeGen.
727   ///
728   static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
729                                  SourceLocation EndLoc, unsigned CollapsedNum,
730                                  ArrayRef<OMPClause *> Clauses,
731                                  Stmt *AssociatedStmt,
732                                  const HelperExprs &Exprs);
733 
734   /// \brief Creates an empty directive with the place
735   /// for \a NumClauses clauses.
736   ///
737   /// \param C AST context.
738   /// \param CollapsedNum Number of collapsed nested loops.
739   /// \param NumClauses Number of clauses.
740   ///
741   static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
742                                       unsigned CollapsedNum, EmptyShell);
743 
classof(const Stmt * T)744   static bool classof(const Stmt *T) {
745     return T->getStmtClass() == OMPForDirectiveClass;
746   }
747 };
748 
749 /// \brief This represents '#pragma omp for simd' directive.
750 ///
751 /// \code
752 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
753 /// \endcode
754 /// In this example directive '#pragma omp for simd' has clauses 'private'
755 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
756 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
757 ///
758 class OMPForSimdDirective : public OMPLoopDirective {
759   friend class ASTStmtReader;
760   /// \brief Build directive with the given start and end location.
761   ///
762   /// \param StartLoc Starting location of the directive kind.
763   /// \param EndLoc Ending location of the directive.
764   /// \param CollapsedNum Number of collapsed nested loops.
765   /// \param NumClauses Number of clauses.
766   ///
OMPForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)767   OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
768                       unsigned CollapsedNum, unsigned NumClauses)
769       : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
770                          StartLoc, EndLoc, CollapsedNum, NumClauses) {}
771 
772   /// \brief Build an empty directive.
773   ///
774   /// \param CollapsedNum Number of collapsed nested loops.
775   /// \param NumClauses Number of clauses.
776   ///
OMPForSimdDirective(unsigned CollapsedNum,unsigned NumClauses)777   explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
778       : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
779                          SourceLocation(), SourceLocation(), CollapsedNum,
780                          NumClauses) {}
781 
782 public:
783   /// \brief Creates directive with a list of \a Clauses.
784   ///
785   /// \param C AST context.
786   /// \param StartLoc Starting location of the directive kind.
787   /// \param EndLoc Ending Location of the directive.
788   /// \param CollapsedNum Number of collapsed loops.
789   /// \param Clauses List of clauses.
790   /// \param AssociatedStmt Statement, associated with the directive.
791   /// \param Exprs Helper expressions for CodeGen.
792   ///
793   static OMPForSimdDirective *
794   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
795          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
796          Stmt *AssociatedStmt, const HelperExprs &Exprs);
797 
798   /// \brief Creates an empty directive with the place
799   /// for \a NumClauses clauses.
800   ///
801   /// \param C AST context.
802   /// \param CollapsedNum Number of collapsed nested loops.
803   /// \param NumClauses Number of clauses.
804   ///
805   static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
806                                           unsigned NumClauses,
807                                           unsigned CollapsedNum, EmptyShell);
808 
classof(const Stmt * T)809   static bool classof(const Stmt *T) {
810     return T->getStmtClass() == OMPForSimdDirectiveClass;
811   }
812 };
813 
814 /// \brief This represents '#pragma omp sections' directive.
815 ///
816 /// \code
817 /// #pragma omp sections private(a,b) reduction(+:c,d)
818 /// \endcode
819 /// In this example directive '#pragma omp sections' has clauses 'private' with
820 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
821 /// 'c' and 'd'.
822 ///
823 class OMPSectionsDirective : public OMPExecutableDirective {
824   friend class ASTStmtReader;
825   /// \brief Build directive with the given start and end location.
826   ///
827   /// \param StartLoc Starting location of the directive kind.
828   /// \param EndLoc Ending location of the directive.
829   /// \param NumClauses Number of clauses.
830   ///
OMPSectionsDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)831   OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
832                        unsigned NumClauses)
833       : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
834                                StartLoc, EndLoc, NumClauses, 1) {}
835 
836   /// \brief Build an empty directive.
837   ///
838   /// \param NumClauses Number of clauses.
839   ///
OMPSectionsDirective(unsigned NumClauses)840   explicit OMPSectionsDirective(unsigned NumClauses)
841       : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
842                                SourceLocation(), SourceLocation(), NumClauses,
843                                1) {}
844 
845 public:
846   /// \brief Creates directive with a list of \a Clauses.
847   ///
848   /// \param C AST context.
849   /// \param StartLoc Starting location of the directive kind.
850   /// \param EndLoc Ending Location of the directive.
851   /// \param Clauses List of clauses.
852   /// \param AssociatedStmt Statement, associated with the directive.
853   ///
854   static OMPSectionsDirective *
855   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
856          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
857 
858   /// \brief Creates an empty directive with the place for \a NumClauses
859   /// clauses.
860   ///
861   /// \param C AST context.
862   /// \param NumClauses Number of clauses.
863   ///
864   static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
865                                            unsigned NumClauses, EmptyShell);
866 
classof(const Stmt * T)867   static bool classof(const Stmt *T) {
868     return T->getStmtClass() == OMPSectionsDirectiveClass;
869   }
870 };
871 
872 /// \brief This represents '#pragma omp section' directive.
873 ///
874 /// \code
875 /// #pragma omp section
876 /// \endcode
877 ///
878 class OMPSectionDirective : public OMPExecutableDirective {
879   friend class ASTStmtReader;
880   /// \brief Build directive with the given start and end location.
881   ///
882   /// \param StartLoc Starting location of the directive kind.
883   /// \param EndLoc Ending location of the directive.
884   ///
OMPSectionDirective(SourceLocation StartLoc,SourceLocation EndLoc)885   OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
886       : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
887                                StartLoc, EndLoc, 0, 1) {}
888 
889   /// \brief Build an empty directive.
890   ///
OMPSectionDirective()891   explicit OMPSectionDirective()
892       : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
893                                SourceLocation(), SourceLocation(), 0, 1) {}
894 
895 public:
896   /// \brief Creates directive.
897   ///
898   /// \param C AST context.
899   /// \param StartLoc Starting location of the directive kind.
900   /// \param EndLoc Ending Location of the directive.
901   /// \param AssociatedStmt Statement, associated with the directive.
902   ///
903   static OMPSectionDirective *Create(const ASTContext &C,
904                                      SourceLocation StartLoc,
905                                      SourceLocation EndLoc,
906                                      Stmt *AssociatedStmt);
907 
908   /// \brief Creates an empty directive.
909   ///
910   /// \param C AST context.
911   ///
912   static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
913 
classof(const Stmt * T)914   static bool classof(const Stmt *T) {
915     return T->getStmtClass() == OMPSectionDirectiveClass;
916   }
917 };
918 
919 /// \brief This represents '#pragma omp single' directive.
920 ///
921 /// \code
922 /// #pragma omp single private(a,b) copyprivate(c,d)
923 /// \endcode
924 /// In this example directive '#pragma omp single' has clauses 'private' with
925 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
926 ///
927 class OMPSingleDirective : public OMPExecutableDirective {
928   friend class ASTStmtReader;
929   /// \brief Build directive with the given start and end location.
930   ///
931   /// \param StartLoc Starting location of the directive kind.
932   /// \param EndLoc Ending location of the directive.
933   /// \param NumClauses Number of clauses.
934   ///
OMPSingleDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)935   OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
936                      unsigned NumClauses)
937       : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
938                                StartLoc, EndLoc, NumClauses, 1) {}
939 
940   /// \brief Build an empty directive.
941   ///
942   /// \param NumClauses Number of clauses.
943   ///
OMPSingleDirective(unsigned NumClauses)944   explicit OMPSingleDirective(unsigned NumClauses)
945       : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
946                                SourceLocation(), SourceLocation(), NumClauses,
947                                1) {}
948 
949 public:
950   /// \brief Creates directive with a list of \a Clauses.
951   ///
952   /// \param C AST context.
953   /// \param StartLoc Starting location of the directive kind.
954   /// \param EndLoc Ending Location of the directive.
955   /// \param Clauses List of clauses.
956   /// \param AssociatedStmt Statement, associated with the directive.
957   ///
958   static OMPSingleDirective *
959   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
960          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
961 
962   /// \brief Creates an empty directive with the place for \a NumClauses
963   /// clauses.
964   ///
965   /// \param C AST context.
966   /// \param NumClauses Number of clauses.
967   ///
968   static OMPSingleDirective *CreateEmpty(const ASTContext &C,
969                                          unsigned NumClauses, EmptyShell);
970 
classof(const Stmt * T)971   static bool classof(const Stmt *T) {
972     return T->getStmtClass() == OMPSingleDirectiveClass;
973   }
974 };
975 
976 /// \brief This represents '#pragma omp master' directive.
977 ///
978 /// \code
979 /// #pragma omp master
980 /// \endcode
981 ///
982 class OMPMasterDirective : public OMPExecutableDirective {
983   friend class ASTStmtReader;
984   /// \brief Build directive with the given start and end location.
985   ///
986   /// \param StartLoc Starting location of the directive kind.
987   /// \param EndLoc Ending location of the directive.
988   ///
OMPMasterDirective(SourceLocation StartLoc,SourceLocation EndLoc)989   OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
990       : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
991                                StartLoc, EndLoc, 0, 1) {}
992 
993   /// \brief Build an empty directive.
994   ///
OMPMasterDirective()995   explicit OMPMasterDirective()
996       : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
997                                SourceLocation(), SourceLocation(), 0, 1) {}
998 
999 public:
1000   /// \brief Creates directive.
1001   ///
1002   /// \param C AST context.
1003   /// \param StartLoc Starting location of the directive kind.
1004   /// \param EndLoc Ending Location of the directive.
1005   /// \param AssociatedStmt Statement, associated with the directive.
1006   ///
1007   static OMPMasterDirective *Create(const ASTContext &C,
1008                                     SourceLocation StartLoc,
1009                                     SourceLocation EndLoc,
1010                                     Stmt *AssociatedStmt);
1011 
1012   /// \brief Creates an empty directive.
1013   ///
1014   /// \param C AST context.
1015   ///
1016   static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1017 
classof(const Stmt * T)1018   static bool classof(const Stmt *T) {
1019     return T->getStmtClass() == OMPMasterDirectiveClass;
1020   }
1021 };
1022 
1023 /// \brief This represents '#pragma omp critical' directive.
1024 ///
1025 /// \code
1026 /// #pragma omp critical
1027 /// \endcode
1028 ///
1029 class OMPCriticalDirective : public OMPExecutableDirective {
1030   friend class ASTStmtReader;
1031   /// \brief Name of the directive.
1032   DeclarationNameInfo DirName;
1033   /// \brief Build directive with the given start and end location.
1034   ///
1035   /// \param Name Name of the directive.
1036   /// \param StartLoc Starting location of the directive kind.
1037   /// \param EndLoc Ending location of the directive.
1038   ///
OMPCriticalDirective(const DeclarationNameInfo & Name,SourceLocation StartLoc,SourceLocation EndLoc)1039   OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
1040                        SourceLocation EndLoc)
1041       : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
1042                                StartLoc, EndLoc, 0, 1),
1043         DirName(Name) {}
1044 
1045   /// \brief Build an empty directive.
1046   ///
OMPCriticalDirective()1047   explicit OMPCriticalDirective()
1048       : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
1049                                SourceLocation(), SourceLocation(), 0, 1),
1050         DirName() {}
1051 
1052   /// \brief Set name of the directive.
1053   ///
1054   /// \param Name Name of the directive.
1055   ///
setDirectiveName(const DeclarationNameInfo & Name)1056   void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
1057 
1058 public:
1059   /// \brief Creates directive.
1060   ///
1061   /// \param C AST context.
1062   /// \param Name Name of the directive.
1063   /// \param StartLoc Starting location of the directive kind.
1064   /// \param EndLoc Ending Location of the directive.
1065   /// \param AssociatedStmt Statement, associated with the directive.
1066   ///
1067   static OMPCriticalDirective *
1068   Create(const ASTContext &C, const DeclarationNameInfo &Name,
1069          SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt);
1070 
1071   /// \brief Creates an empty directive.
1072   ///
1073   /// \param C AST context.
1074   ///
1075   static OMPCriticalDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1076 
1077   /// \brief Return name of the directive.
1078   ///
getDirectiveName()1079   DeclarationNameInfo getDirectiveName() const { return DirName; }
1080 
classof(const Stmt * T)1081   static bool classof(const Stmt *T) {
1082     return T->getStmtClass() == OMPCriticalDirectiveClass;
1083   }
1084 };
1085 
1086 /// \brief This represents '#pragma omp parallel for' directive.
1087 ///
1088 /// \code
1089 /// #pragma omp parallel for private(a,b) reduction(+:c,d)
1090 /// \endcode
1091 /// In this example directive '#pragma omp parallel for' has clauses 'private'
1092 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
1093 /// variables 'c' and 'd'.
1094 ///
1095 class OMPParallelForDirective : public OMPLoopDirective {
1096   friend class ASTStmtReader;
1097   /// \brief Build directive with the given start and end location.
1098   ///
1099   /// \param StartLoc Starting location of the directive kind.
1100   /// \param EndLoc Ending location of the directive.
1101   /// \param CollapsedNum Number of collapsed nested loops.
1102   /// \param NumClauses Number of clauses.
1103   ///
OMPParallelForDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)1104   OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1105                           unsigned CollapsedNum, unsigned NumClauses)
1106       : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
1107                          StartLoc, EndLoc, CollapsedNum, NumClauses) {}
1108 
1109   /// \brief Build an empty directive.
1110   ///
1111   /// \param CollapsedNum Number of collapsed nested loops.
1112   /// \param NumClauses Number of clauses.
1113   ///
OMPParallelForDirective(unsigned CollapsedNum,unsigned NumClauses)1114   explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
1115       : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
1116                          SourceLocation(), SourceLocation(), CollapsedNum,
1117                          NumClauses) {}
1118 
1119 public:
1120   /// \brief Creates directive with a list of \a Clauses.
1121   ///
1122   /// \param C AST context.
1123   /// \param StartLoc Starting location of the directive kind.
1124   /// \param EndLoc Ending Location of the directive.
1125   /// \param CollapsedNum Number of collapsed loops.
1126   /// \param Clauses List of clauses.
1127   /// \param AssociatedStmt Statement, associated with the directive.
1128   /// \param Exprs Helper expressions for CodeGen.
1129   ///
1130   static OMPParallelForDirective *
1131   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1132          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1133          Stmt *AssociatedStmt, const HelperExprs &Exprs);
1134 
1135   /// \brief Creates an empty directive with the place
1136   /// for \a NumClauses clauses.
1137   ///
1138   /// \param C AST context.
1139   /// \param CollapsedNum Number of collapsed nested loops.
1140   /// \param NumClauses Number of clauses.
1141   ///
1142   static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
1143                                               unsigned NumClauses,
1144                                               unsigned CollapsedNum,
1145                                               EmptyShell);
1146 
classof(const Stmt * T)1147   static bool classof(const Stmt *T) {
1148     return T->getStmtClass() == OMPParallelForDirectiveClass;
1149   }
1150 };
1151 
1152 /// \brief This represents '#pragma omp parallel for simd' directive.
1153 ///
1154 /// \code
1155 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
1156 /// \endcode
1157 /// In this example directive '#pragma omp parallel for simd' has clauses
1158 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
1159 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and
1160 /// 'd'.
1161 ///
1162 class OMPParallelForSimdDirective : public OMPLoopDirective {
1163   friend class ASTStmtReader;
1164   /// \brief Build directive with the given start and end location.
1165   ///
1166   /// \param StartLoc Starting location of the directive kind.
1167   /// \param EndLoc Ending location of the directive.
1168   /// \param CollapsedNum Number of collapsed nested loops.
1169   /// \param NumClauses Number of clauses.
1170   ///
OMPParallelForSimdDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned CollapsedNum,unsigned NumClauses)1171   OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1172                               unsigned CollapsedNum, unsigned NumClauses)
1173       : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
1174                          OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum,
1175                          NumClauses) {}
1176 
1177   /// \brief Build an empty directive.
1178   ///
1179   /// \param CollapsedNum Number of collapsed nested loops.
1180   /// \param NumClauses Number of clauses.
1181   ///
OMPParallelForSimdDirective(unsigned CollapsedNum,unsigned NumClauses)1182   explicit OMPParallelForSimdDirective(unsigned CollapsedNum,
1183                                        unsigned NumClauses)
1184       : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
1185                          OMPD_parallel_for_simd, SourceLocation(),
1186                          SourceLocation(), CollapsedNum, NumClauses) {}
1187 
1188 public:
1189   /// \brief Creates directive with a list of \a Clauses.
1190   ///
1191   /// \param C AST context.
1192   /// \param StartLoc Starting location of the directive kind.
1193   /// \param EndLoc Ending Location of the directive.
1194   /// \param CollapsedNum Number of collapsed loops.
1195   /// \param Clauses List of clauses.
1196   /// \param AssociatedStmt Statement, associated with the directive.
1197   /// \param Exprs Helper expressions for CodeGen.
1198   ///
1199   static OMPParallelForSimdDirective *
1200   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1201          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
1202          Stmt *AssociatedStmt, const HelperExprs &Exprs);
1203 
1204   /// \brief Creates an empty directive with the place
1205   /// for \a NumClauses clauses.
1206   ///
1207   /// \param C AST context.
1208   /// \param CollapsedNum Number of collapsed nested loops.
1209   /// \param NumClauses Number of clauses.
1210   ///
1211   static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
1212                                                   unsigned NumClauses,
1213                                                   unsigned CollapsedNum,
1214                                                   EmptyShell);
1215 
classof(const Stmt * T)1216   static bool classof(const Stmt *T) {
1217     return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
1218   }
1219 };
1220 
1221 /// \brief This represents '#pragma omp parallel sections' directive.
1222 ///
1223 /// \code
1224 /// #pragma omp parallel sections private(a,b) reduction(+:c,d)
1225 /// \endcode
1226 /// In this example directive '#pragma omp parallel sections' has clauses
1227 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
1228 /// and variables 'c' and 'd'.
1229 ///
1230 class OMPParallelSectionsDirective : public OMPExecutableDirective {
1231   friend class ASTStmtReader;
1232   /// \brief Build directive with the given start and end location.
1233   ///
1234   /// \param StartLoc Starting location of the directive kind.
1235   /// \param EndLoc Ending location of the directive.
1236   /// \param NumClauses Number of clauses.
1237   ///
OMPParallelSectionsDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1238   OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1239                                unsigned NumClauses)
1240       : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
1241                                OMPD_parallel_sections, StartLoc, EndLoc,
1242                                NumClauses, 1) {}
1243 
1244   /// \brief Build an empty directive.
1245   ///
1246   /// \param NumClauses Number of clauses.
1247   ///
OMPParallelSectionsDirective(unsigned NumClauses)1248   explicit OMPParallelSectionsDirective(unsigned NumClauses)
1249       : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
1250                                OMPD_parallel_sections, SourceLocation(),
1251                                SourceLocation(), NumClauses, 1) {}
1252 
1253 public:
1254   /// \brief Creates directive with a list of \a Clauses.
1255   ///
1256   /// \param C AST context.
1257   /// \param StartLoc Starting location of the directive kind.
1258   /// \param EndLoc Ending Location of the directive.
1259   /// \param Clauses List of clauses.
1260   /// \param AssociatedStmt Statement, associated with the directive.
1261   ///
1262   static OMPParallelSectionsDirective *
1263   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1264          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1265 
1266   /// \brief Creates an empty directive with the place for \a NumClauses
1267   /// clauses.
1268   ///
1269   /// \param C AST context.
1270   /// \param NumClauses Number of clauses.
1271   ///
1272   static OMPParallelSectionsDirective *
1273   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
1274 
classof(const Stmt * T)1275   static bool classof(const Stmt *T) {
1276     return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
1277   }
1278 };
1279 
1280 /// \brief This represents '#pragma omp task' directive.
1281 ///
1282 /// \code
1283 /// #pragma omp task private(a,b) final(d)
1284 /// \endcode
1285 /// In this example directive '#pragma omp task' has clauses 'private' with the
1286 /// variables 'a' and 'b' and 'final' with condition 'd'.
1287 ///
1288 class OMPTaskDirective : public OMPExecutableDirective {
1289   friend class ASTStmtReader;
1290   /// \brief Build directive with the given start and end location.
1291   ///
1292   /// \param StartLoc Starting location of the directive kind.
1293   /// \param EndLoc Ending location of the directive.
1294   /// \param NumClauses Number of clauses.
1295   ///
OMPTaskDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1296   OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1297                    unsigned NumClauses)
1298       : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
1299                                EndLoc, NumClauses, 1) {}
1300 
1301   /// \brief Build an empty directive.
1302   ///
1303   /// \param NumClauses Number of clauses.
1304   ///
OMPTaskDirective(unsigned NumClauses)1305   explicit OMPTaskDirective(unsigned NumClauses)
1306       : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
1307                                SourceLocation(), SourceLocation(), NumClauses,
1308                                1) {}
1309 
1310 public:
1311   /// \brief Creates directive with a list of \a Clauses.
1312   ///
1313   /// \param C AST context.
1314   /// \param StartLoc Starting location of the directive kind.
1315   /// \param EndLoc Ending Location of the directive.
1316   /// \param Clauses List of clauses.
1317   /// \param AssociatedStmt Statement, associated with the directive.
1318   ///
1319   static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1320                                   SourceLocation EndLoc,
1321                                   ArrayRef<OMPClause *> Clauses,
1322                                   Stmt *AssociatedStmt);
1323 
1324   /// \brief Creates an empty directive with the place for \a NumClauses
1325   /// clauses.
1326   ///
1327   /// \param C AST context.
1328   /// \param NumClauses Number of clauses.
1329   ///
1330   static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
1331                                        EmptyShell);
1332 
classof(const Stmt * T)1333   static bool classof(const Stmt *T) {
1334     return T->getStmtClass() == OMPTaskDirectiveClass;
1335   }
1336 };
1337 
1338 /// \brief This represents '#pragma omp taskyield' directive.
1339 ///
1340 /// \code
1341 /// #pragma omp taskyield
1342 /// \endcode
1343 ///
1344 class OMPTaskyieldDirective : public OMPExecutableDirective {
1345   friend class ASTStmtReader;
1346   /// \brief Build directive with the given start and end location.
1347   ///
1348   /// \param StartLoc Starting location of the directive kind.
1349   /// \param EndLoc Ending location of the directive.
1350   ///
OMPTaskyieldDirective(SourceLocation StartLoc,SourceLocation EndLoc)1351   OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1352       : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
1353                                StartLoc, EndLoc, 0, 0) {}
1354 
1355   /// \brief Build an empty directive.
1356   ///
OMPTaskyieldDirective()1357   explicit OMPTaskyieldDirective()
1358       : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
1359                                SourceLocation(), SourceLocation(), 0, 0) {}
1360 
1361 public:
1362   /// \brief Creates directive.
1363   ///
1364   /// \param C AST context.
1365   /// \param StartLoc Starting location of the directive kind.
1366   /// \param EndLoc Ending Location of the directive.
1367   ///
1368   static OMPTaskyieldDirective *
1369   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1370 
1371   /// \brief Creates an empty directive.
1372   ///
1373   /// \param C AST context.
1374   ///
1375   static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1376 
classof(const Stmt * T)1377   static bool classof(const Stmt *T) {
1378     return T->getStmtClass() == OMPTaskyieldDirectiveClass;
1379   }
1380 };
1381 
1382 /// \brief This represents '#pragma omp barrier' directive.
1383 ///
1384 /// \code
1385 /// #pragma omp barrier
1386 /// \endcode
1387 ///
1388 class OMPBarrierDirective : public OMPExecutableDirective {
1389   friend class ASTStmtReader;
1390   /// \brief Build directive with the given start and end location.
1391   ///
1392   /// \param StartLoc Starting location of the directive kind.
1393   /// \param EndLoc Ending location of the directive.
1394   ///
OMPBarrierDirective(SourceLocation StartLoc,SourceLocation EndLoc)1395   OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1396       : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
1397                                StartLoc, EndLoc, 0, 0) {}
1398 
1399   /// \brief Build an empty directive.
1400   ///
OMPBarrierDirective()1401   explicit OMPBarrierDirective()
1402       : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
1403                                SourceLocation(), SourceLocation(), 0, 0) {}
1404 
1405 public:
1406   /// \brief Creates directive.
1407   ///
1408   /// \param C AST context.
1409   /// \param StartLoc Starting location of the directive kind.
1410   /// \param EndLoc Ending Location of the directive.
1411   ///
1412   static OMPBarrierDirective *
1413   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1414 
1415   /// \brief Creates an empty directive.
1416   ///
1417   /// \param C AST context.
1418   ///
1419   static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1420 
classof(const Stmt * T)1421   static bool classof(const Stmt *T) {
1422     return T->getStmtClass() == OMPBarrierDirectiveClass;
1423   }
1424 };
1425 
1426 /// \brief This represents '#pragma omp taskwait' directive.
1427 ///
1428 /// \code
1429 /// #pragma omp taskwait
1430 /// \endcode
1431 ///
1432 class OMPTaskwaitDirective : public OMPExecutableDirective {
1433   friend class ASTStmtReader;
1434   /// \brief Build directive with the given start and end location.
1435   ///
1436   /// \param StartLoc Starting location of the directive kind.
1437   /// \param EndLoc Ending location of the directive.
1438   ///
OMPTaskwaitDirective(SourceLocation StartLoc,SourceLocation EndLoc)1439   OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1440       : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
1441                                StartLoc, EndLoc, 0, 0) {}
1442 
1443   /// \brief Build an empty directive.
1444   ///
OMPTaskwaitDirective()1445   explicit OMPTaskwaitDirective()
1446       : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
1447                                SourceLocation(), SourceLocation(), 0, 0) {}
1448 
1449 public:
1450   /// \brief Creates directive.
1451   ///
1452   /// \param C AST context.
1453   /// \param StartLoc Starting location of the directive kind.
1454   /// \param EndLoc Ending Location of the directive.
1455   ///
1456   static OMPTaskwaitDirective *
1457   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
1458 
1459   /// \brief Creates an empty directive.
1460   ///
1461   /// \param C AST context.
1462   ///
1463   static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1464 
classof(const Stmt * T)1465   static bool classof(const Stmt *T) {
1466     return T->getStmtClass() == OMPTaskwaitDirectiveClass;
1467   }
1468 };
1469 
1470 /// \brief This represents '#pragma omp flush' directive.
1471 ///
1472 /// \code
1473 /// #pragma omp flush(a,b)
1474 /// \endcode
1475 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
1476 /// and 'b'.
1477 /// 'omp flush' directive does not have clauses but have an optional list of
1478 /// variables to flush. This list of variables is stored within some fake clause
1479 /// FlushClause.
1480 class OMPFlushDirective : public OMPExecutableDirective {
1481   friend class ASTStmtReader;
1482   /// \brief Build directive with the given start and end location.
1483   ///
1484   /// \param StartLoc Starting location of the directive kind.
1485   /// \param EndLoc Ending location of the directive.
1486   /// \param NumClauses Number of clauses.
1487   ///
OMPFlushDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1488   OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1489                     unsigned NumClauses)
1490       : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
1491                                StartLoc, EndLoc, NumClauses, 0) {}
1492 
1493   /// \brief Build an empty directive.
1494   ///
1495   /// \param NumClauses Number of clauses.
1496   ///
OMPFlushDirective(unsigned NumClauses)1497   explicit OMPFlushDirective(unsigned NumClauses)
1498       : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
1499                                SourceLocation(), SourceLocation(), NumClauses,
1500                                0) {}
1501 
1502 public:
1503   /// \brief Creates directive with a list of \a Clauses.
1504   ///
1505   /// \param C AST context.
1506   /// \param StartLoc Starting location of the directive kind.
1507   /// \param EndLoc Ending Location of the directive.
1508   /// \param Clauses List of clauses (only single OMPFlushClause clause is
1509   /// allowed).
1510   ///
1511   static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1512                                    SourceLocation EndLoc,
1513                                    ArrayRef<OMPClause *> Clauses);
1514 
1515   /// \brief Creates an empty directive with the place for \a NumClauses
1516   /// clauses.
1517   ///
1518   /// \param C AST context.
1519   /// \param NumClauses Number of clauses.
1520   ///
1521   static OMPFlushDirective *CreateEmpty(const ASTContext &C,
1522                                         unsigned NumClauses, EmptyShell);
1523 
classof(const Stmt * T)1524   static bool classof(const Stmt *T) {
1525     return T->getStmtClass() == OMPFlushDirectiveClass;
1526   }
1527 };
1528 
1529 /// \brief This represents '#pragma omp ordered' directive.
1530 ///
1531 /// \code
1532 /// #pragma omp ordered
1533 /// \endcode
1534 ///
1535 class OMPOrderedDirective : public OMPExecutableDirective {
1536   friend class ASTStmtReader;
1537   /// \brief Build directive with the given start and end location.
1538   ///
1539   /// \param StartLoc Starting location of the directive kind.
1540   /// \param EndLoc Ending location of the directive.
1541   ///
OMPOrderedDirective(SourceLocation StartLoc,SourceLocation EndLoc)1542   OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
1543       : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
1544                                StartLoc, EndLoc, 0, 1) {}
1545 
1546   /// \brief Build an empty directive.
1547   ///
OMPOrderedDirective()1548   explicit OMPOrderedDirective()
1549       : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
1550                                SourceLocation(), SourceLocation(), 0, 1) {}
1551 
1552 public:
1553   /// \brief Creates directive.
1554   ///
1555   /// \param C AST context.
1556   /// \param StartLoc Starting location of the directive kind.
1557   /// \param EndLoc Ending Location of the directive.
1558   /// \param AssociatedStmt Statement, associated with the directive.
1559   ///
1560   static OMPOrderedDirective *Create(const ASTContext &C,
1561                                      SourceLocation StartLoc,
1562                                      SourceLocation EndLoc,
1563                                      Stmt *AssociatedStmt);
1564 
1565   /// \brief Creates an empty directive.
1566   ///
1567   /// \param C AST context.
1568   ///
1569   static OMPOrderedDirective *CreateEmpty(const ASTContext &C, EmptyShell);
1570 
classof(const Stmt * T)1571   static bool classof(const Stmt *T) {
1572     return T->getStmtClass() == OMPOrderedDirectiveClass;
1573   }
1574 };
1575 
1576 /// \brief This represents '#pragma omp atomic' directive.
1577 ///
1578 /// \code
1579 /// #pragma omp atomic capture
1580 /// \endcode
1581 /// In this example directive '#pragma omp atomic' has clause 'capture'.
1582 ///
1583 class OMPAtomicDirective : public OMPExecutableDirective {
1584   friend class ASTStmtReader;
1585   /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
1586   /// have atomic expressions of forms
1587   /// \code
1588   /// x = x binop expr;
1589   /// x = expr binop x;
1590   /// \endcode
1591   /// This field is true for the first form of the expression and false for the
1592   /// second. Required for correct codegen of non-associative operations (like
1593   /// << or >>).
1594   bool IsXLHSInRHSPart;
1595   /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
1596   /// have atomic expressions of forms
1597   /// \code
1598   /// v = x; <update x>;
1599   /// <update x>; v = x;
1600   /// \endcode
1601   /// This field is true for the first(postfix) form of the expression and false
1602   /// otherwise.
1603   bool IsPostfixUpdate;
1604 
1605   /// \brief Build directive with the given start and end location.
1606   ///
1607   /// \param StartLoc Starting location of the directive kind.
1608   /// \param EndLoc Ending location of the directive.
1609   /// \param NumClauses Number of clauses.
1610   ///
OMPAtomicDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1611   OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1612                      unsigned NumClauses)
1613       : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
1614                                StartLoc, EndLoc, NumClauses, 5),
1615         IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
1616 
1617   /// \brief Build an empty directive.
1618   ///
1619   /// \param NumClauses Number of clauses.
1620   ///
OMPAtomicDirective(unsigned NumClauses)1621   explicit OMPAtomicDirective(unsigned NumClauses)
1622       : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
1623                                SourceLocation(), SourceLocation(), NumClauses,
1624                                5),
1625         IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
1626 
1627   /// \brief Set 'x' part of the associated expression/statement.
setX(Expr * X)1628   void setX(Expr *X) { *std::next(child_begin()) = X; }
1629   /// \brief Set helper expression of the form
1630   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1631   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
setUpdateExpr(Expr * UE)1632   void setUpdateExpr(Expr *UE) { *std::next(child_begin(), 2) = UE; }
1633   /// \brief Set 'v' part of the associated expression/statement.
setV(Expr * V)1634   void setV(Expr *V) { *std::next(child_begin(), 3) = V; }
1635   /// \brief Set 'expr' part of the associated expression/statement.
setExpr(Expr * E)1636   void setExpr(Expr *E) { *std::next(child_begin(), 4) = E; }
1637 
1638 public:
1639   /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
1640   /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
1641   /// detailed description of 'x', 'v' and 'expr').
1642   ///
1643   /// \param C AST context.
1644   /// \param StartLoc Starting location of the directive kind.
1645   /// \param EndLoc Ending Location of the directive.
1646   /// \param Clauses List of clauses.
1647   /// \param AssociatedStmt Statement, associated with the directive.
1648   /// \param X 'x' part of the associated expression/statement.
1649   /// \param V 'v' part of the associated expression/statement.
1650   /// \param E 'expr' part of the associated expression/statement.
1651   /// \param UE Helper expression of the form
1652   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1653   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
1654   /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the
1655   /// second.
1656   /// \param IsPostfixUpdate true if original value of 'x' must be stored in
1657   /// 'v', not an updated one.
1658   static OMPAtomicDirective *
1659   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1660          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
1661          Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate);
1662 
1663   /// \brief Creates an empty directive with the place for \a NumClauses
1664   /// clauses.
1665   ///
1666   /// \param C AST context.
1667   /// \param NumClauses Number of clauses.
1668   ///
1669   static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
1670                                          unsigned NumClauses, EmptyShell);
1671 
1672   /// \brief Get 'x' part of the associated expression/statement.
getX()1673   Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); }
getX()1674   const Expr *getX() const {
1675     return cast_or_null<Expr>(*std::next(child_begin()));
1676   }
1677   /// \brief Get helper expression of the form
1678   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
1679   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
getUpdateExpr()1680   Expr *getUpdateExpr() {
1681     return cast_or_null<Expr>(*std::next(child_begin(), 2));
1682   }
getUpdateExpr()1683   const Expr *getUpdateExpr() const {
1684     return cast_or_null<Expr>(*std::next(child_begin(), 2));
1685   }
1686   /// \brief Return true if helper update expression has form
1687   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
1688   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
isXLHSInRHSPart()1689   bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
1690   /// \brief Return true if 'v' expression must be updated to original value of
1691   /// 'x', false if 'v' must be updated to the new value of 'x'.
isPostfixUpdate()1692   bool isPostfixUpdate() const { return IsPostfixUpdate; }
1693   /// \brief Get 'v' part of the associated expression/statement.
getV()1694   Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); }
getV()1695   const Expr *getV() const {
1696     return cast_or_null<Expr>(*std::next(child_begin(), 3));
1697   }
1698   /// \brief Get 'expr' part of the associated expression/statement.
getExpr()1699   Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 4)); }
getExpr()1700   const Expr *getExpr() const {
1701     return cast_or_null<Expr>(*std::next(child_begin(), 4));
1702   }
1703 
classof(const Stmt * T)1704   static bool classof(const Stmt *T) {
1705     return T->getStmtClass() == OMPAtomicDirectiveClass;
1706   }
1707 };
1708 
1709 /// \brief This represents '#pragma omp target' directive.
1710 ///
1711 /// \code
1712 /// #pragma omp target if(a)
1713 /// \endcode
1714 /// In this example directive '#pragma omp target' has clause 'if' with
1715 /// condition 'a'.
1716 ///
1717 class OMPTargetDirective : public OMPExecutableDirective {
1718   friend class ASTStmtReader;
1719   /// \brief Build directive with the given start and end location.
1720   ///
1721   /// \param StartLoc Starting location of the directive kind.
1722   /// \param EndLoc Ending location of the directive.
1723   /// \param NumClauses Number of clauses.
1724   ///
OMPTargetDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1725   OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1726                      unsigned NumClauses)
1727       : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
1728                                StartLoc, EndLoc, NumClauses, 1) {}
1729 
1730   /// \brief Build an empty directive.
1731   ///
1732   /// \param NumClauses Number of clauses.
1733   ///
OMPTargetDirective(unsigned NumClauses)1734   explicit OMPTargetDirective(unsigned NumClauses)
1735       : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
1736                                SourceLocation(), SourceLocation(), NumClauses,
1737                                1) {}
1738 
1739 public:
1740   /// \brief Creates directive with a list of \a Clauses.
1741   ///
1742   /// \param C AST context.
1743   /// \param StartLoc Starting location of the directive kind.
1744   /// \param EndLoc Ending Location of the directive.
1745   /// \param Clauses List of clauses.
1746   /// \param AssociatedStmt Statement, associated with the directive.
1747   ///
1748   static OMPTargetDirective *
1749   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
1750          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
1751 
1752   /// \brief Creates an empty directive with the place for \a NumClauses
1753   /// clauses.
1754   ///
1755   /// \param C AST context.
1756   /// \param NumClauses Number of clauses.
1757   ///
1758   static OMPTargetDirective *CreateEmpty(const ASTContext &C,
1759                                          unsigned NumClauses, EmptyShell);
1760 
classof(const Stmt * T)1761   static bool classof(const Stmt *T) {
1762     return T->getStmtClass() == OMPTargetDirectiveClass;
1763   }
1764 };
1765 
1766 /// \brief This represents '#pragma omp teams' directive.
1767 ///
1768 /// \code
1769 /// #pragma omp teams if(a)
1770 /// \endcode
1771 /// In this example directive '#pragma omp teams' has clause 'if' with
1772 /// condition 'a'.
1773 ///
1774 class OMPTeamsDirective : public OMPExecutableDirective {
1775   friend class ASTStmtReader;
1776   /// \brief Build directive with the given start and end location.
1777   ///
1778   /// \param StartLoc Starting location of the directive kind.
1779   /// \param EndLoc Ending location of the directive.
1780   /// \param NumClauses Number of clauses.
1781   ///
OMPTeamsDirective(SourceLocation StartLoc,SourceLocation EndLoc,unsigned NumClauses)1782   OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
1783                     unsigned NumClauses)
1784       : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
1785                                StartLoc, EndLoc, NumClauses, 1) {}
1786 
1787   /// \brief Build an empty directive.
1788   ///
1789   /// \param NumClauses Number of clauses.
1790   ///
OMPTeamsDirective(unsigned NumClauses)1791   explicit OMPTeamsDirective(unsigned NumClauses)
1792       : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
1793                                SourceLocation(), SourceLocation(), NumClauses,
1794                                1) {}
1795 
1796 public:
1797   /// \brief Creates directive with a list of \a Clauses.
1798   ///
1799   /// \param C AST context.
1800   /// \param StartLoc Starting location of the directive kind.
1801   /// \param EndLoc Ending Location of the directive.
1802   /// \param Clauses List of clauses.
1803   /// \param AssociatedStmt Statement, associated with the directive.
1804   ///
1805   static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
1806                                    SourceLocation EndLoc,
1807                                    ArrayRef<OMPClause *> Clauses,
1808                                    Stmt *AssociatedStmt);
1809 
1810   /// \brief Creates an empty directive with the place for \a NumClauses
1811   /// clauses.
1812   ///
1813   /// \param C AST context.
1814   /// \param NumClauses Number of clauses.
1815   ///
1816   static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
1817                                         unsigned NumClauses, EmptyShell);
1818 
classof(const Stmt * T)1819   static bool classof(const Stmt *T) {
1820     return T->getStmtClass() == OMPTeamsDirectiveClass;
1821   }
1822 };
1823 
1824 } // end namespace clang
1825 
1826 #endif
1827