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) { *child_begin() = S; }
87
88public:
89  /// \brief Iterates over a filtered subrange of clauses applied to a
90  /// directive.
91  ///
92  /// This iterator visits only those declarations that meet some run-time
93  /// criteria.
94  template <class FilterPredicate> class filtered_clause_iterator {
95    ArrayRef<OMPClause *>::const_iterator Current;
96    ArrayRef<OMPClause *>::const_iterator End;
97    FilterPredicate Pred;
98    void SkipToNextClause() {
99      while (Current != End && !Pred(*Current))
100        ++Current;
101    }
102
103  public:
104    typedef const OMPClause *value_type;
105    filtered_clause_iterator() : Current(), End() {}
106    filtered_clause_iterator(ArrayRef<OMPClause *> Arr, FilterPredicate Pred)
107        : Current(Arr.begin()), End(Arr.end()), Pred(Pred) {
108      SkipToNextClause();
109    }
110    value_type operator*() const { return *Current; }
111    value_type operator->() const { return *Current; }
112    filtered_clause_iterator &operator++() {
113      ++Current;
114      SkipToNextClause();
115      return *this;
116    }
117
118    filtered_clause_iterator operator++(int) {
119      filtered_clause_iterator tmp(*this);
120      ++(*this);
121      return tmp;
122    }
123
124    bool operator!() { return Current == End; }
125    operator bool() { return Current != End; }
126  };
127
128  /// \brief Returns starting location of directive kind.
129  SourceLocation getLocStart() const { return StartLoc; }
130  /// \brief Returns ending location of directive.
131  SourceLocation getLocEnd() const { return EndLoc; }
132
133  /// \brief Set starting location of directive kind.
134  ///
135  /// \param Loc New starting location of directive.
136  ///
137  void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
138  /// \brief Set ending location of directive.
139  ///
140  /// \param Loc New ending location of directive.
141  ///
142  void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
143
144  /// \brief Get number of clauses.
145  unsigned getNumClauses() const { return NumClauses; }
146
147  /// \brief Returns specified clause.
148  ///
149  /// \param i Number of clause.
150  ///
151  OMPClause *getClause(unsigned i) const { return clauses()[i]; }
152
153  /// \brief Returns statement associated with the directive.
154  Stmt *getAssociatedStmt() const { return const_cast<Stmt *>(*child_begin()); }
155
156  OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
157
158  static bool classof(const Stmt *S) {
159    return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
160           S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
161  }
162
163  child_range children() {
164    Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
165    return child_range(ChildStorage, ChildStorage + NumChildren);
166  }
167
168  ArrayRef<OMPClause *> clauses() { return getClauses(); }
169
170  ArrayRef<OMPClause *> clauses() const {
171    return const_cast<OMPExecutableDirective *>(this)->getClauses();
172  }
173};
174
175/// \brief This represents '#pragma omp parallel' directive.
176///
177/// \code
178/// #pragma omp parallel private(a,b) reduction(+: c,d)
179/// \endcode
180/// In this example directive '#pragma omp parallel' has clauses 'private'
181/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
182/// variables 'c' and 'd'.
183///
184class OMPParallelDirective : public OMPExecutableDirective {
185  /// \brief Build directive with the given start and end location.
186  ///
187  /// \param StartLoc Starting location of the directive (directive keyword).
188  /// \param EndLoc Ending Location of the directive.
189  ///
190  OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
191                       unsigned NumClauses)
192      : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
193                               StartLoc, EndLoc, NumClauses, 1) {}
194
195  /// \brief Build an empty directive.
196  ///
197  /// \param NumClauses Number of clauses.
198  ///
199  explicit OMPParallelDirective(unsigned NumClauses)
200      : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
201                               SourceLocation(), SourceLocation(), NumClauses,
202                               1) {}
203
204public:
205  /// \brief Creates directive with a list of \a Clauses.
206  ///
207  /// \param C AST context.
208  /// \param StartLoc Starting location of the directive kind.
209  /// \param EndLoc Ending Location of the directive.
210  /// \param Clauses List of clauses.
211  /// \param AssociatedStmt Statement associated with the directive.
212  ///
213  static OMPParallelDirective *
214  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
215         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
216
217  /// \brief Creates an empty directive with the place for \a N clauses.
218  ///
219  /// \param C AST context.
220  /// \param NumClauses Number of clauses.
221  ///
222  static OMPParallelDirective *CreateEmpty(const ASTContext &C,
223                                           unsigned NumClauses, EmptyShell);
224
225  static bool classof(const Stmt *T) {
226    return T->getStmtClass() == OMPParallelDirectiveClass;
227  }
228};
229
230/// \brief This represents '#pragma omp simd' directive.
231///
232/// \code
233/// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
234/// \endcode
235/// In this example directive '#pragma omp simd' has clauses 'private'
236/// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
237/// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
238///
239class OMPSimdDirective : public OMPExecutableDirective {
240  friend class ASTStmtReader;
241  /// \brief Number of collapsed loops as specified by 'collapse' clause.
242  unsigned CollapsedNum;
243  /// \brief Build directive with the given start and end location.
244  ///
245  /// \param StartLoc Starting location of the directive kind.
246  /// \param EndLoc Ending location of the directive.
247  /// \param CollapsedNum Number of collapsed nested loops.
248  /// \param NumClauses Number of clauses.
249  ///
250  OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
251                   unsigned CollapsedNum, unsigned NumClauses)
252      : OMPExecutableDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
253                               EndLoc, NumClauses, 1),
254        CollapsedNum(CollapsedNum) {}
255
256  /// \brief Build an empty directive.
257  ///
258  /// \param CollapsedNum Number of collapsed nested loops.
259  /// \param NumClauses Number of clauses.
260  ///
261  explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
262      : OMPExecutableDirective(this, OMPSimdDirectiveClass, OMPD_simd,
263                               SourceLocation(), SourceLocation(), NumClauses,
264                               1),
265        CollapsedNum(CollapsedNum) {}
266
267public:
268  /// \brief Creates directive with a list of \a Clauses.
269  ///
270  /// \param C AST context.
271  /// \param StartLoc Starting location of the directive kind.
272  /// \param EndLoc Ending Location of the directive.
273  /// \param CollapsedNum Number of collapsed loops.
274  /// \param Clauses List of clauses.
275  /// \param AssociatedStmt Statement, associated with the directive.
276  ///
277  static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
278                                  SourceLocation EndLoc, unsigned CollapsedNum,
279                                  ArrayRef<OMPClause *> Clauses,
280                                  Stmt *AssociatedStmt);
281
282  /// \brief Creates an empty directive with the place
283  /// for \a NumClauses clauses.
284  ///
285  /// \param C AST context.
286  /// \param CollapsedNum Number of collapsed nested loops.
287  /// \param NumClauses Number of clauses.
288  ///
289  static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
290                                       unsigned CollapsedNum, EmptyShell);
291
292  unsigned getCollapsedNumber() const { return CollapsedNum; }
293
294  static bool classof(const Stmt *T) {
295    return T->getStmtClass() == OMPSimdDirectiveClass;
296  }
297};
298
299/// \brief This represents '#pragma omp for' directive.
300///
301/// \code
302/// #pragma omp for private(a,b) reduction(+:c,d)
303/// \endcode
304/// In this example directive '#pragma omp for' has clauses 'private' with the
305/// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
306/// and 'd'.
307///
308class OMPForDirective : public OMPExecutableDirective {
309  friend class ASTStmtReader;
310  /// \brief Number of collapsed loops as specified by 'collapse' clause.
311  unsigned CollapsedNum;
312  /// \brief Build directive with the given start and end location.
313  ///
314  /// \param StartLoc Starting location of the directive kind.
315  /// \param EndLoc Ending location of the directive.
316  /// \param CollapsedNum Number of collapsed nested loops.
317  /// \param NumClauses Number of clauses.
318  ///
319  OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
320                  unsigned CollapsedNum, unsigned NumClauses)
321      : OMPExecutableDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc,
322                               EndLoc, NumClauses, 1),
323        CollapsedNum(CollapsedNum) {}
324
325  /// \brief Build an empty directive.
326  ///
327  /// \param CollapsedNum Number of collapsed nested loops.
328  /// \param NumClauses Number of clauses.
329  ///
330  explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
331      : OMPExecutableDirective(this, OMPForDirectiveClass, OMPD_for,
332                               SourceLocation(), SourceLocation(), NumClauses,
333                               1),
334        CollapsedNum(CollapsedNum) {}
335
336public:
337  /// \brief Creates directive with a list of \a Clauses.
338  ///
339  /// \param C AST context.
340  /// \param StartLoc Starting location of the directive kind.
341  /// \param EndLoc Ending Location of the directive.
342  /// \param CollapsedNum Number of collapsed loops.
343  /// \param Clauses List of clauses.
344  /// \param AssociatedStmt Statement, associated with the directive.
345  ///
346  static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
347                                 SourceLocation EndLoc, unsigned CollapsedNum,
348                                 ArrayRef<OMPClause *> Clauses,
349                                 Stmt *AssociatedStmt);
350
351  /// \brief Creates an empty directive with the place
352  /// for \a NumClauses clauses.
353  ///
354  /// \param C AST context.
355  /// \param CollapsedNum Number of collapsed nested loops.
356  /// \param NumClauses Number of clauses.
357  ///
358  static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
359                                      unsigned CollapsedNum, EmptyShell);
360
361  unsigned getCollapsedNumber() const { return CollapsedNum; }
362
363  static bool classof(const Stmt *T) {
364    return T->getStmtClass() == OMPForDirectiveClass;
365  }
366};
367
368/// \brief This represents '#pragma omp sections' directive.
369///
370/// \code
371/// #pragma omp sections private(a,b) reduction(+:c,d)
372/// \endcode
373/// In this example directive '#pragma omp sections' has clauses 'private' with
374/// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
375/// 'c' and 'd'.
376///
377class OMPSectionsDirective : public OMPExecutableDirective {
378  friend class ASTStmtReader;
379  /// \brief Build directive with the given start and end location.
380  ///
381  /// \param StartLoc Starting location of the directive kind.
382  /// \param EndLoc Ending location of the directive.
383  /// \param NumClauses Number of clauses.
384  ///
385  OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
386                       unsigned NumClauses)
387      : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
388                               StartLoc, EndLoc, NumClauses, 1) {}
389
390  /// \brief Build an empty directive.
391  ///
392  /// \param NumClauses Number of clauses.
393  ///
394  explicit OMPSectionsDirective(unsigned NumClauses)
395      : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
396                               SourceLocation(), SourceLocation(), NumClauses,
397                               1) {}
398
399public:
400  /// \brief Creates directive with a list of \a Clauses.
401  ///
402  /// \param C AST context.
403  /// \param StartLoc Starting location of the directive kind.
404  /// \param EndLoc Ending Location of the directive.
405  /// \param Clauses List of clauses.
406  /// \param AssociatedStmt Statement, associated with the directive.
407  ///
408  static OMPSectionsDirective *
409  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
410         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
411
412  /// \brief Creates an empty directive with the place for \a NumClauses
413  /// clauses.
414  ///
415  /// \param C AST context.
416  /// \param NumClauses Number of clauses.
417  ///
418  static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
419                                           unsigned NumClauses, EmptyShell);
420
421  static bool classof(const Stmt *T) {
422    return T->getStmtClass() == OMPSectionsDirectiveClass;
423  }
424};
425
426/// \brief This represents '#pragma omp section' directive.
427///
428/// \code
429/// #pragma omp section
430/// \endcode
431///
432class OMPSectionDirective : public OMPExecutableDirective {
433  friend class ASTStmtReader;
434  /// \brief Build directive with the given start and end location.
435  ///
436  /// \param StartLoc Starting location of the directive kind.
437  /// \param EndLoc Ending location of the directive.
438  ///
439  OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
440      : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
441                               StartLoc, EndLoc, 0, 1) {}
442
443  /// \brief Build an empty directive.
444  ///
445  explicit OMPSectionDirective()
446      : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
447                               SourceLocation(), SourceLocation(), 0, 1) {}
448
449public:
450  /// \brief Creates directive.
451  ///
452  /// \param C AST context.
453  /// \param StartLoc Starting location of the directive kind.
454  /// \param EndLoc Ending Location of the directive.
455  /// \param AssociatedStmt Statement, associated with the directive.
456  ///
457  static OMPSectionDirective *Create(const ASTContext &C,
458                                     SourceLocation StartLoc,
459                                     SourceLocation EndLoc,
460                                     Stmt *AssociatedStmt);
461
462  /// \brief Creates an empty directive.
463  ///
464  /// \param C AST context.
465  ///
466  static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
467
468  static bool classof(const Stmt *T) {
469    return T->getStmtClass() == OMPSectionDirectiveClass;
470  }
471};
472
473/// \brief This represents '#pragma omp single' directive.
474///
475/// \code
476/// #pragma omp single private(a,b) copyprivate(c,d)
477/// \endcode
478/// In this example directive '#pragma omp single' has clauses 'private' with
479/// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
480///
481class OMPSingleDirective : public OMPExecutableDirective {
482  friend class ASTStmtReader;
483  /// \brief Build directive with the given start and end location.
484  ///
485  /// \param StartLoc Starting location of the directive kind.
486  /// \param EndLoc Ending location of the directive.
487  /// \param NumClauses Number of clauses.
488  ///
489  OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
490                     unsigned NumClauses)
491      : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
492                               StartLoc, EndLoc, NumClauses, 1) {}
493
494  /// \brief Build an empty directive.
495  ///
496  /// \param NumClauses Number of clauses.
497  ///
498  explicit OMPSingleDirective(unsigned NumClauses)
499      : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
500                               SourceLocation(), SourceLocation(), NumClauses,
501                               1) {}
502
503public:
504  /// \brief Creates directive with a list of \a Clauses.
505  ///
506  /// \param C AST context.
507  /// \param StartLoc Starting location of the directive kind.
508  /// \param EndLoc Ending Location of the directive.
509  /// \param Clauses List of clauses.
510  /// \param AssociatedStmt Statement, associated with the directive.
511  ///
512  static OMPSingleDirective *
513  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
514         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
515
516  /// \brief Creates an empty directive with the place for \a NumClauses
517  /// clauses.
518  ///
519  /// \param C AST context.
520  /// \param NumClauses Number of clauses.
521  ///
522  static OMPSingleDirective *CreateEmpty(const ASTContext &C,
523                                         unsigned NumClauses, EmptyShell);
524
525  static bool classof(const Stmt *T) {
526    return T->getStmtClass() == OMPSingleDirectiveClass;
527  }
528};
529
530/// \brief This represents '#pragma omp parallel for' directive.
531///
532/// \code
533/// #pragma omp parallel for private(a,b) reduction(+:c,d)
534/// \endcode
535/// In this example directive '#pragma omp parallel for' has clauses 'private'
536/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
537/// variables 'c' and 'd'.
538///
539class OMPParallelForDirective : public OMPExecutableDirective {
540  friend class ASTStmtReader;
541  /// \brief Number of collapsed loops as specified by 'collapse' clause.
542  unsigned CollapsedNum;
543  /// \brief Build directive with the given start and end location.
544  ///
545  /// \param StartLoc Starting location of the directive kind.
546  /// \param EndLoc Ending location of the directive.
547  /// \param CollapsedNum Number of collapsed nested loops.
548  /// \param NumClauses Number of clauses.
549  ///
550  OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
551                          unsigned CollapsedNum, unsigned NumClauses)
552      : OMPExecutableDirective(this, OMPParallelForDirectiveClass,
553                               OMPD_parallel_for, StartLoc, EndLoc, NumClauses,
554                               1),
555        CollapsedNum(CollapsedNum) {}
556
557  /// \brief Build an empty directive.
558  ///
559  /// \param CollapsedNum Number of collapsed nested loops.
560  /// \param NumClauses Number of clauses.
561  ///
562  explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
563      : OMPExecutableDirective(this, OMPParallelForDirectiveClass,
564                               OMPD_parallel_for, SourceLocation(),
565                               SourceLocation(), NumClauses, 1),
566        CollapsedNum(CollapsedNum) {}
567
568public:
569  /// \brief Creates directive with a list of \a Clauses.
570  ///
571  /// \param C AST context.
572  /// \param StartLoc Starting location of the directive kind.
573  /// \param EndLoc Ending Location of the directive.
574  /// \param CollapsedNum Number of collapsed loops.
575  /// \param Clauses List of clauses.
576  /// \param AssociatedStmt Statement, associated with the directive.
577  ///
578  static OMPParallelForDirective *
579  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
580         unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
581         Stmt *AssociatedStmt);
582
583  /// \brief Creates an empty directive with the place
584  /// for \a NumClauses clauses.
585  ///
586  /// \param C AST context.
587  /// \param CollapsedNum Number of collapsed nested loops.
588  /// \param NumClauses Number of clauses.
589  ///
590  static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
591                                              unsigned NumClauses,
592                                              unsigned CollapsedNum,
593                                              EmptyShell);
594
595  unsigned getCollapsedNumber() const { return CollapsedNum; }
596
597  static bool classof(const Stmt *T) {
598    return T->getStmtClass() == OMPParallelForDirectiveClass;
599  }
600};
601
602/// \brief This represents '#pragma omp parallel sections' directive.
603///
604/// \code
605/// #pragma omp parallel sections private(a,b) reduction(+:c,d)
606/// \endcode
607/// In this example directive '#pragma omp parallel sections' has clauses
608/// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
609/// and variables 'c' and 'd'.
610///
611class OMPParallelSectionsDirective : public OMPExecutableDirective {
612  friend class ASTStmtReader;
613  /// \brief Build directive with the given start and end location.
614  ///
615  /// \param StartLoc Starting location of the directive kind.
616  /// \param EndLoc Ending location of the directive.
617  /// \param NumClauses Number of clauses.
618  ///
619  OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
620                               unsigned NumClauses)
621      : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
622                               OMPD_parallel_sections, StartLoc, EndLoc,
623                               NumClauses, 1) {}
624
625  /// \brief Build an empty directive.
626  ///
627  /// \param NumClauses Number of clauses.
628  ///
629  explicit OMPParallelSectionsDirective(unsigned NumClauses)
630      : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
631                               OMPD_parallel_sections, SourceLocation(),
632                               SourceLocation(), NumClauses, 1) {}
633
634public:
635  /// \brief Creates directive with a list of \a Clauses.
636  ///
637  /// \param C AST context.
638  /// \param StartLoc Starting location of the directive kind.
639  /// \param EndLoc Ending Location of the directive.
640  /// \param Clauses List of clauses.
641  /// \param AssociatedStmt Statement, associated with the directive.
642  ///
643  static OMPParallelSectionsDirective *
644  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
645         ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
646
647  /// \brief Creates an empty directive with the place for \a NumClauses
648  /// clauses.
649  ///
650  /// \param C AST context.
651  /// \param NumClauses Number of clauses.
652  ///
653  static OMPParallelSectionsDirective *
654  CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
655
656  static bool classof(const Stmt *T) {
657    return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
658  }
659};
660
661} // end namespace clang
662
663#endif
664