1259701Sdim//===- StmtOpenMP.h - Classes for OpenMP directives and clauses --*- C++ -*-===//
2259701Sdim//
3259701Sdim//                     The LLVM Compiler Infrastructure
4259701Sdim//
5259701Sdim// This file is distributed under the University of Illinois Open Source
6259701Sdim// License. See LICENSE.TXT for details.
7259701Sdim//
8259701Sdim//===----------------------------------------------------------------------===//
9259701Sdim/// \file
10259701Sdim/// \brief This file defines OpenMP AST classes for executable directives and
11259701Sdim/// clauses.
12259701Sdim///
13259701Sdim//===----------------------------------------------------------------------===//
14259701Sdim
15259701Sdim#ifndef LLVM_CLANG_AST_STMTOPENMP_H
16259701Sdim#define LLVM_CLANG_AST_STMTOPENMP_H
17259701Sdim
18259701Sdim#include "clang/Basic/OpenMPKinds.h"
19259701Sdim#include "clang/Basic/SourceLocation.h"
20259701Sdim#include "clang/AST/Expr.h"
21259701Sdim#include "clang/AST/Stmt.h"
22259701Sdim
23259701Sdimnamespace clang {
24259701Sdim
25259701Sdim//===----------------------------------------------------------------------===//
26259701Sdim// AST classes for clauses.
27259701Sdim//===----------------------------------------------------------------------===//
28259701Sdim
29259701Sdim/// \brief This is a basic class for representing single OpenMP clause.
30259701Sdim///
31259701Sdimclass OMPClause {
32259701Sdim  /// \brief Starting location of the clause (the clause keyword).
33259701Sdim  SourceLocation StartLoc;
34259701Sdim  /// \brief Ending location of the clause.
35259701Sdim  SourceLocation EndLoc;
36259701Sdim  /// \brief Kind of the clause.
37259701Sdim  OpenMPClauseKind Kind;
38259701Sdimprotected:
39259701Sdim  OMPClause(OpenMPClauseKind K, SourceLocation StartLoc, SourceLocation EndLoc)
40259701Sdim    : StartLoc(StartLoc), EndLoc(EndLoc), Kind(K) {}
41259701Sdim
42259701Sdimpublic:
43259701Sdim
44259701Sdim  /// \brief Returns the starting location of the clause.
45259701Sdim  SourceLocation getLocStart() const { return StartLoc; }
46259701Sdim  /// \brief Returns the ending location of the clause.
47259701Sdim  SourceLocation getLocEnd() const { return EndLoc; }
48259701Sdim
49259701Sdim  /// \brief Sets the starting location of the clause.
50259701Sdim  void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
51259701Sdim  /// \brief Sets the ending location of the clause.
52259701Sdim  void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
53259701Sdim
54259701Sdim  /// \brief Returns kind of OpenMP clause (private, shared, reduction, etc.).
55259701Sdim  OpenMPClauseKind getClauseKind() const { return Kind; }
56259701Sdim
57259701Sdim  bool isImplicit() const { return StartLoc.isInvalid();}
58259701Sdim
59259701Sdim  StmtRange children();
60259701Sdim  ConstStmtRange children() const {
61259701Sdim    return const_cast<OMPClause *>(this)->children();
62259701Sdim  }
63259701Sdim  static bool classof(const OMPClause *T) {
64259701Sdim    return true;
65259701Sdim  }
66259701Sdim};
67259701Sdim
68259701Sdim/// \brief This represents clauses with the list of variables like 'private',
69259701Sdim/// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the
70259701Sdim/// '#pragma omp ...' directives.
71259701Sdimtemplate <class T>
72259701Sdimclass OMPVarList {
73259701Sdim  friend class OMPClauseReader;
74259701Sdim  /// \brief Location of '('.
75259701Sdim  SourceLocation LParenLoc;
76259701Sdim  /// \brief Number of variables in the list.
77259701Sdim  unsigned NumVars;
78259701Sdimprotected:
79259701Sdim  /// \brief Fetches list of variables associated with this clause.
80259701Sdim  llvm::MutableArrayRef<Expr *> getVarRefs() {
81259701Sdim    return llvm::MutableArrayRef<Expr *>(
82259701Sdim                         reinterpret_cast<Expr **>(static_cast<T *>(this) + 1),
83259701Sdim                         NumVars);
84259701Sdim  }
85259701Sdim
86259701Sdim  /// \brief Sets the list of variables for this clause.
87259701Sdim  void setVarRefs(ArrayRef<Expr *> VL) {
88259701Sdim    assert(VL.size() == NumVars &&
89259701Sdim           "Number of variables is not the same as the preallocated buffer");
90259701Sdim    std::copy(VL.begin(), VL.end(),
91259701Sdim              reinterpret_cast<Expr **>(static_cast<T *>(this) + 1));
92259701Sdim  }
93259701Sdim
94259701Sdim  /// \brief Build clause with number of variables \a N.
95259701Sdim  ///
96259701Sdim  /// \param N Number of the variables in the clause.
97259701Sdim  ///
98259701Sdim  OMPVarList(SourceLocation LParenLoc, unsigned N)
99259701Sdim    : LParenLoc(LParenLoc), NumVars(N) { }
100259701Sdimpublic:
101259701Sdim  typedef llvm::MutableArrayRef<Expr *>::iterator varlist_iterator;
102259701Sdim  typedef ArrayRef<const Expr *>::iterator varlist_const_iterator;
103259701Sdim
104259701Sdim  unsigned varlist_size() const { return NumVars; }
105259701Sdim  bool varlist_empty() const { return NumVars == 0; }
106259701Sdim  varlist_iterator varlist_begin() { return getVarRefs().begin(); }
107259701Sdim  varlist_iterator varlist_end() { return getVarRefs().end(); }
108259701Sdim  varlist_const_iterator varlist_begin() const { return getVarRefs().begin(); }
109259701Sdim  varlist_const_iterator varlist_end() const { return getVarRefs().end(); }
110259701Sdim
111259701Sdim  /// \brief Sets the location of '('.
112259701Sdim  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
113259701Sdim  /// \brief Returns the location of '('.
114259701Sdim  SourceLocation getLParenLoc() const { return LParenLoc; }
115259701Sdim
116259701Sdim  /// \brief Fetches list of all variables in the clause.
117259701Sdim  ArrayRef<const Expr *> getVarRefs() const {
118259701Sdim    return ArrayRef<const Expr *>(
119259701Sdim       reinterpret_cast<const Expr *const *>(static_cast<const T *>(this) + 1),
120259701Sdim       NumVars);
121259701Sdim  }
122259701Sdim};
123259701Sdim
124259701Sdim/// \brief This represents 'default' clause in the '#pragma omp ...' directive.
125259701Sdim///
126259701Sdim/// \code
127259701Sdim/// #pragma omp parallel default(shared)
128259701Sdim/// \endcode
129259701Sdim/// In this example directive '#pragma omp parallel' has simple 'default'
130259701Sdim/// clause with kind 'shared'.
131259701Sdim///
132259701Sdimclass OMPDefaultClause : public OMPClause {
133259701Sdim  friend class OMPClauseReader;
134259701Sdim  /// \brief Location of '('.
135259701Sdim  SourceLocation LParenLoc;
136259701Sdim  /// \brief A kind of the 'default' clause.
137259701Sdim  OpenMPDefaultClauseKind Kind;
138259701Sdim  /// \brief Start location of the kind in source code.
139259701Sdim  SourceLocation KindKwLoc;
140259701Sdim
141259701Sdim  /// \brief Set kind of the clauses.
142259701Sdim  ///
143259701Sdim  /// \param K Argument of clause.
144259701Sdim  ///
145259701Sdim  void setDefaultKind(OpenMPDefaultClauseKind K) { Kind = K; }
146259701Sdim
147259701Sdim  /// \brief Set argument location.
148259701Sdim  ///
149259701Sdim  /// \param KLoc Argument location.
150259701Sdim  ///
151259701Sdim  void setDefaultKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }
152259701Sdimpublic:
153259701Sdim  /// \brief Build 'default' clause with argument \a A ('none' or 'shared').
154259701Sdim  ///
155259701Sdim  /// \param A Argument of the clause ('none' or 'shared').
156259701Sdim  /// \param ALoc Starting location of the argument.
157259701Sdim  /// \param StartLoc Starting location of the clause.
158259701Sdim  /// \param LParenLoc Location of '('.
159259701Sdim  /// \param EndLoc Ending location of the clause.
160259701Sdim  ///
161259701Sdim  OMPDefaultClause(OpenMPDefaultClauseKind A, SourceLocation ALoc,
162259701Sdim                   SourceLocation StartLoc, SourceLocation LParenLoc,
163259701Sdim                   SourceLocation EndLoc)
164259701Sdim    : OMPClause(OMPC_default, StartLoc, EndLoc), LParenLoc(LParenLoc),
165259701Sdim      Kind(A), KindKwLoc(ALoc) { }
166259701Sdim
167259701Sdim  /// \brief Build an empty clause.
168259701Sdim  ///
169259701Sdim  OMPDefaultClause()
170259701Sdim    : OMPClause(OMPC_default, SourceLocation(), SourceLocation()),
171259701Sdim      LParenLoc(SourceLocation()), Kind(OMPC_DEFAULT_unknown),
172259701Sdim      KindKwLoc(SourceLocation()) { }
173259701Sdim
174259701Sdim  /// \brief Sets the location of '('.
175259701Sdim  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }
176259701Sdim  /// \brief Returns the location of '('.
177259701Sdim  SourceLocation getLParenLoc() const { return LParenLoc; }
178259701Sdim
179259701Sdim  /// \brief Returns kind of the clause.
180259701Sdim  OpenMPDefaultClauseKind getDefaultKind() const { return Kind; }
181259701Sdim
182259701Sdim  /// \brief Returns location of clause kind.
183259701Sdim  SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; }
184259701Sdim
185259701Sdim  static bool classof(const OMPClause *T) {
186259701Sdim    return T->getClauseKind() == OMPC_default;
187259701Sdim  }
188259701Sdim
189259701Sdim  StmtRange children() {
190259701Sdim    return StmtRange();
191259701Sdim  }
192259701Sdim};
193259701Sdim
194259701Sdim/// \brief This represents clause 'private' in the '#pragma omp ...' directives.
195259701Sdim///
196259701Sdim/// \code
197259701Sdim/// #pragma omp parallel private(a,b)
198259701Sdim/// \endcode
199259701Sdim/// In this example directive '#pragma omp parallel' has clause 'private'
200259701Sdim/// with the variables 'a' and 'b'.
201259701Sdim///
202259701Sdimclass OMPPrivateClause : public OMPClause, public OMPVarList<OMPPrivateClause> {
203259701Sdim  /// \brief Build clause with number of variables \a N.
204259701Sdim  ///
205259701Sdim  /// \param StartLoc Starting location of the clause.
206259701Sdim  /// \param LParenLoc Location of '('.
207259701Sdim  /// \param EndLoc Ending location of the clause.
208259701Sdim  /// \param N Number of the variables in the clause.
209259701Sdim  ///
210259701Sdim  OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
211259701Sdim                   SourceLocation EndLoc, unsigned N)
212259701Sdim    : OMPClause(OMPC_private, StartLoc, EndLoc),
213259701Sdim      OMPVarList<OMPPrivateClause>(LParenLoc, N) { }
214259701Sdim
215259701Sdim  /// \brief Build an empty clause.
216259701Sdim  ///
217259701Sdim  /// \param N Number of variables.
218259701Sdim  ///
219259701Sdim  explicit OMPPrivateClause(unsigned N)
220259701Sdim    : OMPClause(OMPC_private, SourceLocation(), SourceLocation()),
221259701Sdim      OMPVarList<OMPPrivateClause>(SourceLocation(), N) { }
222259701Sdimpublic:
223259701Sdim  /// \brief Creates clause with a list of variables \a VL.
224259701Sdim  ///
225259701Sdim  /// \param C AST context.
226259701Sdim  /// \param StartLoc Starting location of the clause.
227259701Sdim  /// \param LParenLoc Location of '('.
228259701Sdim  /// \param EndLoc Ending location of the clause.
229259701Sdim  /// \param VL List of references to the variables.
230259701Sdim  ///
231259701Sdim  static OMPPrivateClause *Create(const ASTContext &C, SourceLocation StartLoc,
232259701Sdim                                  SourceLocation LParenLoc,
233259701Sdim                                  SourceLocation EndLoc,
234259701Sdim                                  ArrayRef<Expr *> VL);
235259701Sdim  /// \brief Creates an empty clause with the place for \a N variables.
236259701Sdim  ///
237259701Sdim  /// \param C AST context.
238259701Sdim  /// \param N The number of variables.
239259701Sdim  ///
240259701Sdim  static OMPPrivateClause *CreateEmpty(const ASTContext &C, unsigned N);
241259701Sdim
242259701Sdim  StmtRange children() {
243259701Sdim    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
244259701Sdim                     reinterpret_cast<Stmt **>(varlist_end()));
245259701Sdim  }
246259701Sdim
247259701Sdim  static bool classof(const OMPClause *T) {
248259701Sdim    return T->getClauseKind() == OMPC_private;
249259701Sdim  }
250259701Sdim};
251259701Sdim
252259701Sdim/// \brief This represents clause 'firstprivate' in the '#pragma omp ...'
253259701Sdim/// directives.
254259701Sdim///
255259701Sdim/// \code
256259701Sdim/// #pragma omp parallel firstprivate(a,b)
257259701Sdim/// \endcode
258259701Sdim/// In this example directive '#pragma omp parallel' has clause 'firstprivate'
259259701Sdim/// with the variables 'a' and 'b'.
260259701Sdim///
261259701Sdimclass OMPFirstprivateClause : public OMPClause,
262259701Sdim                              public OMPVarList<OMPFirstprivateClause> {
263259701Sdim  /// \brief Build clause with number of variables \a N.
264259701Sdim  ///
265259701Sdim  /// \param StartLoc Starting location of the clause.
266259701Sdim  /// \param LParenLoc Location of '('.
267259701Sdim  /// \param EndLoc Ending location of the clause.
268259701Sdim  /// \param N Number of the variables in the clause.
269259701Sdim  ///
270259701Sdim  OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
271259701Sdim                   SourceLocation EndLoc, unsigned N)
272259701Sdim    : OMPClause(OMPC_firstprivate, StartLoc, EndLoc),
273259701Sdim      OMPVarList<OMPFirstprivateClause>(LParenLoc, N) { }
274259701Sdim
275259701Sdim  /// \brief Build an empty clause.
276259701Sdim  ///
277259701Sdim  /// \param N Number of variables.
278259701Sdim  ///
279259701Sdim  explicit OMPFirstprivateClause(unsigned N)
280259701Sdim    : OMPClause(OMPC_firstprivate, SourceLocation(), SourceLocation()),
281259701Sdim      OMPVarList<OMPFirstprivateClause>(SourceLocation(), N) { }
282259701Sdimpublic:
283259701Sdim  /// \brief Creates clause with a list of variables \a VL.
284259701Sdim  ///
285259701Sdim  /// \param C AST context.
286259701Sdim  /// \param StartLoc Starting location of the clause.
287259701Sdim  /// \param LParenLoc Location of '('.
288259701Sdim  /// \param EndLoc Ending location of the clause.
289259701Sdim  /// \param VL List of references to the variables.
290259701Sdim  ///
291259701Sdim  static OMPFirstprivateClause *Create(const ASTContext &C,
292259701Sdim                                       SourceLocation StartLoc,
293259701Sdim                                       SourceLocation LParenLoc,
294259701Sdim                                       SourceLocation EndLoc,
295259701Sdim                                       ArrayRef<Expr *> VL);
296259701Sdim  /// \brief Creates an empty clause with the place for \a N variables.
297259701Sdim  ///
298259701Sdim  /// \param C AST context.
299259701Sdim  /// \param N The number of variables.
300259701Sdim  ///
301259701Sdim  static OMPFirstprivateClause *CreateEmpty(const ASTContext &C, unsigned N);
302259701Sdim
303259701Sdim  StmtRange children() {
304259701Sdim    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
305259701Sdim                     reinterpret_cast<Stmt **>(varlist_end()));
306259701Sdim  }
307259701Sdim
308259701Sdim  static bool classof(const OMPClause *T) {
309259701Sdim    return T->getClauseKind() == OMPC_firstprivate;
310259701Sdim  }
311259701Sdim};
312259701Sdim
313259701Sdim/// \brief This represents clause 'shared' in the '#pragma omp ...' directives.
314259701Sdim///
315259701Sdim/// \code
316259701Sdim/// #pragma omp parallel shared(a,b)
317259701Sdim/// \endcode
318259701Sdim/// In this example directive '#pragma omp parallel' has clause 'shared'
319259701Sdim/// with the variables 'a' and 'b'.
320259701Sdim///
321259701Sdimclass OMPSharedClause : public OMPClause, public OMPVarList<OMPSharedClause> {
322259701Sdim  /// \brief Build clause with number of variables \a N.
323259701Sdim  ///
324259701Sdim  /// \param StartLoc Starting location of the clause.
325259701Sdim  /// \param LParenLoc Location of '('.
326259701Sdim  /// \param EndLoc Ending location of the clause.
327259701Sdim  /// \param N Number of the variables in the clause.
328259701Sdim  ///
329259701Sdim  OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
330259701Sdim                  SourceLocation EndLoc, unsigned N)
331259701Sdim    : OMPClause(OMPC_shared, StartLoc, EndLoc),
332259701Sdim      OMPVarList<OMPSharedClause>(LParenLoc, N) { }
333259701Sdim
334259701Sdim  /// \brief Build an empty clause.
335259701Sdim  ///
336259701Sdim  /// \param N Number of variables.
337259701Sdim  ///
338259701Sdim  explicit OMPSharedClause(unsigned N)
339259701Sdim    : OMPClause(OMPC_shared, SourceLocation(), SourceLocation()),
340259701Sdim      OMPVarList<OMPSharedClause>(SourceLocation(), N) { }
341259701Sdimpublic:
342259701Sdim  /// \brief Creates clause with a list of variables \a VL.
343259701Sdim  ///
344259701Sdim  /// \param C AST context.
345259701Sdim  /// \param StartLoc Starting location of the clause.
346259701Sdim  /// \param LParenLoc Location of '('.
347259701Sdim  /// \param EndLoc Ending location of the clause.
348259701Sdim  /// \param VL List of references to the variables.
349259701Sdim  ///
350259701Sdim  static OMPSharedClause *Create(const ASTContext &C, SourceLocation StartLoc,
351259701Sdim                                 SourceLocation LParenLoc,
352259701Sdim                                 SourceLocation EndLoc, ArrayRef<Expr *> VL);
353259701Sdim  /// \brief Creates an empty clause with \a N variables.
354259701Sdim  ///
355259701Sdim  /// \param C AST context.
356259701Sdim  /// \param N The number of variables.
357259701Sdim  ///
358259701Sdim  static OMPSharedClause *CreateEmpty(const ASTContext &C, unsigned N);
359259701Sdim
360259701Sdim  StmtRange children() {
361259701Sdim    return StmtRange(reinterpret_cast<Stmt **>(varlist_begin()),
362259701Sdim                     reinterpret_cast<Stmt **>(varlist_end()));
363259701Sdim  }
364259701Sdim
365259701Sdim  static bool classof(const OMPClause *T) {
366259701Sdim    return T->getClauseKind() == OMPC_shared;
367259701Sdim  }
368259701Sdim};
369259701Sdim
370259701Sdim//===----------------------------------------------------------------------===//
371259701Sdim// AST classes for directives.
372259701Sdim//===----------------------------------------------------------------------===//
373259701Sdim
374259701Sdim/// \brief This is a basic class for representing single OpenMP executable
375259701Sdim/// directive.
376259701Sdim///
377259701Sdimclass OMPExecutableDirective : public Stmt {
378259701Sdim  friend class ASTStmtReader;
379259701Sdim  /// \brief Kind of the directive.
380259701Sdim  OpenMPDirectiveKind Kind;
381259701Sdim  /// \brief Starting location of the directive (directive keyword).
382259701Sdim  SourceLocation StartLoc;
383259701Sdim  /// \brief Ending location of the directive.
384259701Sdim  SourceLocation EndLoc;
385259701Sdim  /// \brief Pointer to the list of clauses.
386259701Sdim  llvm::MutableArrayRef<OMPClause *> Clauses;
387259701Sdim  /// \brief Associated statement (if any) and expressions.
388259701Sdim  llvm::MutableArrayRef<Stmt *> StmtAndExpressions;
389259701Sdimprotected:
390259701Sdim  /// \brief Build instance of directive of class \a K.
391259701Sdim  ///
392259701Sdim  /// \param SC Statement class.
393259701Sdim  /// \param K Kind of OpenMP directive.
394259701Sdim  /// \param StartLoc Starting location of the directive (directive keyword).
395259701Sdim  /// \param EndLoc Ending location of the directive.
396259701Sdim  ///
397259701Sdim  template <typename T>
398259701Sdim  OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K,
399259701Sdim                         SourceLocation StartLoc, SourceLocation EndLoc,
400259701Sdim                         unsigned NumClauses, unsigned NumberOfExpressions)
401259701Sdim    : Stmt(SC), Kind(K), StartLoc(StartLoc), EndLoc(EndLoc),
402259701Sdim      Clauses(reinterpret_cast<OMPClause **>(static_cast<T *>(this) + 1),
403259701Sdim              NumClauses),
404259701Sdim      StmtAndExpressions(reinterpret_cast<Stmt **>(Clauses.end()),
405259701Sdim                         NumberOfExpressions) { }
406259701Sdim
407259701Sdim  /// \brief Sets the list of variables for this clause.
408259701Sdim  ///
409259701Sdim  /// \param Clauses The list of clauses for the directive.
410259701Sdim  ///
411259701Sdim  void setClauses(ArrayRef<OMPClause *> Clauses);
412259701Sdim
413259701Sdim  /// \brief Set the associated statement for the directive.
414259701Sdim  ///
415259701Sdim  /// /param S Associated statement.
416259701Sdim  ///
417259701Sdim  void setAssociatedStmt(Stmt *S) {
418259701Sdim    StmtAndExpressions[0] = S;
419259701Sdim  }
420259701Sdim
421259701Sdimpublic:
422259701Sdim  /// \brief Returns starting location of directive kind.
423259701Sdim  SourceLocation getLocStart() const { return StartLoc; }
424259701Sdim  /// \brief Returns ending location of directive.
425259701Sdim  SourceLocation getLocEnd() const { return EndLoc; }
426259701Sdim
427259701Sdim  /// \brief Set starting location of directive kind.
428259701Sdim  ///
429259701Sdim  /// \param Loc New starting location of directive.
430259701Sdim  ///
431259701Sdim  void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
432259701Sdim  /// \brief Set ending location of directive.
433259701Sdim  ///
434259701Sdim  /// \param Loc New ending location of directive.
435259701Sdim  ///
436259701Sdim  void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
437259701Sdim
438259701Sdim  /// \brief Get number of clauses.
439259701Sdim  unsigned getNumClauses() const { return Clauses.size(); }
440259701Sdim
441259701Sdim  /// \brief Returns specified clause.
442259701Sdim  ///
443259701Sdim  /// \param i Number of clause.
444259701Sdim  ///
445259701Sdim  OMPClause *getClause(unsigned i) const {
446259701Sdim    assert(i < Clauses.size() && "index out of bound!");
447259701Sdim    return Clauses[i];
448259701Sdim  }
449259701Sdim
450259701Sdim  /// \brief Returns statement associated with the directive.
451259701Sdim  Stmt *getAssociatedStmt() const {
452259701Sdim    return StmtAndExpressions[0];
453259701Sdim  }
454259701Sdim
455259701Sdim  OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
456259701Sdim
457259701Sdim  static bool classof(const Stmt *S) {
458259701Sdim    return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
459259701Sdim           S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
460259701Sdim  }
461259701Sdim
462259701Sdim  child_range children() {
463259701Sdim    return child_range(StmtAndExpressions.begin(), StmtAndExpressions.end());
464259701Sdim  }
465259701Sdim
466259701Sdim  ArrayRef<OMPClause *> clauses() { return Clauses; }
467259701Sdim
468259701Sdim  ArrayRef<OMPClause *> clauses() const { return Clauses; }
469259701Sdim};
470259701Sdim
471259701Sdim/// \brief This represents '#pragma omp parallel' directive.
472259701Sdim///
473259701Sdim/// \code
474259701Sdim/// #pragma omp parallel private(a,b) reduction(+: c,d)
475259701Sdim/// \endcode
476259701Sdim/// In this example directive '#pragma omp parallel' has clauses 'private'
477259701Sdim/// with the variables 'a' and 'b' and 'reduction' with operator '+' and
478259701Sdim/// variables 'c' and 'd'.
479259701Sdim///
480259701Sdimclass OMPParallelDirective : public OMPExecutableDirective {
481259701Sdim  /// \brief Build directive with the given start and end location.
482259701Sdim  ///
483259701Sdim  /// \param StartLoc Starting location of the directive (directive keyword).
484259701Sdim  /// \param EndLoc Ending Location of the directive.
485259701Sdim  ///
486259701Sdim  OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
487259701Sdim                       unsigned N)
488259701Sdim    : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
489259701Sdim                             StartLoc, EndLoc, N, 1) { }
490259701Sdim
491259701Sdim  /// \brief Build an empty directive.
492259701Sdim  ///
493259701Sdim  /// \param N Number of clauses.
494259701Sdim  ///
495259701Sdim  explicit OMPParallelDirective(unsigned N)
496259701Sdim    : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
497259701Sdim                             SourceLocation(), SourceLocation(), N, 1) { }
498259701Sdimpublic:
499259701Sdim  /// \brief Creates directive with a list of \a Clauses.
500259701Sdim  ///
501259701Sdim  /// \param C AST context.
502259701Sdim  /// \param StartLoc Starting location of the directive kind.
503259701Sdim  /// \param EndLoc Ending Location of the directive.
504259701Sdim  /// \param Clauses List of clauses.
505259701Sdim  /// \param AssociatedStmt Statement associated with the directive.
506259701Sdim  ///
507259701Sdim  static OMPParallelDirective *Create(const ASTContext &C,
508259701Sdim                                      SourceLocation StartLoc,
509259701Sdim                                      SourceLocation EndLoc,
510259701Sdim                                      ArrayRef<OMPClause *> Clauses,
511259701Sdim                                      Stmt *AssociatedStmt);
512259701Sdim
513259701Sdim  /// \brief Creates an empty directive with the place for \a N clauses.
514259701Sdim  ///
515259701Sdim  /// \param C AST context.
516259701Sdim  /// \param N The number of clauses.
517259701Sdim  ///
518259701Sdim  static OMPParallelDirective *CreateEmpty(const ASTContext &C, unsigned N,
519259701Sdim                                           EmptyShell);
520259701Sdim
521259701Sdim  static bool classof(const Stmt *T) {
522259701Sdim    return T->getStmtClass() == OMPParallelDirectiveClass;
523259701Sdim  }
524259701Sdim};
525259701Sdim
526259701Sdim}  // end namespace clang
527259701Sdim
528259701Sdim#endif
529