clang API Documentation

StmtOpenMP.h
Go to the documentation of this file.
00001 //===- StmtOpenMP.h - Classes for OpenMP directives  ------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 /// \file
00010 /// \brief This file defines OpenMP AST classes for executable directives and
00011 /// clauses.
00012 ///
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef LLVM_CLANG_AST_STMTOPENMP_H
00016 #define LLVM_CLANG_AST_STMTOPENMP_H
00017 
00018 #include "clang/AST/Expr.h"
00019 #include "clang/AST/OpenMPClause.h"
00020 #include "clang/AST/Stmt.h"
00021 #include "clang/Basic/OpenMPKinds.h"
00022 #include "clang/Basic/SourceLocation.h"
00023 
00024 namespace clang {
00025 
00026 //===----------------------------------------------------------------------===//
00027 // AST classes for directives.
00028 //===----------------------------------------------------------------------===//
00029 
00030 /// \brief This is a basic class for representing single OpenMP executable
00031 /// directive.
00032 ///
00033 class OMPExecutableDirective : public Stmt {
00034   friend class ASTStmtReader;
00035   /// \brief Kind of the directive.
00036   OpenMPDirectiveKind Kind;
00037   /// \brief Starting location of the directive (directive keyword).
00038   SourceLocation StartLoc;
00039   /// \brief Ending location of the directive.
00040   SourceLocation EndLoc;
00041   /// \brief Numbers of clauses.
00042   const unsigned NumClauses;
00043   /// \brief Number of child expressions/stmts.
00044   const unsigned NumChildren;
00045   /// \brief Offset from this to the start of clauses.
00046   /// There are NumClauses pointers to clauses, they are followed by
00047   /// NumChildren pointers to child stmts/exprs (if the directive type
00048   /// requires an associated stmt, then it has to be the first of them).
00049   const unsigned ClausesOffset;
00050 
00051   /// \brief Get the clauses storage.
00052   MutableArrayRef<OMPClause *> getClauses() {
00053     OMPClause **ClauseStorage = reinterpret_cast<OMPClause **>(
00054         reinterpret_cast<char *>(this) + ClausesOffset);
00055     return MutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);
00056   }
00057 
00058 protected:
00059   /// \brief Build instance of directive of class \a K.
00060   ///
00061   /// \param SC Statement class.
00062   /// \param K Kind of OpenMP directive.
00063   /// \param StartLoc Starting location of the directive (directive keyword).
00064   /// \param EndLoc Ending location of the directive.
00065   ///
00066   template <typename T>
00067   OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K,
00068                          SourceLocation StartLoc, SourceLocation EndLoc,
00069                          unsigned NumClauses, unsigned NumChildren)
00070       : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
00071         EndLoc(std::move(EndLoc)), NumClauses(NumClauses),
00072         NumChildren(NumChildren),
00073         ClausesOffset(llvm::RoundUpToAlignment(sizeof(T),
00074                                                llvm::alignOf<OMPClause *>())) {}
00075 
00076   /// \brief Sets the list of variables for this clause.
00077   ///
00078   /// \param Clauses The list of clauses for the directive.
00079   ///
00080   void setClauses(ArrayRef<OMPClause *> Clauses);
00081 
00082   /// \brief Set the associated statement for the directive.
00083   ///
00084   /// /param S Associated statement.
00085   ///
00086   void setAssociatedStmt(Stmt *S) {
00087     assert(hasAssociatedStmt() && "no associated statement.");
00088     *child_begin() = S;
00089   }
00090 
00091 public:
00092   /// \brief Iterates over a filtered subrange of clauses applied to a
00093   /// directive.
00094   ///
00095   /// This iterator visits only those declarations that meet some run-time
00096   /// criteria.
00097   template <class FilterPredicate> class filtered_clause_iterator {
00098     ArrayRef<OMPClause *>::const_iterator Current;
00099     ArrayRef<OMPClause *>::const_iterator End;
00100     FilterPredicate Pred;
00101     void SkipToNextClause() {
00102       while (Current != End && !Pred(*Current))
00103         ++Current;
00104     }
00105 
00106   public:
00107     typedef const OMPClause *value_type;
00108     filtered_clause_iterator() : Current(), End() {}
00109     filtered_clause_iterator(ArrayRef<OMPClause *> Arr, FilterPredicate Pred)
00110         : Current(Arr.begin()), End(Arr.end()), Pred(Pred) {
00111       SkipToNextClause();
00112     }
00113     value_type operator*() const { return *Current; }
00114     value_type operator->() const { return *Current; }
00115     filtered_clause_iterator &operator++() {
00116       ++Current;
00117       SkipToNextClause();
00118       return *this;
00119     }
00120 
00121     filtered_clause_iterator operator++(int) {
00122       filtered_clause_iterator tmp(*this);
00123       ++(*this);
00124       return tmp;
00125     }
00126 
00127     bool operator!() { return Current == End; }
00128     operator bool() { return Current != End; }
00129   };
00130 
00131   /// \brief Gets a single clause of the specified kind \a K associated with the
00132   /// current directive iff there is only one clause of this kind (and assertion
00133   /// is fired if there is more than one clause is associated with the
00134   /// directive). Returns nullptr if no clause of kind \a K is associated with
00135   /// the directive.
00136   const OMPClause *getSingleClause(OpenMPClauseKind K) const;
00137 
00138   /// \brief Returns starting location of directive kind.
00139   SourceLocation getLocStart() const { return StartLoc; }
00140   /// \brief Returns ending location of directive.
00141   SourceLocation getLocEnd() const { return EndLoc; }
00142 
00143   /// \brief Set starting location of directive kind.
00144   ///
00145   /// \param Loc New starting location of directive.
00146   ///
00147   void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
00148   /// \brief Set ending location of directive.
00149   ///
00150   /// \param Loc New ending location of directive.
00151   ///
00152   void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
00153 
00154   /// \brief Get number of clauses.
00155   unsigned getNumClauses() const { return NumClauses; }
00156 
00157   /// \brief Returns specified clause.
00158   ///
00159   /// \param i Number of clause.
00160   ///
00161   OMPClause *getClause(unsigned i) const { return clauses()[i]; }
00162 
00163   /// \brief Returns true if directive has associated statement.
00164   bool hasAssociatedStmt() const { return NumChildren > 0; }
00165 
00166   /// \brief Returns statement associated with the directive.
00167   Stmt *getAssociatedStmt() const {
00168     assert(hasAssociatedStmt() && "no associated statement.");
00169     return const_cast<Stmt *>(*child_begin());
00170   }
00171 
00172   OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
00173 
00174   static bool classof(const Stmt *S) {
00175     return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
00176            S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
00177   }
00178 
00179   child_range children() {
00180     if (!hasAssociatedStmt())
00181       return child_range();
00182     Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
00183     return child_range(ChildStorage, ChildStorage + NumChildren);
00184   }
00185 
00186   ArrayRef<OMPClause *> clauses() { return getClauses(); }
00187 
00188   ArrayRef<OMPClause *> clauses() const {
00189     return const_cast<OMPExecutableDirective *>(this)->getClauses();
00190   }
00191 };
00192 
00193 /// \brief This represents '#pragma omp parallel' directive.
00194 ///
00195 /// \code
00196 /// #pragma omp parallel private(a,b) reduction(+: c,d)
00197 /// \endcode
00198 /// In this example directive '#pragma omp parallel' has clauses 'private'
00199 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
00200 /// variables 'c' and 'd'.
00201 ///
00202 class OMPParallelDirective : public OMPExecutableDirective {
00203   /// \brief Build directive with the given start and end location.
00204   ///
00205   /// \param StartLoc Starting location of the directive (directive keyword).
00206   /// \param EndLoc Ending Location of the directive.
00207   ///
00208   OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
00209                        unsigned NumClauses)
00210       : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
00211                                StartLoc, EndLoc, NumClauses, 1) {}
00212 
00213   /// \brief Build an empty directive.
00214   ///
00215   /// \param NumClauses Number of clauses.
00216   ///
00217   explicit OMPParallelDirective(unsigned NumClauses)
00218       : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
00219                                SourceLocation(), SourceLocation(), NumClauses,
00220                                1) {}
00221 
00222 public:
00223   /// \brief Creates directive with a list of \a Clauses.
00224   ///
00225   /// \param C AST context.
00226   /// \param StartLoc Starting location of the directive kind.
00227   /// \param EndLoc Ending Location of the directive.
00228   /// \param Clauses List of clauses.
00229   /// \param AssociatedStmt Statement associated with the directive.
00230   ///
00231   static OMPParallelDirective *
00232   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
00233          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
00234 
00235   /// \brief Creates an empty directive with the place for \a N clauses.
00236   ///
00237   /// \param C AST context.
00238   /// \param NumClauses Number of clauses.
00239   ///
00240   static OMPParallelDirective *CreateEmpty(const ASTContext &C,
00241                                            unsigned NumClauses, EmptyShell);
00242 
00243   static bool classof(const Stmt *T) {
00244     return T->getStmtClass() == OMPParallelDirectiveClass;
00245   }
00246 };
00247 
00248 /// \brief This is a common base class for loop directives ('omp simd', 'omp
00249 /// for', 'omp for simd' etc.). It is responsible for the loop code generation.
00250 ///
00251 class OMPLoopDirective : public OMPExecutableDirective {
00252   friend class ASTStmtReader;
00253   /// \brief Number of collapsed loops as specified by 'collapse' clause.
00254   unsigned CollapsedNum;
00255 
00256   /// \brief Offsets to the stored exprs.
00257   enum {
00258     AssociatedStmtOffset = 0,
00259     IterationVariableOffset = 1,
00260     LastIterationOffset = 2,
00261     CalcLastIterationOffset = 3,
00262     PreConditionOffset = 4,
00263     CondOffset = 5,
00264     SeparatedCondOffset = 6,
00265     InitOffset = 7,
00266     IncOffset = 8,
00267     ArraysOffset = 9
00268   };
00269 
00270   /// \brief Get the counters storage.
00271   MutableArrayRef<Expr *> getCounters() {
00272     Expr **Storage =
00273         reinterpret_cast<Expr **>(&(*(std::next(child_begin(), ArraysOffset))));
00274     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
00275   }
00276 
00277   /// \brief Get the updates storage.
00278   MutableArrayRef<Expr *> getUpdates() {
00279     Expr **Storage = reinterpret_cast<Expr **>(
00280         &*std::next(child_begin(), ArraysOffset + CollapsedNum));
00281     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
00282   }
00283 
00284   /// \brief Get the final counter updates storage.
00285   MutableArrayRef<Expr *> getFinals() {
00286     Expr **Storage = reinterpret_cast<Expr **>(
00287         &*std::next(child_begin(), ArraysOffset + 2 * CollapsedNum));
00288     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
00289   }
00290 
00291 protected:
00292   /// \brief Build instance of loop directive of class \a Kind.
00293   ///
00294   /// \param SC Statement class.
00295   /// \param Kind Kind of OpenMP directive.
00296   /// \param StartLoc Starting location of the directive (directive keyword).
00297   /// \param EndLoc Ending location of the directive.
00298   /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
00299   /// \param NumClauses Number of clauses.
00300   /// \param NumSpecialChildren Number of additional directive-specific stmts.
00301   ///
00302   template <typename T>
00303   OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind,
00304                    SourceLocation StartLoc, SourceLocation EndLoc,
00305                    unsigned CollapsedNum, unsigned NumClauses,
00306                    unsigned NumSpecialChildren = 0)
00307       : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses,
00308                                numLoopChildren(CollapsedNum) +
00309                                    NumSpecialChildren),
00310         CollapsedNum(CollapsedNum) {}
00311 
00312   /// \brief Children number.
00313   static unsigned numLoopChildren(unsigned CollapsedNum) {
00314     return ArraysOffset + 3 * CollapsedNum; // Counters, Updates and Finals
00315   }
00316 
00317   void setIterationVariable(Expr *IV) {
00318     *std::next(child_begin(), IterationVariableOffset) = IV;
00319   }
00320   void setLastIteration(Expr *LI) {
00321     *std::next(child_begin(), LastIterationOffset) = LI;
00322   }
00323   void setCalcLastIteration(Expr *CLI) {
00324     *std::next(child_begin(), CalcLastIterationOffset) = CLI;
00325   }
00326   void setPreCond(Expr *PC) {
00327     *std::next(child_begin(), PreConditionOffset) = PC;
00328   }
00329   void setCond(Expr *Cond, Expr *SeparatedCond) {
00330     *std::next(child_begin(), CondOffset) = Cond;
00331     *std::next(child_begin(), SeparatedCondOffset) = SeparatedCond;
00332   }
00333   void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; }
00334   void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; }
00335   void setCounters(ArrayRef<Expr *> A);
00336   void setUpdates(ArrayRef<Expr *> A);
00337   void setFinals(ArrayRef<Expr *> A);
00338 
00339 public:
00340   /// \brief Get number of collapsed loops.
00341   unsigned getCollapsedNumber() const { return CollapsedNum; }
00342 
00343   Expr *getIterationVariable() const {
00344     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
00345         *std::next(child_begin(), IterationVariableOffset)));
00346   }
00347   Expr *getLastIteration() const {
00348     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
00349         *std::next(child_begin(), LastIterationOffset)));
00350   }
00351   Expr *getCalcLastIteration() const {
00352     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
00353         *std::next(child_begin(), CalcLastIterationOffset)));
00354   }
00355   Expr *getPreCond() const {
00356     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
00357         *std::next(child_begin(), PreConditionOffset)));
00358   }
00359   Expr *getCond(bool SeparateIter) const {
00360     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
00361         *std::next(child_begin(),
00362                    (SeparateIter ? SeparatedCondOffset : CondOffset))));
00363   }
00364   Expr *getInit() const {
00365     return const_cast<Expr *>(
00366         reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset)));
00367   }
00368   Expr *getInc() const {
00369     return const_cast<Expr *>(
00370         reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset)));
00371   }
00372   const Stmt *getBody() const {
00373     // This relies on the loop form is already checked by Sema.
00374     Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
00375     Body = cast<ForStmt>(Body)->getBody();
00376     for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
00377       Body = Body->IgnoreContainers();
00378       Body = cast<ForStmt>(Body)->getBody();
00379     }
00380     return Body;
00381   }
00382 
00383   ArrayRef<Expr *> counters() { return getCounters(); }
00384 
00385   ArrayRef<Expr *> counters() const {
00386     return const_cast<OMPLoopDirective *>(this)->getCounters();
00387   }
00388 
00389   ArrayRef<Expr *> updates() { return getUpdates(); }
00390 
00391   ArrayRef<Expr *> updates() const {
00392     return const_cast<OMPLoopDirective *>(this)->getUpdates();
00393   }
00394 
00395   ArrayRef<Expr *> finals() { return getFinals(); }
00396 
00397   ArrayRef<Expr *> finals() const {
00398     return const_cast<OMPLoopDirective *>(this)->getFinals();
00399   }
00400 
00401   static bool classof(const Stmt *T) {
00402     return T->getStmtClass() == OMPSimdDirectiveClass ||
00403            T->getStmtClass() == OMPForDirectiveClass ||
00404            T->getStmtClass() == OMPForSimdDirectiveClass ||
00405            T->getStmtClass() == OMPParallelForDirectiveClass ||
00406            T->getStmtClass() == OMPParallelForSimdDirectiveClass;
00407   }
00408 };
00409 
00410 /// \brief This represents '#pragma omp simd' directive.
00411 ///
00412 /// \code
00413 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
00414 /// \endcode
00415 /// In this example directive '#pragma omp simd' has clauses 'private'
00416 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
00417 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
00418 ///
00419 class OMPSimdDirective : public OMPLoopDirective {
00420   friend class ASTStmtReader;
00421   /// \brief Build directive with the given start and end location.
00422   ///
00423   /// \param StartLoc Starting location of the directive kind.
00424   /// \param EndLoc Ending location of the directive.
00425   /// \param CollapsedNum Number of collapsed nested loops.
00426   /// \param NumClauses Number of clauses.
00427   ///
00428   OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
00429                    unsigned CollapsedNum, unsigned NumClauses)
00430       : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
00431                          EndLoc, CollapsedNum, NumClauses) {}
00432 
00433   /// \brief Build an empty directive.
00434   ///
00435   /// \param CollapsedNum Number of collapsed nested loops.
00436   /// \param NumClauses Number of clauses.
00437   ///
00438   explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
00439       : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd,
00440                          SourceLocation(), SourceLocation(), CollapsedNum,
00441                          NumClauses) {}
00442 
00443 public:
00444   /// \brief Creates directive with a list of \a Clauses.
00445   ///
00446   /// \param C AST context.
00447   /// \param StartLoc Starting location of the directive kind.
00448   /// \param EndLoc Ending Location of the directive.
00449   /// \param CollapsedNum Number of collapsed loops.
00450   /// \param Clauses List of clauses.
00451   /// \param AssociatedStmt Statement, associated with the directive.
00452   /// \param IV Loop iteration variable for CodeGen.
00453   /// \param LastIteration Loop last iteration number for CodeGen.
00454   /// \param CalcLastIteration Calculation of last iteration.
00455   /// \param PreCond Pre-condition.
00456   /// \param Cond Condition.
00457   /// \param SeparatedCond Condition with 1 iteration separated.
00458   /// \param Inc Loop increment.
00459   /// \param Counters Loop counters.
00460   /// \param Updates Expressions for loop counters update for CodeGen.
00461   /// \param Finals Final loop counter values for GodeGen.
00462   ///
00463   static OMPSimdDirective *
00464   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
00465          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
00466          Stmt *AssociatedStmt, Expr *IV, Expr *LastIteration,
00467          Expr *CalcLastIteration, Expr *PreCond, Expr *Cond,
00468          Expr *SeparatedCond, Expr *Init, Expr *Inc, ArrayRef<Expr *> Counters,
00469          ArrayRef<Expr *> Updates, ArrayRef<Expr *> Finals);
00470 
00471   /// \brief Creates an empty directive with the place
00472   /// for \a NumClauses clauses.
00473   ///
00474   /// \param C AST context.
00475   /// \param CollapsedNum Number of collapsed nested loops.
00476   /// \param NumClauses Number of clauses.
00477   ///
00478   static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
00479                                        unsigned CollapsedNum, EmptyShell);
00480 
00481   static bool classof(const Stmt *T) {
00482     return T->getStmtClass() == OMPSimdDirectiveClass;
00483   }
00484 };
00485 
00486 /// \brief This represents '#pragma omp for' directive.
00487 ///
00488 /// \code
00489 /// #pragma omp for private(a,b) reduction(+:c,d)
00490 /// \endcode
00491 /// In this example directive '#pragma omp for' has clauses 'private' with the
00492 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
00493 /// and 'd'.
00494 ///
00495 class OMPForDirective : public OMPLoopDirective {
00496   friend class ASTStmtReader;
00497   /// \brief Build directive with the given start and end location.
00498   ///
00499   /// \param StartLoc Starting location of the directive kind.
00500   /// \param EndLoc Ending location of the directive.
00501   /// \param CollapsedNum Number of collapsed nested loops.
00502   /// \param NumClauses Number of clauses.
00503   ///
00504   OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
00505                   unsigned CollapsedNum, unsigned NumClauses)
00506       : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc,
00507                          CollapsedNum, NumClauses) {}
00508 
00509   /// \brief Build an empty directive.
00510   ///
00511   /// \param CollapsedNum Number of collapsed nested loops.
00512   /// \param NumClauses Number of clauses.
00513   ///
00514   explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
00515       : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(),
00516                          SourceLocation(), CollapsedNum, NumClauses) {}
00517 
00518 public:
00519   /// \brief Creates directive with a list of \a Clauses.
00520   ///
00521   /// \param C AST context.
00522   /// \param StartLoc Starting location of the directive kind.
00523   /// \param EndLoc Ending Location of the directive.
00524   /// \param CollapsedNum Number of collapsed loops.
00525   /// \param Clauses List of clauses.
00526   /// \param AssociatedStmt Statement, associated with the directive.
00527   /// \param IV Loop iteration variable for CodeGen.
00528   /// \param LastIteration Loop last iteration number for CodeGen.
00529   /// \param CalcLastIteration Calculation of last iteration.
00530   /// \param PreCond Pre-condition.
00531   /// \param Cond Condition.
00532   /// \param SeparatedCond Condition with 1 iteration separated.
00533   /// \param Inc Loop increment.
00534   /// \param Counters Loop counters.
00535   /// \param Updates Expressions for loop counters update for CodeGen.
00536   /// \param Finals Final loop counter values for GodeGen.
00537   ///
00538   static OMPForDirective *
00539   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
00540          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
00541          Stmt *AssociatedStmt, Expr *IV, Expr *LastIteration,
00542          Expr *CalcLastIteration, Expr *PreCond, Expr *Cond,
00543          Expr *SeparatedCond, Expr *Init, Expr *Inc, ArrayRef<Expr *> Counters,
00544          ArrayRef<Expr *> Updates, ArrayRef<Expr *> Finals);
00545 
00546   /// \brief Creates an empty directive with the place
00547   /// for \a NumClauses clauses.
00548   ///
00549   /// \param C AST context.
00550   /// \param CollapsedNum Number of collapsed nested loops.
00551   /// \param NumClauses Number of clauses.
00552   ///
00553   static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
00554                                       unsigned CollapsedNum, EmptyShell);
00555 
00556   static bool classof(const Stmt *T) {
00557     return T->getStmtClass() == OMPForDirectiveClass;
00558   }
00559 };
00560 
00561 /// \brief This represents '#pragma omp for simd' directive.
00562 ///
00563 /// \code
00564 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
00565 /// \endcode
00566 /// In this example directive '#pragma omp for simd' has clauses 'private'
00567 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
00568 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
00569 ///
00570 class OMPForSimdDirective : public OMPLoopDirective {
00571   friend class ASTStmtReader;
00572   /// \brief Build directive with the given start and end location.
00573   ///
00574   /// \param StartLoc Starting location of the directive kind.
00575   /// \param EndLoc Ending location of the directive.
00576   /// \param CollapsedNum Number of collapsed nested loops.
00577   /// \param NumClauses Number of clauses.
00578   ///
00579   OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
00580                       unsigned CollapsedNum, unsigned NumClauses)
00581       : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
00582                          StartLoc, EndLoc, CollapsedNum, NumClauses) {}
00583 
00584   /// \brief Build an empty directive.
00585   ///
00586   /// \param CollapsedNum Number of collapsed nested loops.
00587   /// \param NumClauses Number of clauses.
00588   ///
00589   explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
00590       : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
00591                          SourceLocation(), SourceLocation(), CollapsedNum,
00592                          NumClauses) {}
00593 
00594 public:
00595   /// \brief Creates directive with a list of \a Clauses.
00596   ///
00597   /// \param C AST context.
00598   /// \param StartLoc Starting location of the directive kind.
00599   /// \param EndLoc Ending Location of the directive.
00600   /// \param CollapsedNum Number of collapsed loops.
00601   /// \param Clauses List of clauses.
00602   /// \param AssociatedStmt Statement, associated with the directive.
00603   /// \param IV Loop iteration variable for CodeGen.
00604   /// \param LastIteration Loop last iteration number for CodeGen.
00605   /// \param CalcLastIteration Calculation of last iteration.
00606   /// \param PreCond Pre-condition.
00607   /// \param Cond Condition.
00608   /// \param SeparatedCond Condition with 1 iteration separated.
00609   /// \param Inc Loop increment.
00610   /// \param Counters Loop counters.
00611   /// \param Updates Expressions for loop counters update for CodeGen.
00612   /// \param Finals Final loop counter values for GodeGen.
00613   ///
00614   static OMPForSimdDirective *
00615   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
00616          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
00617          Stmt *AssociatedStmt, Expr *IV, Expr *LastIteration,
00618          Expr *CalcLastIteration, Expr *PreCond, Expr *Cond,
00619          Expr *SeparatedCond, Expr *Init, Expr *Inc, ArrayRef<Expr *> Counters,
00620          ArrayRef<Expr *> Updates, ArrayRef<Expr *> Finals);
00621 
00622   /// \brief Creates an empty directive with the place
00623   /// for \a NumClauses clauses.
00624   ///
00625   /// \param C AST context.
00626   /// \param CollapsedNum Number of collapsed nested loops.
00627   /// \param NumClauses Number of clauses.
00628   ///
00629   static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
00630                                           unsigned NumClauses,
00631                                           unsigned CollapsedNum, EmptyShell);
00632 
00633   static bool classof(const Stmt *T) {
00634     return T->getStmtClass() == OMPForSimdDirectiveClass;
00635   }
00636 };
00637 
00638 /// \brief This represents '#pragma omp sections' directive.
00639 ///
00640 /// \code
00641 /// #pragma omp sections private(a,b) reduction(+:c,d)
00642 /// \endcode
00643 /// In this example directive '#pragma omp sections' has clauses 'private' with
00644 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
00645 /// 'c' and 'd'.
00646 ///
00647 class OMPSectionsDirective : public OMPExecutableDirective {
00648   friend class ASTStmtReader;
00649   /// \brief Build directive with the given start and end location.
00650   ///
00651   /// \param StartLoc Starting location of the directive kind.
00652   /// \param EndLoc Ending location of the directive.
00653   /// \param NumClauses Number of clauses.
00654   ///
00655   OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
00656                        unsigned NumClauses)
00657       : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
00658                                StartLoc, EndLoc, NumClauses, 1) {}
00659 
00660   /// \brief Build an empty directive.
00661   ///
00662   /// \param NumClauses Number of clauses.
00663   ///
00664   explicit OMPSectionsDirective(unsigned NumClauses)
00665       : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
00666                                SourceLocation(), SourceLocation(), NumClauses,
00667                                1) {}
00668 
00669 public:
00670   /// \brief Creates directive with a list of \a Clauses.
00671   ///
00672   /// \param C AST context.
00673   /// \param StartLoc Starting location of the directive kind.
00674   /// \param EndLoc Ending Location of the directive.
00675   /// \param Clauses List of clauses.
00676   /// \param AssociatedStmt Statement, associated with the directive.
00677   ///
00678   static OMPSectionsDirective *
00679   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
00680          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
00681 
00682   /// \brief Creates an empty directive with the place for \a NumClauses
00683   /// clauses.
00684   ///
00685   /// \param C AST context.
00686   /// \param NumClauses Number of clauses.
00687   ///
00688   static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
00689                                            unsigned NumClauses, EmptyShell);
00690 
00691   static bool classof(const Stmt *T) {
00692     return T->getStmtClass() == OMPSectionsDirectiveClass;
00693   }
00694 };
00695 
00696 /// \brief This represents '#pragma omp section' directive.
00697 ///
00698 /// \code
00699 /// #pragma omp section
00700 /// \endcode
00701 ///
00702 class OMPSectionDirective : public OMPExecutableDirective {
00703   friend class ASTStmtReader;
00704   /// \brief Build directive with the given start and end location.
00705   ///
00706   /// \param StartLoc Starting location of the directive kind.
00707   /// \param EndLoc Ending location of the directive.
00708   ///
00709   OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
00710       : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
00711                                StartLoc, EndLoc, 0, 1) {}
00712 
00713   /// \brief Build an empty directive.
00714   ///
00715   explicit OMPSectionDirective()
00716       : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
00717                                SourceLocation(), SourceLocation(), 0, 1) {}
00718 
00719 public:
00720   /// \brief Creates directive.
00721   ///
00722   /// \param C AST context.
00723   /// \param StartLoc Starting location of the directive kind.
00724   /// \param EndLoc Ending Location of the directive.
00725   /// \param AssociatedStmt Statement, associated with the directive.
00726   ///
00727   static OMPSectionDirective *Create(const ASTContext &C,
00728                                      SourceLocation StartLoc,
00729                                      SourceLocation EndLoc,
00730                                      Stmt *AssociatedStmt);
00731 
00732   /// \brief Creates an empty directive.
00733   ///
00734   /// \param C AST context.
00735   ///
00736   static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
00737 
00738   static bool classof(const Stmt *T) {
00739     return T->getStmtClass() == OMPSectionDirectiveClass;
00740   }
00741 };
00742 
00743 /// \brief This represents '#pragma omp single' directive.
00744 ///
00745 /// \code
00746 /// #pragma omp single private(a,b) copyprivate(c,d)
00747 /// \endcode
00748 /// In this example directive '#pragma omp single' has clauses 'private' with
00749 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
00750 ///
00751 class OMPSingleDirective : public OMPExecutableDirective {
00752   friend class ASTStmtReader;
00753   /// \brief Build directive with the given start and end location.
00754   ///
00755   /// \param StartLoc Starting location of the directive kind.
00756   /// \param EndLoc Ending location of the directive.
00757   /// \param NumClauses Number of clauses.
00758   ///
00759   OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
00760                      unsigned NumClauses)
00761       : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
00762                                StartLoc, EndLoc, NumClauses, 1) {}
00763 
00764   /// \brief Build an empty directive.
00765   ///
00766   /// \param NumClauses Number of clauses.
00767   ///
00768   explicit OMPSingleDirective(unsigned NumClauses)
00769       : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
00770                                SourceLocation(), SourceLocation(), NumClauses,
00771                                1) {}
00772 
00773 public:
00774   /// \brief Creates directive with a list of \a Clauses.
00775   ///
00776   /// \param C AST context.
00777   /// \param StartLoc Starting location of the directive kind.
00778   /// \param EndLoc Ending Location of the directive.
00779   /// \param Clauses List of clauses.
00780   /// \param AssociatedStmt Statement, associated with the directive.
00781   ///
00782   static OMPSingleDirective *
00783   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
00784          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
00785 
00786   /// \brief Creates an empty directive with the place for \a NumClauses
00787   /// clauses.
00788   ///
00789   /// \param C AST context.
00790   /// \param NumClauses Number of clauses.
00791   ///
00792   static OMPSingleDirective *CreateEmpty(const ASTContext &C,
00793                                          unsigned NumClauses, EmptyShell);
00794 
00795   static bool classof(const Stmt *T) {
00796     return T->getStmtClass() == OMPSingleDirectiveClass;
00797   }
00798 };
00799 
00800 /// \brief This represents '#pragma omp master' directive.
00801 ///
00802 /// \code
00803 /// #pragma omp master
00804 /// \endcode
00805 ///
00806 class OMPMasterDirective : public OMPExecutableDirective {
00807   friend class ASTStmtReader;
00808   /// \brief Build directive with the given start and end location.
00809   ///
00810   /// \param StartLoc Starting location of the directive kind.
00811   /// \param EndLoc Ending location of the directive.
00812   ///
00813   OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
00814       : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
00815                                StartLoc, EndLoc, 0, 1) {}
00816 
00817   /// \brief Build an empty directive.
00818   ///
00819   explicit OMPMasterDirective()
00820       : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
00821                                SourceLocation(), SourceLocation(), 0, 1) {}
00822 
00823 public:
00824   /// \brief Creates directive.
00825   ///
00826   /// \param C AST context.
00827   /// \param StartLoc Starting location of the directive kind.
00828   /// \param EndLoc Ending Location of the directive.
00829   /// \param AssociatedStmt Statement, associated with the directive.
00830   ///
00831   static OMPMasterDirective *Create(const ASTContext &C,
00832                                     SourceLocation StartLoc,
00833                                     SourceLocation EndLoc,
00834                                     Stmt *AssociatedStmt);
00835 
00836   /// \brief Creates an empty directive.
00837   ///
00838   /// \param C AST context.
00839   ///
00840   static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
00841 
00842   static bool classof(const Stmt *T) {
00843     return T->getStmtClass() == OMPMasterDirectiveClass;
00844   }
00845 };
00846 
00847 /// \brief This represents '#pragma omp critical' directive.
00848 ///
00849 /// \code
00850 /// #pragma omp critical
00851 /// \endcode
00852 ///
00853 class OMPCriticalDirective : public OMPExecutableDirective {
00854   friend class ASTStmtReader;
00855   /// \brief Name of the directive.
00856   DeclarationNameInfo DirName;
00857   /// \brief Build directive with the given start and end location.
00858   ///
00859   /// \param Name Name of the directive.
00860   /// \param StartLoc Starting location of the directive kind.
00861   /// \param EndLoc Ending location of the directive.
00862   ///
00863   OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
00864                        SourceLocation EndLoc)
00865       : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
00866                                StartLoc, EndLoc, 0, 1),
00867         DirName(Name) {}
00868 
00869   /// \brief Build an empty directive.
00870   ///
00871   explicit OMPCriticalDirective()
00872       : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
00873                                SourceLocation(), SourceLocation(), 0, 1),
00874         DirName() {}
00875 
00876   /// \brief Set name of the directive.
00877   ///
00878   /// \param Name Name of the directive.
00879   ///
00880   void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
00881 
00882 public:
00883   /// \brief Creates directive.
00884   ///
00885   /// \param C AST context.
00886   /// \param Name Name of the directive.
00887   /// \param StartLoc Starting location of the directive kind.
00888   /// \param EndLoc Ending Location of the directive.
00889   /// \param AssociatedStmt Statement, associated with the directive.
00890   ///
00891   static OMPCriticalDirective *
00892   Create(const ASTContext &C, const DeclarationNameInfo &Name,
00893          SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt);
00894 
00895   /// \brief Creates an empty directive.
00896   ///
00897   /// \param C AST context.
00898   ///
00899   static OMPCriticalDirective *CreateEmpty(const ASTContext &C, EmptyShell);
00900 
00901   /// \brief Return name of the directive.
00902   ///
00903   DeclarationNameInfo getDirectiveName() const { return DirName; }
00904 
00905   static bool classof(const Stmt *T) {
00906     return T->getStmtClass() == OMPCriticalDirectiveClass;
00907   }
00908 };
00909 
00910 /// \brief This represents '#pragma omp parallel for' directive.
00911 ///
00912 /// \code
00913 /// #pragma omp parallel for private(a,b) reduction(+:c,d)
00914 /// \endcode
00915 /// In this example directive '#pragma omp parallel for' has clauses 'private'
00916 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
00917 /// variables 'c' and 'd'.
00918 ///
00919 class OMPParallelForDirective : public OMPLoopDirective {
00920   friend class ASTStmtReader;
00921   /// \brief Build directive with the given start and end location.
00922   ///
00923   /// \param StartLoc Starting location of the directive kind.
00924   /// \param EndLoc Ending location of the directive.
00925   /// \param CollapsedNum Number of collapsed nested loops.
00926   /// \param NumClauses Number of clauses.
00927   ///
00928   OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
00929                           unsigned CollapsedNum, unsigned NumClauses)
00930       : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
00931                          StartLoc, EndLoc, CollapsedNum, NumClauses) {}
00932 
00933   /// \brief Build an empty directive.
00934   ///
00935   /// \param CollapsedNum Number of collapsed nested loops.
00936   /// \param NumClauses Number of clauses.
00937   ///
00938   explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
00939       : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
00940                          SourceLocation(), SourceLocation(), CollapsedNum,
00941                          NumClauses) {}
00942 
00943 public:
00944   /// \brief Creates directive with a list of \a Clauses.
00945   ///
00946   /// \param C AST context.
00947   /// \param StartLoc Starting location of the directive kind.
00948   /// \param EndLoc Ending Location of the directive.
00949   /// \param CollapsedNum Number of collapsed loops.
00950   /// \param Clauses List of clauses.
00951   /// \param AssociatedStmt Statement, associated with the directive.
00952   /// \param IV Loop iteration variable for CodeGen.
00953   /// \param LastIteration Loop last iteration number for CodeGen.
00954   /// \param CalcLastIteration Calculation of last iteration.
00955   /// \param PreCond Pre-condition.
00956   /// \param Cond Condition.
00957   /// \param SeparatedCond Condition with 1 iteration separated.
00958   /// \param Inc Loop increment.
00959   /// \param Counters Loop counters.
00960   /// \param Updates Expressions for loop counters update for CodeGen.
00961   /// \param Finals Final loop counter values for GodeGen.
00962   ///
00963   static OMPParallelForDirective *
00964   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
00965          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
00966          Stmt *AssociatedStmt, Expr *IV, Expr *LastIteration,
00967          Expr *CalcLastIteration, Expr *PreCond, Expr *Cond,
00968          Expr *SeparatedCond, Expr *Init, Expr *Inc, ArrayRef<Expr *> Counters,
00969          ArrayRef<Expr *> Updates, ArrayRef<Expr *> Finals);
00970 
00971   /// \brief Creates an empty directive with the place
00972   /// for \a NumClauses clauses.
00973   ///
00974   /// \param C AST context.
00975   /// \param CollapsedNum Number of collapsed nested loops.
00976   /// \param NumClauses Number of clauses.
00977   ///
00978   static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
00979                                               unsigned NumClauses,
00980                                               unsigned CollapsedNum,
00981                                               EmptyShell);
00982 
00983   static bool classof(const Stmt *T) {
00984     return T->getStmtClass() == OMPParallelForDirectiveClass;
00985   }
00986 };
00987 
00988 /// \brief This represents '#pragma omp parallel for simd' directive.
00989 ///
00990 /// \code
00991 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
00992 /// \endcode
00993 /// In this example directive '#pragma omp parallel for simd' has clauses
00994 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
00995 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and
00996 /// 'd'.
00997 ///
00998 class OMPParallelForSimdDirective : public OMPLoopDirective {
00999   friend class ASTStmtReader;
01000   /// \brief Build directive with the given start and end location.
01001   ///
01002   /// \param StartLoc Starting location of the directive kind.
01003   /// \param EndLoc Ending location of the directive.
01004   /// \param CollapsedNum Number of collapsed nested loops.
01005   /// \param NumClauses Number of clauses.
01006   ///
01007   OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
01008                               unsigned CollapsedNum, unsigned NumClauses)
01009       : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
01010                          OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum,
01011                          NumClauses) {}
01012 
01013   /// \brief Build an empty directive.
01014   ///
01015   /// \param CollapsedNum Number of collapsed nested loops.
01016   /// \param NumClauses Number of clauses.
01017   ///
01018   explicit OMPParallelForSimdDirective(unsigned CollapsedNum,
01019                                        unsigned NumClauses)
01020       : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
01021                          OMPD_parallel_for_simd, SourceLocation(),
01022                          SourceLocation(), CollapsedNum, NumClauses) {}
01023 
01024 public:
01025   /// \brief Creates directive with a list of \a Clauses.
01026   ///
01027   /// \param C AST context.
01028   /// \param StartLoc Starting location of the directive kind.
01029   /// \param EndLoc Ending Location of the directive.
01030   /// \param CollapsedNum Number of collapsed loops.
01031   /// \param Clauses List of clauses.
01032   /// \param AssociatedStmt Statement, associated with the directive.
01033   /// \param IV Loop iteration variable for CodeGen.
01034   /// \param LastIteration Loop last iteration number for CodeGen.
01035   /// \param CalcLastIteration Calculation of last iteration.
01036   /// \param PreCond Pre-condition.
01037   /// \param Cond Condition.
01038   /// \param SeparatedCond Condition with 1 iteration separated.
01039   /// \param Inc Loop increment.
01040   /// \param Counters Loop counters.
01041   /// \param Updates Expressions for loop counters update for CodeGen.
01042   /// \param Finals Final loop counter values for GodeGen.
01043   ///
01044   static OMPParallelForSimdDirective *
01045   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
01046          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
01047          Stmt *AssociatedStmt, Expr *IV, Expr *LastIteration,
01048          Expr *CalcLastIteration, Expr *PreCond, Expr *Cond,
01049          Expr *SeparatedCond, Expr *Init, Expr *Inc, ArrayRef<Expr *> Counters,
01050          ArrayRef<Expr *> Updates, ArrayRef<Expr *> Finals);
01051 
01052   /// \brief Creates an empty directive with the place
01053   /// for \a NumClauses clauses.
01054   ///
01055   /// \param C AST context.
01056   /// \param CollapsedNum Number of collapsed nested loops.
01057   /// \param NumClauses Number of clauses.
01058   ///
01059   static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
01060                                                   unsigned NumClauses,
01061                                                   unsigned CollapsedNum,
01062                                                   EmptyShell);
01063 
01064   static bool classof(const Stmt *T) {
01065     return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
01066   }
01067 };
01068 
01069 /// \brief This represents '#pragma omp parallel sections' directive.
01070 ///
01071 /// \code
01072 /// #pragma omp parallel sections private(a,b) reduction(+:c,d)
01073 /// \endcode
01074 /// In this example directive '#pragma omp parallel sections' has clauses
01075 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
01076 /// and variables 'c' and 'd'.
01077 ///
01078 class OMPParallelSectionsDirective : public OMPExecutableDirective {
01079   friend class ASTStmtReader;
01080   /// \brief Build directive with the given start and end location.
01081   ///
01082   /// \param StartLoc Starting location of the directive kind.
01083   /// \param EndLoc Ending location of the directive.
01084   /// \param NumClauses Number of clauses.
01085   ///
01086   OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
01087                                unsigned NumClauses)
01088       : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
01089                                OMPD_parallel_sections, StartLoc, EndLoc,
01090                                NumClauses, 1) {}
01091 
01092   /// \brief Build an empty directive.
01093   ///
01094   /// \param NumClauses Number of clauses.
01095   ///
01096   explicit OMPParallelSectionsDirective(unsigned NumClauses)
01097       : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
01098                                OMPD_parallel_sections, SourceLocation(),
01099                                SourceLocation(), NumClauses, 1) {}
01100 
01101 public:
01102   /// \brief Creates directive with a list of \a Clauses.
01103   ///
01104   /// \param C AST context.
01105   /// \param StartLoc Starting location of the directive kind.
01106   /// \param EndLoc Ending Location of the directive.
01107   /// \param Clauses List of clauses.
01108   /// \param AssociatedStmt Statement, associated with the directive.
01109   ///
01110   static OMPParallelSectionsDirective *
01111   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
01112          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
01113 
01114   /// \brief Creates an empty directive with the place for \a NumClauses
01115   /// clauses.
01116   ///
01117   /// \param C AST context.
01118   /// \param NumClauses Number of clauses.
01119   ///
01120   static OMPParallelSectionsDirective *
01121   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
01122 
01123   static bool classof(const Stmt *T) {
01124     return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
01125   }
01126 };
01127 
01128 /// \brief This represents '#pragma omp task' directive.
01129 ///
01130 /// \code
01131 /// #pragma omp task private(a,b) final(d)
01132 /// \endcode
01133 /// In this example directive '#pragma omp task' has clauses 'private' with the
01134 /// variables 'a' and 'b' and 'final' with condition 'd'.
01135 ///
01136 class OMPTaskDirective : public OMPExecutableDirective {
01137   friend class ASTStmtReader;
01138   /// \brief Build directive with the given start and end location.
01139   ///
01140   /// \param StartLoc Starting location of the directive kind.
01141   /// \param EndLoc Ending location of the directive.
01142   /// \param NumClauses Number of clauses.
01143   ///
01144   OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
01145                    unsigned NumClauses)
01146       : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
01147                                EndLoc, NumClauses, 1) {}
01148 
01149   /// \brief Build an empty directive.
01150   ///
01151   /// \param NumClauses Number of clauses.
01152   ///
01153   explicit OMPTaskDirective(unsigned NumClauses)
01154       : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
01155                                SourceLocation(), SourceLocation(), NumClauses,
01156                                1) {}
01157 
01158 public:
01159   /// \brief Creates directive with a list of \a Clauses.
01160   ///
01161   /// \param C AST context.
01162   /// \param StartLoc Starting location of the directive kind.
01163   /// \param EndLoc Ending Location of the directive.
01164   /// \param Clauses List of clauses.
01165   /// \param AssociatedStmt Statement, associated with the directive.
01166   ///
01167   static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
01168                                   SourceLocation EndLoc,
01169                                   ArrayRef<OMPClause *> Clauses,
01170                                   Stmt *AssociatedStmt);
01171 
01172   /// \brief Creates an empty directive with the place for \a NumClauses
01173   /// clauses.
01174   ///
01175   /// \param C AST context.
01176   /// \param NumClauses Number of clauses.
01177   ///
01178   static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
01179                                        EmptyShell);
01180 
01181   static bool classof(const Stmt *T) {
01182     return T->getStmtClass() == OMPTaskDirectiveClass;
01183   }
01184 };
01185 
01186 /// \brief This represents '#pragma omp taskyield' directive.
01187 ///
01188 /// \code
01189 /// #pragma omp taskyield
01190 /// \endcode
01191 ///
01192 class OMPTaskyieldDirective : public OMPExecutableDirective {
01193   friend class ASTStmtReader;
01194   /// \brief Build directive with the given start and end location.
01195   ///
01196   /// \param StartLoc Starting location of the directive kind.
01197   /// \param EndLoc Ending location of the directive.
01198   ///
01199   OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
01200       : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
01201                                StartLoc, EndLoc, 0, 0) {}
01202 
01203   /// \brief Build an empty directive.
01204   ///
01205   explicit OMPTaskyieldDirective()
01206       : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
01207                                SourceLocation(), SourceLocation(), 0, 0) {}
01208 
01209 public:
01210   /// \brief Creates directive.
01211   ///
01212   /// \param C AST context.
01213   /// \param StartLoc Starting location of the directive kind.
01214   /// \param EndLoc Ending Location of the directive.
01215   ///
01216   static OMPTaskyieldDirective *
01217   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
01218 
01219   /// \brief Creates an empty directive.
01220   ///
01221   /// \param C AST context.
01222   ///
01223   static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
01224 
01225   static bool classof(const Stmt *T) {
01226     return T->getStmtClass() == OMPTaskyieldDirectiveClass;
01227   }
01228 };
01229 
01230 /// \brief This represents '#pragma omp barrier' directive.
01231 ///
01232 /// \code
01233 /// #pragma omp barrier
01234 /// \endcode
01235 ///
01236 class OMPBarrierDirective : public OMPExecutableDirective {
01237   friend class ASTStmtReader;
01238   /// \brief Build directive with the given start and end location.
01239   ///
01240   /// \param StartLoc Starting location of the directive kind.
01241   /// \param EndLoc Ending location of the directive.
01242   ///
01243   OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
01244       : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
01245                                StartLoc, EndLoc, 0, 0) {}
01246 
01247   /// \brief Build an empty directive.
01248   ///
01249   explicit OMPBarrierDirective()
01250       : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
01251                                SourceLocation(), SourceLocation(), 0, 0) {}
01252 
01253 public:
01254   /// \brief Creates directive.
01255   ///
01256   /// \param C AST context.
01257   /// \param StartLoc Starting location of the directive kind.
01258   /// \param EndLoc Ending Location of the directive.
01259   ///
01260   static OMPBarrierDirective *
01261   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
01262 
01263   /// \brief Creates an empty directive.
01264   ///
01265   /// \param C AST context.
01266   ///
01267   static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
01268 
01269   static bool classof(const Stmt *T) {
01270     return T->getStmtClass() == OMPBarrierDirectiveClass;
01271   }
01272 };
01273 
01274 /// \brief This represents '#pragma omp taskwait' directive.
01275 ///
01276 /// \code
01277 /// #pragma omp taskwait
01278 /// \endcode
01279 ///
01280 class OMPTaskwaitDirective : public OMPExecutableDirective {
01281   friend class ASTStmtReader;
01282   /// \brief Build directive with the given start and end location.
01283   ///
01284   /// \param StartLoc Starting location of the directive kind.
01285   /// \param EndLoc Ending location of the directive.
01286   ///
01287   OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
01288       : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
01289                                StartLoc, EndLoc, 0, 0) {}
01290 
01291   /// \brief Build an empty directive.
01292   ///
01293   explicit OMPTaskwaitDirective()
01294       : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
01295                                SourceLocation(), SourceLocation(), 0, 0) {}
01296 
01297 public:
01298   /// \brief Creates directive.
01299   ///
01300   /// \param C AST context.
01301   /// \param StartLoc Starting location of the directive kind.
01302   /// \param EndLoc Ending Location of the directive.
01303   ///
01304   static OMPTaskwaitDirective *
01305   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
01306 
01307   /// \brief Creates an empty directive.
01308   ///
01309   /// \param C AST context.
01310   ///
01311   static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
01312 
01313   static bool classof(const Stmt *T) {
01314     return T->getStmtClass() == OMPTaskwaitDirectiveClass;
01315   }
01316 };
01317 
01318 /// \brief This represents '#pragma omp flush' directive.
01319 ///
01320 /// \code
01321 /// #pragma omp flush(a,b)
01322 /// \endcode
01323 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
01324 /// and 'b'.
01325 /// 'omp flush' directive does not have clauses but have an optional list of
01326 /// variables to flush. This list of variables is stored within some fake clause
01327 /// FlushClause.
01328 class OMPFlushDirective : public OMPExecutableDirective {
01329   friend class ASTStmtReader;
01330   /// \brief Build directive with the given start and end location.
01331   ///
01332   /// \param StartLoc Starting location of the directive kind.
01333   /// \param EndLoc Ending location of the directive.
01334   /// \param NumClauses Number of clauses.
01335   ///
01336   OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
01337                     unsigned NumClauses)
01338       : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
01339                                StartLoc, EndLoc, NumClauses, 0) {}
01340 
01341   /// \brief Build an empty directive.
01342   ///
01343   /// \param NumClauses Number of clauses.
01344   ///
01345   explicit OMPFlushDirective(unsigned NumClauses)
01346       : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
01347                                SourceLocation(), SourceLocation(), NumClauses,
01348                                0) {}
01349 
01350 public:
01351   /// \brief Creates directive with a list of \a Clauses.
01352   ///
01353   /// \param C AST context.
01354   /// \param StartLoc Starting location of the directive kind.
01355   /// \param EndLoc Ending Location of the directive.
01356   /// \param Clauses List of clauses (only single OMPFlushClause clause is
01357   /// allowed).
01358   ///
01359   static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
01360                                    SourceLocation EndLoc,
01361                                    ArrayRef<OMPClause *> Clauses);
01362 
01363   /// \brief Creates an empty directive with the place for \a NumClauses
01364   /// clauses.
01365   ///
01366   /// \param C AST context.
01367   /// \param NumClauses Number of clauses.
01368   ///
01369   static OMPFlushDirective *CreateEmpty(const ASTContext &C,
01370                                         unsigned NumClauses, EmptyShell);
01371 
01372   static bool classof(const Stmt *T) {
01373     return T->getStmtClass() == OMPFlushDirectiveClass;
01374   }
01375 };
01376 
01377 /// \brief This represents '#pragma omp ordered' directive.
01378 ///
01379 /// \code
01380 /// #pragma omp ordered
01381 /// \endcode
01382 ///
01383 class OMPOrderedDirective : public OMPExecutableDirective {
01384   friend class ASTStmtReader;
01385   /// \brief Build directive with the given start and end location.
01386   ///
01387   /// \param StartLoc Starting location of the directive kind.
01388   /// \param EndLoc Ending location of the directive.
01389   ///
01390   OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
01391       : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
01392                                StartLoc, EndLoc, 0, 1) {}
01393 
01394   /// \brief Build an empty directive.
01395   ///
01396   explicit OMPOrderedDirective()
01397       : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
01398                                SourceLocation(), SourceLocation(), 0, 1) {}
01399 
01400 public:
01401   /// \brief Creates directive.
01402   ///
01403   /// \param C AST context.
01404   /// \param StartLoc Starting location of the directive kind.
01405   /// \param EndLoc Ending Location of the directive.
01406   /// \param AssociatedStmt Statement, associated with the directive.
01407   ///
01408   static OMPOrderedDirective *Create(const ASTContext &C,
01409                                      SourceLocation StartLoc,
01410                                      SourceLocation EndLoc,
01411                                      Stmt *AssociatedStmt);
01412 
01413   /// \brief Creates an empty directive.
01414   ///
01415   /// \param C AST context.
01416   ///
01417   static OMPOrderedDirective *CreateEmpty(const ASTContext &C, EmptyShell);
01418 
01419   static bool classof(const Stmt *T) {
01420     return T->getStmtClass() == OMPOrderedDirectiveClass;
01421   }
01422 };
01423 
01424 /// \brief This represents '#pragma omp atomic' directive.
01425 ///
01426 /// \code
01427 /// #pragma omp atomic capture
01428 /// \endcode
01429 /// In this example directive '#pragma omp atomic' has clause 'capture'.
01430 ///
01431 class OMPAtomicDirective : public OMPExecutableDirective {
01432   friend class ASTStmtReader;
01433   /// \brief Build directive with the given start and end location.
01434   ///
01435   /// \param StartLoc Starting location of the directive kind.
01436   /// \param EndLoc Ending location of the directive.
01437   /// \param NumClauses Number of clauses.
01438   ///
01439   OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc,
01440                      unsigned NumClauses)
01441       : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
01442                                StartLoc, EndLoc, NumClauses, 4) {}
01443 
01444   /// \brief Build an empty directive.
01445   ///
01446   /// \param NumClauses Number of clauses.
01447   ///
01448   explicit OMPAtomicDirective(unsigned NumClauses)
01449       : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
01450                                SourceLocation(), SourceLocation(), NumClauses,
01451                                4) {}
01452 
01453   /// \brief Set 'x' part of the associated expression/statement.
01454   void setX(Expr *X) { *std::next(child_begin()) = X; }
01455   /// \brief Set 'v' part of the associated expression/statement.
01456   void setV(Expr *V) { *std::next(child_begin(), 2) = V; }
01457   /// \brief Set 'expr' part of the associated expression/statement.
01458   void setExpr(Expr *E) { *std::next(child_begin(), 3) = E; }
01459 
01460 public:
01461   /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
01462   /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
01463   /// detailed description of 'x', 'v' and 'expr').
01464   ///
01465   /// \param C AST context.
01466   /// \param StartLoc Starting location of the directive kind.
01467   /// \param EndLoc Ending Location of the directive.
01468   /// \param Clauses List of clauses.
01469   /// \param AssociatedStmt Statement, associated with the directive.
01470   /// \param X 'x' part of the associated expression/statement.
01471   /// \param V 'v' part of the associated expression/statement.
01472   /// \param Expr 'expr' part of the associated expression/statement.
01473   ///
01474   static OMPAtomicDirective *
01475   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
01476          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
01477          Expr *E);
01478 
01479   /// \brief Creates an empty directive with the place for \a NumClauses
01480   /// clauses.
01481   ///
01482   /// \param C AST context.
01483   /// \param NumClauses Number of clauses.
01484   ///
01485   static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
01486                                          unsigned NumClauses, EmptyShell);
01487 
01488   /// \brief Get 'x' part of the associated expression/statement.
01489   Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); }
01490   const Expr *getX() const {
01491     return cast_or_null<Expr>(*std::next(child_begin()));
01492   }
01493   /// \brief Get 'v' part of the associated expression/statement.
01494   Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 2)); }
01495   const Expr *getV() const {
01496     return cast_or_null<Expr>(*std::next(child_begin(), 2));
01497   }
01498   /// \brief Get 'expr' part of the associated expression/statement.
01499   Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); }
01500   const Expr *getExpr() const {
01501     return cast_or_null<Expr>(*std::next(child_begin(), 3));
01502   }
01503 
01504   static bool classof(const Stmt *T) {
01505     return T->getStmtClass() == OMPAtomicDirectiveClass;
01506   }
01507 };
01508 
01509 /// \brief This represents '#pragma omp target' directive.
01510 ///
01511 /// \code
01512 /// #pragma omp target if(a)
01513 /// \endcode
01514 /// In this example directive '#pragma omp target' has clause 'if' with
01515 /// condition 'a'.
01516 ///
01517 class OMPTargetDirective : public OMPExecutableDirective {
01518   friend class ASTStmtReader;
01519   /// \brief Build directive with the given start and end location.
01520   ///
01521   /// \param StartLoc Starting location of the directive kind.
01522   /// \param EndLoc Ending location of the directive.
01523   /// \param NumClauses Number of clauses.
01524   ///
01525   OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc,
01526                      unsigned NumClauses)
01527       : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
01528                                StartLoc, EndLoc, NumClauses, 1) {}
01529 
01530   /// \brief Build an empty directive.
01531   ///
01532   /// \param NumClauses Number of clauses.
01533   ///
01534   explicit OMPTargetDirective(unsigned NumClauses)
01535       : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
01536                                SourceLocation(), SourceLocation(), NumClauses,
01537                                1) {}
01538 
01539 public:
01540   /// \brief Creates directive with a list of \a Clauses.
01541   ///
01542   /// \param C AST context.
01543   /// \param StartLoc Starting location of the directive kind.
01544   /// \param EndLoc Ending Location of the directive.
01545   /// \param Clauses List of clauses.
01546   /// \param AssociatedStmt Statement, associated with the directive.
01547   ///
01548   static OMPTargetDirective *
01549   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
01550          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
01551 
01552   /// \brief Creates an empty directive with the place for \a NumClauses
01553   /// clauses.
01554   ///
01555   /// \param C AST context.
01556   /// \param NumClauses Number of clauses.
01557   ///
01558   static OMPTargetDirective *CreateEmpty(const ASTContext &C,
01559                                          unsigned NumClauses, EmptyShell);
01560 
01561   static bool classof(const Stmt *T) {
01562     return T->getStmtClass() == OMPTargetDirectiveClass;
01563   }
01564 };
01565 
01566 /// \brief This represents '#pragma omp teams' directive.
01567 ///
01568 /// \code
01569 /// #pragma omp teams if(a)
01570 /// \endcode
01571 /// In this example directive '#pragma omp teams' has clause 'if' with
01572 /// condition 'a'.
01573 ///
01574 class OMPTeamsDirective : public OMPExecutableDirective {
01575   friend class ASTStmtReader;
01576   /// \brief Build directive with the given start and end location.
01577   ///
01578   /// \param StartLoc Starting location of the directive kind.
01579   /// \param EndLoc Ending location of the directive.
01580   /// \param NumClauses Number of clauses.
01581   ///
01582   OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
01583                     unsigned NumClauses)
01584       : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
01585                                StartLoc, EndLoc, NumClauses, 1) {}
01586 
01587   /// \brief Build an empty directive.
01588   ///
01589   /// \param NumClauses Number of clauses.
01590   ///
01591   explicit OMPTeamsDirective(unsigned NumClauses)
01592       : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
01593                                SourceLocation(), SourceLocation(), NumClauses,
01594                                1) {}
01595 
01596 public:
01597   /// \brief Creates directive with a list of \a Clauses.
01598   ///
01599   /// \param C AST context.
01600   /// \param StartLoc Starting location of the directive kind.
01601   /// \param EndLoc Ending Location of the directive.
01602   /// \param Clauses List of clauses.
01603   /// \param AssociatedStmt Statement, associated with the directive.
01604   ///
01605   static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
01606                                    SourceLocation EndLoc,
01607                                    ArrayRef<OMPClause *> Clauses,
01608                                    Stmt *AssociatedStmt);
01609 
01610   /// \brief Creates an empty directive with the place for \a NumClauses
01611   /// clauses.
01612   ///
01613   /// \param C AST context.
01614   /// \param NumClauses Number of clauses.
01615   ///
01616   static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
01617                                         unsigned NumClauses, EmptyShell);
01618 
01619   static bool classof(const Stmt *T) {
01620     return T->getStmtClass() == OMPTeamsDirectiveClass;
01621   }
01622 };
01623 
01624 } // end namespace clang
01625 
01626 #endif