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