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