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