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