Home | History | Annotate | Download | only in AST
      1 //===- StmtOpenMP.h - Classes for OpenMP directives  ------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 /// \file
     10 /// \brief This file defines OpenMP AST classes for executable directives and
     11 /// clauses.
     12 ///
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_CLANG_AST_STMTOPENMP_H
     16 #define LLVM_CLANG_AST_STMTOPENMP_H
     17 
     18 #include "clang/AST/Expr.h"
     19 #include "clang/AST/OpenMPClause.h"
     20 #include "clang/AST/Stmt.h"
     21 #include "clang/Basic/OpenMPKinds.h"
     22 #include "clang/Basic/SourceLocation.h"
     23 
     24 namespace clang {
     25 
     26 //===----------------------------------------------------------------------===//
     27 // AST classes for directives.
     28 //===----------------------------------------------------------------------===//
     29 
     30 /// \brief This is a basic class for representing single OpenMP executable
     31 /// directive.
     32 ///
     33 class OMPExecutableDirective : public Stmt {
     34   friend class ASTStmtReader;
     35   /// \brief Kind of the directive.
     36   OpenMPDirectiveKind Kind;
     37   /// \brief Starting location of the directive (directive keyword).
     38   SourceLocation StartLoc;
     39   /// \brief Ending location of the directive.
     40   SourceLocation EndLoc;
     41   /// \brief Numbers of clauses.
     42   const unsigned NumClauses;
     43   /// \brief Number of child expressions/stmts.
     44   const unsigned NumChildren;
     45   /// \brief Offset from this to the start of clauses.
     46   /// There are NumClauses pointers to clauses, they are followed by
     47   /// NumChildren pointers to child stmts/exprs (if the directive type
     48   /// requires an associated stmt, then it has to be the first of them).
     49   const unsigned ClausesOffset;
     50 
     51   /// \brief Get the clauses storage.
     52   MutableArrayRef<OMPClause *> getClauses() {
     53     OMPClause **ClauseStorage = reinterpret_cast<OMPClause **>(
     54         reinterpret_cast<char *>(this) + ClausesOffset);
     55     return MutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);
     56   }
     57 
     58 protected:
     59   /// \brief Build instance of directive of class \a K.
     60   ///
     61   /// \param SC Statement class.
     62   /// \param K Kind of OpenMP directive.
     63   /// \param StartLoc Starting location of the directive (directive keyword).
     64   /// \param EndLoc Ending location of the directive.
     65   ///
     66   template <typename T>
     67   OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K,
     68                          SourceLocation StartLoc, SourceLocation EndLoc,
     69                          unsigned NumClauses, unsigned NumChildren)
     70       : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
     71         EndLoc(std::move(EndLoc)), NumClauses(NumClauses),
     72         NumChildren(NumChildren),
     73         ClausesOffset(llvm::alignTo(sizeof(T), llvm::alignOf<OMPClause *>())) {}
     74 
     75   /// \brief Sets the list of variables for this clause.
     76   ///
     77   /// \param Clauses The list of clauses for the directive.
     78   ///
     79   void setClauses(ArrayRef<OMPClause *> Clauses);
     80 
     81   /// \brief Set the associated statement for the directive.
     82   ///
     83   /// /param S Associated statement.
     84   ///
     85   void setAssociatedStmt(Stmt *S) {
     86     assert(hasAssociatedStmt() && "no associated statement.");
     87     *child_begin() = S;
     88   }
     89 
     90 public:
     91   /// \brief Iterates over a filtered subrange of clauses applied to a
     92   /// directive.
     93   ///
     94   /// This iterator visits only clauses of type SpecificClause.
     95   template <typename SpecificClause>
     96   class specific_clause_iterator
     97       : public llvm::iterator_adaptor_base<
     98             specific_clause_iterator<SpecificClause>,
     99             ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag,
    100             const SpecificClause *, ptrdiff_t, const SpecificClause *,
    101             const SpecificClause *> {
    102     ArrayRef<OMPClause *>::const_iterator End;
    103 
    104     void SkipToNextClause() {
    105       while (this->I != End && !isa<SpecificClause>(*this->I))
    106         ++this->I;
    107     }
    108 
    109   public:
    110     explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses)
    111         : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()),
    112           End(Clauses.end()) {
    113       SkipToNextClause();
    114     }
    115 
    116     const SpecificClause *operator*() const {
    117       return cast<SpecificClause>(*this->I);
    118     }
    119     const SpecificClause *operator->() const { return **this; }
    120 
    121     specific_clause_iterator &operator++() {
    122       ++this->I;
    123       SkipToNextClause();
    124       return *this;
    125     }
    126   };
    127 
    128   template <typename SpecificClause>
    129   static llvm::iterator_range<specific_clause_iterator<SpecificClause>>
    130   getClausesOfKind(ArrayRef<OMPClause *> Clauses) {
    131     return {specific_clause_iterator<SpecificClause>(Clauses),
    132             specific_clause_iterator<SpecificClause>(
    133                 llvm::makeArrayRef(Clauses.end(), 0))};
    134   }
    135 
    136   template <typename SpecificClause>
    137   llvm::iterator_range<specific_clause_iterator<SpecificClause>>
    138   getClausesOfKind() const {
    139     return getClausesOfKind<SpecificClause>(clauses());
    140   }
    141 
    142   /// Gets a single clause of the specified kind associated with the
    143   /// current directive iff there is only one clause of this kind (and assertion
    144   /// is fired if there is more than one clause is associated with the
    145   /// directive). Returns nullptr if no clause of this kind is associated with
    146   /// the directive.
    147   template <typename SpecificClause>
    148   const SpecificClause *getSingleClause() const {
    149     auto Clauses = getClausesOfKind<SpecificClause>();
    150 
    151     if (Clauses.begin() != Clauses.end()) {
    152       assert(std::next(Clauses.begin()) == Clauses.end() &&
    153              "There are at least 2 clauses of the specified kind");
    154       return *Clauses.begin();
    155     }
    156     return nullptr;
    157   }
    158 
    159   /// Returns true if the current directive has one or more clauses of a
    160   /// specific kind.
    161   template <typename SpecificClause>
    162   bool hasClausesOfKind() const {
    163     auto Clauses = getClausesOfKind<SpecificClause>();
    164     return Clauses.begin() != Clauses.end();
    165   }
    166 
    167   /// \brief Returns starting location of directive kind.
    168   SourceLocation getLocStart() const { return StartLoc; }
    169   /// \brief Returns ending location of directive.
    170   SourceLocation getLocEnd() const { return EndLoc; }
    171 
    172   /// \brief Set starting location of directive kind.
    173   ///
    174   /// \param Loc New starting location of directive.
    175   ///
    176   void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
    177   /// \brief Set ending location of directive.
    178   ///
    179   /// \param Loc New ending location of directive.
    180   ///
    181   void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
    182 
    183   /// \brief Get number of clauses.
    184   unsigned getNumClauses() const { return NumClauses; }
    185 
    186   /// \brief Returns specified clause.
    187   ///
    188   /// \param i Number of clause.
    189   ///
    190   OMPClause *getClause(unsigned i) const { return clauses()[i]; }
    191 
    192   /// \brief Returns true if directive has associated statement.
    193   bool hasAssociatedStmt() const { return NumChildren > 0; }
    194 
    195   /// \brief Returns statement associated with the directive.
    196   Stmt *getAssociatedStmt() const {
    197     assert(hasAssociatedStmt() && "no associated statement.");
    198     return const_cast<Stmt *>(*child_begin());
    199   }
    200 
    201   OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
    202 
    203   static bool classof(const Stmt *S) {
    204     return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
    205            S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
    206   }
    207 
    208   child_range children() {
    209     if (!hasAssociatedStmt())
    210       return child_range(child_iterator(), child_iterator());
    211     Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
    212     return child_range(ChildStorage, ChildStorage + NumChildren);
    213   }
    214 
    215   ArrayRef<OMPClause *> clauses() { return getClauses(); }
    216 
    217   ArrayRef<OMPClause *> clauses() const {
    218     return const_cast<OMPExecutableDirective *>(this)->getClauses();
    219   }
    220 };
    221 
    222 /// \brief This represents '#pragma omp parallel' directive.
    223 ///
    224 /// \code
    225 /// #pragma omp parallel private(a,b) reduction(+: c,d)
    226 /// \endcode
    227 /// In this example directive '#pragma omp parallel' has clauses 'private'
    228 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
    229 /// variables 'c' and 'd'.
    230 ///
    231 class OMPParallelDirective : public OMPExecutableDirective {
    232   friend class ASTStmtReader;
    233   /// \brief true if the construct has inner cancel directive.
    234   bool HasCancel;
    235 
    236   /// \brief Build directive with the given start and end location.
    237   ///
    238   /// \param StartLoc Starting location of the directive (directive keyword).
    239   /// \param EndLoc Ending Location of the directive.
    240   ///
    241   OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    242                        unsigned NumClauses)
    243       : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
    244                                StartLoc, EndLoc, NumClauses, 1),
    245         HasCancel(false) {}
    246 
    247   /// \brief Build an empty directive.
    248   ///
    249   /// \param NumClauses Number of clauses.
    250   ///
    251   explicit OMPParallelDirective(unsigned NumClauses)
    252       : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
    253                                SourceLocation(), SourceLocation(), NumClauses,
    254                                1),
    255         HasCancel(false) {}
    256 
    257   /// \brief Set cancel state.
    258   void setHasCancel(bool Has) { HasCancel = Has; }
    259 
    260 public:
    261   /// \brief Creates directive with a list of \a Clauses.
    262   ///
    263   /// \param C AST context.
    264   /// \param StartLoc Starting location of the directive kind.
    265   /// \param EndLoc Ending Location of the directive.
    266   /// \param Clauses List of clauses.
    267   /// \param AssociatedStmt Statement associated with the directive.
    268   /// \param HasCancel true if this directive has inner cancel directive.
    269   ///
    270   static OMPParallelDirective *
    271   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
    272          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
    273 
    274   /// \brief Creates an empty directive with the place for \a N clauses.
    275   ///
    276   /// \param C AST context.
    277   /// \param NumClauses Number of clauses.
    278   ///
    279   static OMPParallelDirective *CreateEmpty(const ASTContext &C,
    280                                            unsigned NumClauses, EmptyShell);
    281 
    282   /// \brief Return true if current directive has inner cancel directive.
    283   bool hasCancel() const { return HasCancel; }
    284 
    285   static bool classof(const Stmt *T) {
    286     return T->getStmtClass() == OMPParallelDirectiveClass;
    287   }
    288 };
    289 
    290 /// \brief This is a common base class for loop directives ('omp simd', 'omp
    291 /// for', 'omp for simd' etc.). It is responsible for the loop code generation.
    292 ///
    293 class OMPLoopDirective : public OMPExecutableDirective {
    294   friend class ASTStmtReader;
    295   /// \brief Number of collapsed loops as specified by 'collapse' clause.
    296   unsigned CollapsedNum;
    297 
    298   /// \brief Offsets to the stored exprs.
    299   /// This enumeration contains offsets to all the pointers to children
    300   /// expressions stored in OMPLoopDirective.
    301   /// The first 9 children are nesessary for all the loop directives, and
    302   /// the next 10 are specific to the worksharing ones.
    303   /// After the fixed children, three arrays of length CollapsedNum are
    304   /// allocated: loop counters, their updates and final values.
    305   /// PrevLowerBound and PrevUpperBound are used to communicate blocking
    306   /// information in composite constructs which require loop blocking
    307   ///
    308   enum {
    309     AssociatedStmtOffset = 0,
    310     IterationVariableOffset = 1,
    311     LastIterationOffset = 2,
    312     CalcLastIterationOffset = 3,
    313     PreConditionOffset = 4,
    314     CondOffset = 5,
    315     InitOffset = 6,
    316     IncOffset = 7,
    317     PreInitsOffset = 8,
    318     // The '...End' enumerators do not correspond to child expressions - they
    319     // specify the offset to the end (and start of the following counters/
    320     // updates/finals arrays).
    321     DefaultEnd = 9,
    322     // The following 7 exprs are used by worksharing loops only.
    323     IsLastIterVariableOffset = 9,
    324     LowerBoundVariableOffset = 10,
    325     UpperBoundVariableOffset = 11,
    326     StrideVariableOffset = 12,
    327     EnsureUpperBoundOffset = 13,
    328     NextLowerBoundOffset = 14,
    329     NextUpperBoundOffset = 15,
    330     NumIterationsOffset = 16,
    331     PrevLowerBoundVariableOffset = 17,
    332     PrevUpperBoundVariableOffset = 18,
    333     // Offset to the end (and start of the following counters/updates/finals
    334     // arrays) for worksharing loop directives.
    335     WorksharingEnd = 19,
    336   };
    337 
    338   /// \brief Get the counters storage.
    339   MutableArrayRef<Expr *> getCounters() {
    340     Expr **Storage = reinterpret_cast<Expr **>(
    341         &(*(std::next(child_begin(), getArraysOffset(getDirectiveKind())))));
    342     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
    343   }
    344 
    345   /// \brief Get the private counters storage.
    346   MutableArrayRef<Expr *> getPrivateCounters() {
    347     Expr **Storage = reinterpret_cast<Expr **>(&*std::next(
    348         child_begin(), getArraysOffset(getDirectiveKind()) + CollapsedNum));
    349     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
    350   }
    351 
    352   /// \brief Get the updates storage.
    353   MutableArrayRef<Expr *> getInits() {
    354     Expr **Storage = reinterpret_cast<Expr **>(
    355         &*std::next(child_begin(),
    356                     getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum));
    357     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
    358   }
    359 
    360   /// \brief Get the updates storage.
    361   MutableArrayRef<Expr *> getUpdates() {
    362     Expr **Storage = reinterpret_cast<Expr **>(
    363         &*std::next(child_begin(),
    364                     getArraysOffset(getDirectiveKind()) + 3 * CollapsedNum));
    365     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
    366   }
    367 
    368   /// \brief Get the final counter updates storage.
    369   MutableArrayRef<Expr *> getFinals() {
    370     Expr **Storage = reinterpret_cast<Expr **>(
    371         &*std::next(child_begin(),
    372                     getArraysOffset(getDirectiveKind()) + 4 * CollapsedNum));
    373     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
    374   }
    375 
    376 protected:
    377   /// \brief Build instance of loop directive of class \a Kind.
    378   ///
    379   /// \param SC Statement class.
    380   /// \param Kind Kind of OpenMP directive.
    381   /// \param StartLoc Starting location of the directive (directive keyword).
    382   /// \param EndLoc Ending location of the directive.
    383   /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
    384   /// \param NumClauses Number of clauses.
    385   /// \param NumSpecialChildren Number of additional directive-specific stmts.
    386   ///
    387   template <typename T>
    388   OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind,
    389                    SourceLocation StartLoc, SourceLocation EndLoc,
    390                    unsigned CollapsedNum, unsigned NumClauses,
    391                    unsigned NumSpecialChildren = 0)
    392       : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses,
    393                                numLoopChildren(CollapsedNum, Kind) +
    394                                    NumSpecialChildren),
    395         CollapsedNum(CollapsedNum) {}
    396 
    397   /// \brief Offset to the start of children expression arrays.
    398   static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
    399     return (isOpenMPWorksharingDirective(Kind) ||
    400             isOpenMPTaskLoopDirective(Kind) ||
    401             isOpenMPDistributeDirective(Kind))
    402                ? WorksharingEnd
    403                : DefaultEnd;
    404   }
    405 
    406   /// \brief Children number.
    407   static unsigned numLoopChildren(unsigned CollapsedNum,
    408                                   OpenMPDirectiveKind Kind) {
    409     return getArraysOffset(Kind) + 5 * CollapsedNum; // Counters,
    410                                                      // PrivateCounters, Inits,
    411                                                      // Updates and Finals
    412   }
    413 
    414   void setIterationVariable(Expr *IV) {
    415     *std::next(child_begin(), IterationVariableOffset) = IV;
    416   }
    417   void setLastIteration(Expr *LI) {
    418     *std::next(child_begin(), LastIterationOffset) = LI;
    419   }
    420   void setCalcLastIteration(Expr *CLI) {
    421     *std::next(child_begin(), CalcLastIterationOffset) = CLI;
    422   }
    423   void setPreCond(Expr *PC) {
    424     *std::next(child_begin(), PreConditionOffset) = PC;
    425   }
    426   void setCond(Expr *Cond) {
    427     *std::next(child_begin(), CondOffset) = Cond;
    428   }
    429   void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; }
    430   void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; }
    431   void setPreInits(Stmt *PreInits) {
    432     *std::next(child_begin(), PreInitsOffset) = PreInits;
    433   }
    434   void setIsLastIterVariable(Expr *IL) {
    435     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    436             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    437             isOpenMPDistributeDirective(getDirectiveKind())) &&
    438            "expected worksharing loop directive");
    439     *std::next(child_begin(), IsLastIterVariableOffset) = IL;
    440   }
    441   void setLowerBoundVariable(Expr *LB) {
    442     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    443             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    444             isOpenMPDistributeDirective(getDirectiveKind())) &&
    445            "expected worksharing loop directive");
    446     *std::next(child_begin(), LowerBoundVariableOffset) = LB;
    447   }
    448   void setUpperBoundVariable(Expr *UB) {
    449     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    450             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    451             isOpenMPDistributeDirective(getDirectiveKind())) &&
    452            "expected worksharing loop directive");
    453     *std::next(child_begin(), UpperBoundVariableOffset) = UB;
    454   }
    455   void setStrideVariable(Expr *ST) {
    456     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    457             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    458             isOpenMPDistributeDirective(getDirectiveKind())) &&
    459            "expected worksharing loop directive");
    460     *std::next(child_begin(), StrideVariableOffset) = ST;
    461   }
    462   void setEnsureUpperBound(Expr *EUB) {
    463     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    464             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    465             isOpenMPDistributeDirective(getDirectiveKind())) &&
    466            "expected worksharing loop directive");
    467     *std::next(child_begin(), EnsureUpperBoundOffset) = EUB;
    468   }
    469   void setNextLowerBound(Expr *NLB) {
    470     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    471             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    472             isOpenMPDistributeDirective(getDirectiveKind())) &&
    473            "expected worksharing loop directive");
    474     *std::next(child_begin(), NextLowerBoundOffset) = NLB;
    475   }
    476   void setNextUpperBound(Expr *NUB) {
    477     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    478             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    479             isOpenMPDistributeDirective(getDirectiveKind())) &&
    480            "expected worksharing loop directive");
    481     *std::next(child_begin(), NextUpperBoundOffset) = NUB;
    482   }
    483   void setNumIterations(Expr *NI) {
    484     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    485             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    486             isOpenMPDistributeDirective(getDirectiveKind())) &&
    487            "expected worksharing loop directive");
    488     *std::next(child_begin(), NumIterationsOffset) = NI;
    489   }
    490   void setPrevLowerBoundVariable(Expr *PrevLB) {
    491     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    492             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    493             isOpenMPDistributeDirective(getDirectiveKind())) &&
    494            "expected worksharing loop directive");
    495     *std::next(child_begin(), PrevLowerBoundVariableOffset) = PrevLB;
    496   }
    497   void setPrevUpperBoundVariable(Expr *PrevUB) {
    498     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    499             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    500             isOpenMPDistributeDirective(getDirectiveKind())) &&
    501            "expected worksharing loop directive");
    502     *std::next(child_begin(), PrevUpperBoundVariableOffset) = PrevUB;
    503   }
    504   void setCounters(ArrayRef<Expr *> A);
    505   void setPrivateCounters(ArrayRef<Expr *> A);
    506   void setInits(ArrayRef<Expr *> A);
    507   void setUpdates(ArrayRef<Expr *> A);
    508   void setFinals(ArrayRef<Expr *> A);
    509 
    510 public:
    511   /// \brief The expressions built for the OpenMP loop CodeGen for the
    512   /// whole collapsed loop nest.
    513   struct HelperExprs {
    514     /// \brief Loop iteration variable.
    515     Expr *IterationVarRef;
    516     /// \brief Loop last iteration number.
    517     Expr *LastIteration;
    518     /// \brief Loop number of iterations.
    519     Expr *NumIterations;
    520     /// \brief Calculation of last iteration.
    521     Expr *CalcLastIteration;
    522     /// \brief Loop pre-condition.
    523     Expr *PreCond;
    524     /// \brief Loop condition.
    525     Expr *Cond;
    526     /// \brief Loop iteration variable init.
    527     Expr *Init;
    528     /// \brief Loop increment.
    529     Expr *Inc;
    530     /// \brief IsLastIteration - local flag variable passed to runtime.
    531     Expr *IL;
    532     /// \brief LowerBound - local variable passed to runtime.
    533     Expr *LB;
    534     /// \brief UpperBound - local variable passed to runtime.
    535     Expr *UB;
    536     /// \brief Stride - local variable passed to runtime.
    537     Expr *ST;
    538     /// \brief EnsureUpperBound -- expression LB = min(LB, NumIterations).
    539     Expr *EUB;
    540     /// \brief Update of LowerBound for statically sheduled 'omp for' loops.
    541     Expr *NLB;
    542     /// \brief Update of UpperBound for statically sheduled 'omp for' loops.
    543     Expr *NUB;
    544     /// \brief PreviousLowerBound - local variable passed to runtime in the
    545     /// enclosing schedule or null if that does not apply.
    546     Expr *PrevLB;
    547     /// \brief PreviousUpperBound - local variable passed to runtime in the
    548     /// enclosing schedule or null if that does not apply.
    549     Expr *PrevUB;
    550     /// \brief Counters Loop counters.
    551     SmallVector<Expr *, 4> Counters;
    552     /// \brief PrivateCounters Loop counters.
    553     SmallVector<Expr *, 4> PrivateCounters;
    554     /// \brief Expressions for loop counters inits for CodeGen.
    555     SmallVector<Expr *, 4> Inits;
    556     /// \brief Expressions for loop counters update for CodeGen.
    557     SmallVector<Expr *, 4> Updates;
    558     /// \brief Final loop counter values for GodeGen.
    559     SmallVector<Expr *, 4> Finals;
    560     /// Init statement for all captured expressions.
    561     Stmt *PreInits;
    562 
    563     /// \brief Check if all the expressions are built (does not check the
    564     /// worksharing ones).
    565     bool builtAll() {
    566       return IterationVarRef != nullptr && LastIteration != nullptr &&
    567              NumIterations != nullptr && PreCond != nullptr &&
    568              Cond != nullptr && Init != nullptr && Inc != nullptr;
    569     }
    570 
    571     /// \brief Initialize all the fields to null.
    572     /// \param Size Number of elements in the counters/finals/updates arrays.
    573     void clear(unsigned Size) {
    574       IterationVarRef = nullptr;
    575       LastIteration = nullptr;
    576       CalcLastIteration = nullptr;
    577       PreCond = nullptr;
    578       Cond = nullptr;
    579       Init = nullptr;
    580       Inc = nullptr;
    581       IL = nullptr;
    582       LB = nullptr;
    583       UB = nullptr;
    584       ST = nullptr;
    585       EUB = nullptr;
    586       NLB = nullptr;
    587       NUB = nullptr;
    588       NumIterations = nullptr;
    589       PrevLB = nullptr;
    590       PrevUB = nullptr;
    591       Counters.resize(Size);
    592       PrivateCounters.resize(Size);
    593       Inits.resize(Size);
    594       Updates.resize(Size);
    595       Finals.resize(Size);
    596       for (unsigned i = 0; i < Size; ++i) {
    597         Counters[i] = nullptr;
    598         PrivateCounters[i] = nullptr;
    599         Inits[i] = nullptr;
    600         Updates[i] = nullptr;
    601         Finals[i] = nullptr;
    602       }
    603       PreInits = nullptr;
    604     }
    605   };
    606 
    607   /// \brief Get number of collapsed loops.
    608   unsigned getCollapsedNumber() const { return CollapsedNum; }
    609 
    610   Expr *getIterationVariable() const {
    611     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    612         *std::next(child_begin(), IterationVariableOffset)));
    613   }
    614   Expr *getLastIteration() const {
    615     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    616         *std::next(child_begin(), LastIterationOffset)));
    617   }
    618   Expr *getCalcLastIteration() const {
    619     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    620         *std::next(child_begin(), CalcLastIterationOffset)));
    621   }
    622   Expr *getPreCond() const {
    623     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    624         *std::next(child_begin(), PreConditionOffset)));
    625   }
    626   Expr *getCond() const {
    627     return const_cast<Expr *>(
    628         reinterpret_cast<const Expr *>(*std::next(child_begin(), CondOffset)));
    629   }
    630   Expr *getInit() const {
    631     return const_cast<Expr *>(
    632         reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset)));
    633   }
    634   Expr *getInc() const {
    635     return const_cast<Expr *>(
    636         reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset)));
    637   }
    638   const Stmt *getPreInits() const {
    639     return *std::next(child_begin(), PreInitsOffset);
    640   }
    641   Stmt *getPreInits() { return *std::next(child_begin(), PreInitsOffset); }
    642   Expr *getIsLastIterVariable() const {
    643     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    644             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    645             isOpenMPDistributeDirective(getDirectiveKind())) &&
    646            "expected worksharing loop directive");
    647     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    648         *std::next(child_begin(), IsLastIterVariableOffset)));
    649   }
    650   Expr *getLowerBoundVariable() const {
    651     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    652             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    653             isOpenMPDistributeDirective(getDirectiveKind())) &&
    654            "expected worksharing loop directive");
    655     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    656         *std::next(child_begin(), LowerBoundVariableOffset)));
    657   }
    658   Expr *getUpperBoundVariable() const {
    659     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    660             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    661             isOpenMPDistributeDirective(getDirectiveKind())) &&
    662            "expected worksharing loop directive");
    663     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    664         *std::next(child_begin(), UpperBoundVariableOffset)));
    665   }
    666   Expr *getStrideVariable() const {
    667     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    668             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    669             isOpenMPDistributeDirective(getDirectiveKind())) &&
    670            "expected worksharing loop directive");
    671     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    672         *std::next(child_begin(), StrideVariableOffset)));
    673   }
    674   Expr *getEnsureUpperBound() const {
    675     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    676             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    677             isOpenMPDistributeDirective(getDirectiveKind())) &&
    678            "expected worksharing loop directive");
    679     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    680         *std::next(child_begin(), EnsureUpperBoundOffset)));
    681   }
    682   Expr *getNextLowerBound() const {
    683     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    684             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    685             isOpenMPDistributeDirective(getDirectiveKind())) &&
    686            "expected worksharing loop directive");
    687     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    688         *std::next(child_begin(), NextLowerBoundOffset)));
    689   }
    690   Expr *getNextUpperBound() const {
    691     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    692             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    693             isOpenMPDistributeDirective(getDirectiveKind())) &&
    694            "expected worksharing loop directive");
    695     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    696         *std::next(child_begin(), NextUpperBoundOffset)));
    697   }
    698   Expr *getNumIterations() const {
    699     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    700             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    701             isOpenMPDistributeDirective(getDirectiveKind())) &&
    702            "expected worksharing loop directive");
    703     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    704         *std::next(child_begin(), NumIterationsOffset)));
    705   }
    706   Expr *getPrevLowerBoundVariable() const {
    707     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    708             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    709             isOpenMPDistributeDirective(getDirectiveKind())) &&
    710            "expected worksharing loop directive");
    711     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    712         *std::next(child_begin(), PrevLowerBoundVariableOffset)));
    713   }
    714   Expr *getPrevUpperBoundVariable() const {
    715     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    716             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    717             isOpenMPDistributeDirective(getDirectiveKind())) &&
    718            "expected worksharing loop directive");
    719     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    720         *std::next(child_begin(), PrevUpperBoundVariableOffset)));
    721   }
    722   const Stmt *getBody() const {
    723     // This relies on the loop form is already checked by Sema.
    724     Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
    725     Body = cast<ForStmt>(Body)->getBody();
    726     for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
    727       Body = Body->IgnoreContainers();
    728       Body = cast<ForStmt>(Body)->getBody();
    729     }
    730     return Body;
    731   }
    732 
    733   ArrayRef<Expr *> counters() { return getCounters(); }
    734 
    735   ArrayRef<Expr *> counters() const {
    736     return const_cast<OMPLoopDirective *>(this)->getCounters();
    737   }
    738 
    739   ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
    740 
    741   ArrayRef<Expr *> private_counters() const {
    742     return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
    743   }
    744 
    745   ArrayRef<Expr *> inits() { return getInits(); }
    746 
    747   ArrayRef<Expr *> inits() const {
    748     return const_cast<OMPLoopDirective *>(this)->getInits();
    749   }
    750 
    751   ArrayRef<Expr *> updates() { return getUpdates(); }
    752 
    753   ArrayRef<Expr *> updates() const {
    754     return const_cast<OMPLoopDirective *>(this)->getUpdates();
    755   }
    756 
    757   ArrayRef<Expr *> finals() { return getFinals(); }
    758 
    759   ArrayRef<Expr *> finals() const {
    760     return const_cast<OMPLoopDirective *>(this)->getFinals();
    761   }
    762 
    763   static bool classof(const Stmt *T) {
    764     return T->getStmtClass() == OMPSimdDirectiveClass ||
    765            T->getStmtClass() == OMPForDirectiveClass ||
    766            T->getStmtClass() == OMPForSimdDirectiveClass ||
    767            T->getStmtClass() == OMPParallelForDirectiveClass ||
    768            T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
    769            T->getStmtClass() == OMPTaskLoopDirectiveClass ||
    770            T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
    771            T->getStmtClass() == OMPDistributeDirectiveClass ||
    772            T->getStmtClass() == OMPTargetParallelForDirectiveClass ||
    773            T->getStmtClass() == OMPDistributeParallelForDirectiveClass ||
    774            T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass ||
    775            T->getStmtClass() == OMPDistributeSimdDirectiveClass ||
    776            T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
    777   }
    778 };
    779 
    780 /// \brief This represents '#pragma omp simd' directive.
    781 ///
    782 /// \code
    783 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
    784 /// \endcode
    785 /// In this example directive '#pragma omp simd' has clauses 'private'
    786 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
    787 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
    788 ///
    789 class OMPSimdDirective : public OMPLoopDirective {
    790   friend class ASTStmtReader;
    791   /// \brief Build directive with the given start and end location.
    792   ///
    793   /// \param StartLoc Starting location of the directive kind.
    794   /// \param EndLoc Ending location of the directive.
    795   /// \param CollapsedNum Number of collapsed nested loops.
    796   /// \param NumClauses Number of clauses.
    797   ///
    798   OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    799                    unsigned CollapsedNum, unsigned NumClauses)
    800       : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
    801                          EndLoc, CollapsedNum, NumClauses) {}
    802 
    803   /// \brief Build an empty directive.
    804   ///
    805   /// \param CollapsedNum Number of collapsed nested loops.
    806   /// \param NumClauses Number of clauses.
    807   ///
    808   explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
    809       : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd,
    810                          SourceLocation(), SourceLocation(), CollapsedNum,
    811                          NumClauses) {}
    812 
    813 public:
    814   /// \brief Creates directive with a list of \a Clauses.
    815   ///
    816   /// \param C AST context.
    817   /// \param StartLoc Starting location of the directive kind.
    818   /// \param EndLoc Ending Location of the directive.
    819   /// \param CollapsedNum Number of collapsed loops.
    820   /// \param Clauses List of clauses.
    821   /// \param AssociatedStmt Statement, associated with the directive.
    822   /// \param Exprs Helper expressions for CodeGen.
    823   ///
    824   static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
    825                                   SourceLocation EndLoc, unsigned CollapsedNum,
    826                                   ArrayRef<OMPClause *> Clauses,
    827                                   Stmt *AssociatedStmt,
    828                                   const HelperExprs &Exprs);
    829 
    830   /// \brief Creates an empty directive with the place
    831   /// for \a NumClauses clauses.
    832   ///
    833   /// \param C AST context.
    834   /// \param CollapsedNum Number of collapsed nested loops.
    835   /// \param NumClauses Number of clauses.
    836   ///
    837   static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
    838                                        unsigned CollapsedNum, EmptyShell);
    839 
    840   static bool classof(const Stmt *T) {
    841     return T->getStmtClass() == OMPSimdDirectiveClass;
    842   }
    843 };
    844 
    845 /// \brief This represents '#pragma omp for' directive.
    846 ///
    847 /// \code
    848 /// #pragma omp for private(a,b) reduction(+:c,d)
    849 /// \endcode
    850 /// In this example directive '#pragma omp for' has clauses 'private' with the
    851 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
    852 /// and 'd'.
    853 ///
    854 class OMPForDirective : public OMPLoopDirective {
    855   friend class ASTStmtReader;
    856 
    857   /// \brief true if current directive has inner cancel directive.
    858   bool HasCancel;
    859 
    860   /// \brief Build directive with the given start and end location.
    861   ///
    862   /// \param StartLoc Starting location of the directive kind.
    863   /// \param EndLoc Ending location of the directive.
    864   /// \param CollapsedNum Number of collapsed nested loops.
    865   /// \param NumClauses Number of clauses.
    866   ///
    867   OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    868                   unsigned CollapsedNum, unsigned NumClauses)
    869       : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc,
    870                          CollapsedNum, NumClauses),
    871         HasCancel(false) {}
    872 
    873   /// \brief Build an empty directive.
    874   ///
    875   /// \param CollapsedNum Number of collapsed nested loops.
    876   /// \param NumClauses Number of clauses.
    877   ///
    878   explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
    879       : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(),
    880                          SourceLocation(), CollapsedNum, NumClauses),
    881         HasCancel(false) {}
    882 
    883   /// \brief Set cancel state.
    884   void setHasCancel(bool Has) { HasCancel = Has; }
    885 
    886 public:
    887   /// \brief Creates directive with a list of \a Clauses.
    888   ///
    889   /// \param C AST context.
    890   /// \param StartLoc Starting location of the directive kind.
    891   /// \param EndLoc Ending Location of the directive.
    892   /// \param CollapsedNum Number of collapsed loops.
    893   /// \param Clauses List of clauses.
    894   /// \param AssociatedStmt Statement, associated with the directive.
    895   /// \param Exprs Helper expressions for CodeGen.
    896   /// \param HasCancel true if current directive has inner cancel directive.
    897   ///
    898   static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
    899                                  SourceLocation EndLoc, unsigned CollapsedNum,
    900                                  ArrayRef<OMPClause *> Clauses,
    901                                  Stmt *AssociatedStmt, const HelperExprs &Exprs,
    902                                  bool HasCancel);
    903 
    904   /// \brief Creates an empty directive with the place
    905   /// for \a NumClauses clauses.
    906   ///
    907   /// \param C AST context.
    908   /// \param CollapsedNum Number of collapsed nested loops.
    909   /// \param NumClauses Number of clauses.
    910   ///
    911   static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
    912                                       unsigned CollapsedNum, EmptyShell);
    913 
    914   /// \brief Return true if current directive has inner cancel directive.
    915   bool hasCancel() const { return HasCancel; }
    916 
    917   static bool classof(const Stmt *T) {
    918     return T->getStmtClass() == OMPForDirectiveClass;
    919   }
    920 };
    921 
    922 /// \brief This represents '#pragma omp for simd' directive.
    923 ///
    924 /// \code
    925 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
    926 /// \endcode
    927 /// In this example directive '#pragma omp for simd' has clauses 'private'
    928 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
    929 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
    930 ///
    931 class OMPForSimdDirective : public OMPLoopDirective {
    932   friend class ASTStmtReader;
    933   /// \brief Build directive with the given start and end location.
    934   ///
    935   /// \param StartLoc Starting location of the directive kind.
    936   /// \param EndLoc Ending location of the directive.
    937   /// \param CollapsedNum Number of collapsed nested loops.
    938   /// \param NumClauses Number of clauses.
    939   ///
    940   OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    941                       unsigned CollapsedNum, unsigned NumClauses)
    942       : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
    943                          StartLoc, EndLoc, CollapsedNum, NumClauses) {}
    944 
    945   /// \brief Build an empty directive.
    946   ///
    947   /// \param CollapsedNum Number of collapsed nested loops.
    948   /// \param NumClauses Number of clauses.
    949   ///
    950   explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
    951       : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
    952                          SourceLocation(), SourceLocation(), CollapsedNum,
    953                          NumClauses) {}
    954 
    955 public:
    956   /// \brief Creates directive with a list of \a Clauses.
    957   ///
    958   /// \param C AST context.
    959   /// \param StartLoc Starting location of the directive kind.
    960   /// \param EndLoc Ending Location of the directive.
    961   /// \param CollapsedNum Number of collapsed loops.
    962   /// \param Clauses List of clauses.
    963   /// \param AssociatedStmt Statement, associated with the directive.
    964   /// \param Exprs Helper expressions for CodeGen.
    965   ///
    966   static OMPForSimdDirective *
    967   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
    968          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
    969          Stmt *AssociatedStmt, const HelperExprs &Exprs);
    970 
    971   /// \brief Creates an empty directive with the place
    972   /// for \a NumClauses clauses.
    973   ///
    974   /// \param C AST context.
    975   /// \param CollapsedNum Number of collapsed nested loops.
    976   /// \param NumClauses Number of clauses.
    977   ///
    978   static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
    979                                           unsigned NumClauses,
    980                                           unsigned CollapsedNum, EmptyShell);
    981 
    982   static bool classof(const Stmt *T) {
    983     return T->getStmtClass() == OMPForSimdDirectiveClass;
    984   }
    985 };
    986 
    987 /// \brief This represents '#pragma omp sections' directive.
    988 ///
    989 /// \code
    990 /// #pragma omp sections private(a,b) reduction(+:c,d)
    991 /// \endcode
    992 /// In this example directive '#pragma omp sections' has clauses 'private' with
    993 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
    994 /// 'c' and 'd'.
    995 ///
    996 class OMPSectionsDirective : public OMPExecutableDirective {
    997   friend class ASTStmtReader;
    998 
    999   /// \brief true if current directive has inner cancel directive.
   1000   bool HasCancel;
   1001 
   1002   /// \brief Build directive with the given start and end location.
   1003   ///
   1004   /// \param StartLoc Starting location of the directive kind.
   1005   /// \param EndLoc Ending location of the directive.
   1006   /// \param NumClauses Number of clauses.
   1007   ///
   1008   OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1009                        unsigned NumClauses)
   1010       : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
   1011                                StartLoc, EndLoc, NumClauses, 1),
   1012         HasCancel(false) {}
   1013 
   1014   /// \brief Build an empty directive.
   1015   ///
   1016   /// \param NumClauses Number of clauses.
   1017   ///
   1018   explicit OMPSectionsDirective(unsigned NumClauses)
   1019       : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
   1020                                SourceLocation(), SourceLocation(), NumClauses,
   1021                                1),
   1022         HasCancel(false) {}
   1023 
   1024   /// \brief Set cancel state.
   1025   void setHasCancel(bool Has) { HasCancel = Has; }
   1026 
   1027 public:
   1028   /// \brief Creates directive with a list of \a Clauses.
   1029   ///
   1030   /// \param C AST context.
   1031   /// \param StartLoc Starting location of the directive kind.
   1032   /// \param EndLoc Ending Location of the directive.
   1033   /// \param Clauses List of clauses.
   1034   /// \param AssociatedStmt Statement, associated with the directive.
   1035   /// \param HasCancel true if current directive has inner directive.
   1036   ///
   1037   static OMPSectionsDirective *
   1038   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1039          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
   1040 
   1041   /// \brief Creates an empty directive with the place for \a NumClauses
   1042   /// clauses.
   1043   ///
   1044   /// \param C AST context.
   1045   /// \param NumClauses Number of clauses.
   1046   ///
   1047   static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
   1048                                            unsigned NumClauses, EmptyShell);
   1049 
   1050   /// \brief Return true if current directive has inner cancel directive.
   1051   bool hasCancel() const { return HasCancel; }
   1052 
   1053   static bool classof(const Stmt *T) {
   1054     return T->getStmtClass() == OMPSectionsDirectiveClass;
   1055   }
   1056 };
   1057 
   1058 /// \brief This represents '#pragma omp section' directive.
   1059 ///
   1060 /// \code
   1061 /// #pragma omp section
   1062 /// \endcode
   1063 ///
   1064 class OMPSectionDirective : public OMPExecutableDirective {
   1065   friend class ASTStmtReader;
   1066 
   1067   /// \brief true if current directive has inner cancel directive.
   1068   bool HasCancel;
   1069 
   1070   /// \brief Build directive with the given start and end location.
   1071   ///
   1072   /// \param StartLoc Starting location of the directive kind.
   1073   /// \param EndLoc Ending location of the directive.
   1074   ///
   1075   OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1076       : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
   1077                                StartLoc, EndLoc, 0, 1),
   1078         HasCancel(false) {}
   1079 
   1080   /// \brief Build an empty directive.
   1081   ///
   1082   explicit OMPSectionDirective()
   1083       : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
   1084                                SourceLocation(), SourceLocation(), 0, 1),
   1085         HasCancel(false) {}
   1086 
   1087 public:
   1088   /// \brief Creates directive.
   1089   ///
   1090   /// \param C AST context.
   1091   /// \param StartLoc Starting location of the directive kind.
   1092   /// \param EndLoc Ending Location of the directive.
   1093   /// \param AssociatedStmt Statement, associated with the directive.
   1094   /// \param HasCancel true if current directive has inner directive.
   1095   ///
   1096   static OMPSectionDirective *Create(const ASTContext &C,
   1097                                      SourceLocation StartLoc,
   1098                                      SourceLocation EndLoc,
   1099                                      Stmt *AssociatedStmt, bool HasCancel);
   1100 
   1101   /// \brief Creates an empty directive.
   1102   ///
   1103   /// \param C AST context.
   1104   ///
   1105   static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1106 
   1107   /// \brief Set cancel state.
   1108   void setHasCancel(bool Has) { HasCancel = Has; }
   1109 
   1110   /// \brief Return true if current directive has inner cancel directive.
   1111   bool hasCancel() const { return HasCancel; }
   1112 
   1113   static bool classof(const Stmt *T) {
   1114     return T->getStmtClass() == OMPSectionDirectiveClass;
   1115   }
   1116 };
   1117 
   1118 /// \brief This represents '#pragma omp single' directive.
   1119 ///
   1120 /// \code
   1121 /// #pragma omp single private(a,b) copyprivate(c,d)
   1122 /// \endcode
   1123 /// In this example directive '#pragma omp single' has clauses 'private' with
   1124 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
   1125 ///
   1126 class OMPSingleDirective : public OMPExecutableDirective {
   1127   friend class ASTStmtReader;
   1128   /// \brief Build directive with the given start and end location.
   1129   ///
   1130   /// \param StartLoc Starting location of the directive kind.
   1131   /// \param EndLoc Ending location of the directive.
   1132   /// \param NumClauses Number of clauses.
   1133   ///
   1134   OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1135                      unsigned NumClauses)
   1136       : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
   1137                                StartLoc, EndLoc, NumClauses, 1) {}
   1138 
   1139   /// \brief Build an empty directive.
   1140   ///
   1141   /// \param NumClauses Number of clauses.
   1142   ///
   1143   explicit OMPSingleDirective(unsigned NumClauses)
   1144       : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
   1145                                SourceLocation(), SourceLocation(), NumClauses,
   1146                                1) {}
   1147 
   1148 public:
   1149   /// \brief Creates directive with a list of \a Clauses.
   1150   ///
   1151   /// \param C AST context.
   1152   /// \param StartLoc Starting location of the directive kind.
   1153   /// \param EndLoc Ending Location of the directive.
   1154   /// \param Clauses List of clauses.
   1155   /// \param AssociatedStmt Statement, associated with the directive.
   1156   ///
   1157   static OMPSingleDirective *
   1158   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1159          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   1160 
   1161   /// \brief Creates an empty directive with the place for \a NumClauses
   1162   /// clauses.
   1163   ///
   1164   /// \param C AST context.
   1165   /// \param NumClauses Number of clauses.
   1166   ///
   1167   static OMPSingleDirective *CreateEmpty(const ASTContext &C,
   1168                                          unsigned NumClauses, EmptyShell);
   1169 
   1170   static bool classof(const Stmt *T) {
   1171     return T->getStmtClass() == OMPSingleDirectiveClass;
   1172   }
   1173 };
   1174 
   1175 /// \brief This represents '#pragma omp master' directive.
   1176 ///
   1177 /// \code
   1178 /// #pragma omp master
   1179 /// \endcode
   1180 ///
   1181 class OMPMasterDirective : public OMPExecutableDirective {
   1182   friend class ASTStmtReader;
   1183   /// \brief Build directive with the given start and end location.
   1184   ///
   1185   /// \param StartLoc Starting location of the directive kind.
   1186   /// \param EndLoc Ending location of the directive.
   1187   ///
   1188   OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1189       : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
   1190                                StartLoc, EndLoc, 0, 1) {}
   1191 
   1192   /// \brief Build an empty directive.
   1193   ///
   1194   explicit OMPMasterDirective()
   1195       : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
   1196                                SourceLocation(), SourceLocation(), 0, 1) {}
   1197 
   1198 public:
   1199   /// \brief Creates directive.
   1200   ///
   1201   /// \param C AST context.
   1202   /// \param StartLoc Starting location of the directive kind.
   1203   /// \param EndLoc Ending Location of the directive.
   1204   /// \param AssociatedStmt Statement, associated with the directive.
   1205   ///
   1206   static OMPMasterDirective *Create(const ASTContext &C,
   1207                                     SourceLocation StartLoc,
   1208                                     SourceLocation EndLoc,
   1209                                     Stmt *AssociatedStmt);
   1210 
   1211   /// \brief Creates an empty directive.
   1212   ///
   1213   /// \param C AST context.
   1214   ///
   1215   static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1216 
   1217   static bool classof(const Stmt *T) {
   1218     return T->getStmtClass() == OMPMasterDirectiveClass;
   1219   }
   1220 };
   1221 
   1222 /// \brief This represents '#pragma omp critical' directive.
   1223 ///
   1224 /// \code
   1225 /// #pragma omp critical
   1226 /// \endcode
   1227 ///
   1228 class OMPCriticalDirective : public OMPExecutableDirective {
   1229   friend class ASTStmtReader;
   1230   /// \brief Name of the directive.
   1231   DeclarationNameInfo DirName;
   1232   /// \brief Build directive with the given start and end location.
   1233   ///
   1234   /// \param Name Name of the directive.
   1235   /// \param StartLoc Starting location of the directive kind.
   1236   /// \param EndLoc Ending location of the directive.
   1237   /// \param NumClauses Number of clauses.
   1238   ///
   1239   OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
   1240                        SourceLocation EndLoc, unsigned NumClauses)
   1241       : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
   1242                                StartLoc, EndLoc, NumClauses, 1),
   1243         DirName(Name) {}
   1244 
   1245   /// \brief Build an empty directive.
   1246   ///
   1247   /// \param NumClauses Number of clauses.
   1248   ///
   1249   explicit OMPCriticalDirective(unsigned NumClauses)
   1250       : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
   1251                                SourceLocation(), SourceLocation(), NumClauses,
   1252                                1),
   1253         DirName() {}
   1254 
   1255   /// \brief Set name of the directive.
   1256   ///
   1257   /// \param Name Name of the directive.
   1258   ///
   1259   void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
   1260 
   1261 public:
   1262   /// \brief Creates directive.
   1263   ///
   1264   /// \param C AST context.
   1265   /// \param Name Name of the directive.
   1266   /// \param StartLoc Starting location of the directive kind.
   1267   /// \param EndLoc Ending Location of the directive.
   1268   /// \param Clauses List of clauses.
   1269   /// \param AssociatedStmt Statement, associated with the directive.
   1270   ///
   1271   static OMPCriticalDirective *
   1272   Create(const ASTContext &C, const DeclarationNameInfo &Name,
   1273          SourceLocation StartLoc, SourceLocation EndLoc,
   1274          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   1275 
   1276   /// \brief Creates an empty directive.
   1277   ///
   1278   /// \param C AST context.
   1279   /// \param NumClauses Number of clauses.
   1280   ///
   1281   static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
   1282                                            unsigned NumClauses, EmptyShell);
   1283 
   1284   /// \brief Return name of the directive.
   1285   ///
   1286   DeclarationNameInfo getDirectiveName() const { return DirName; }
   1287 
   1288   static bool classof(const Stmt *T) {
   1289     return T->getStmtClass() == OMPCriticalDirectiveClass;
   1290   }
   1291 };
   1292 
   1293 /// \brief This represents '#pragma omp parallel for' directive.
   1294 ///
   1295 /// \code
   1296 /// #pragma omp parallel for private(a,b) reduction(+:c,d)
   1297 /// \endcode
   1298 /// In this example directive '#pragma omp parallel for' has clauses 'private'
   1299 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
   1300 /// variables 'c' and 'd'.
   1301 ///
   1302 class OMPParallelForDirective : public OMPLoopDirective {
   1303   friend class ASTStmtReader;
   1304 
   1305   /// \brief true if current region has inner cancel directive.
   1306   bool HasCancel;
   1307 
   1308   /// \brief Build directive with the given start and end location.
   1309   ///
   1310   /// \param StartLoc Starting location of the directive kind.
   1311   /// \param EndLoc Ending location of the directive.
   1312   /// \param CollapsedNum Number of collapsed nested loops.
   1313   /// \param NumClauses Number of clauses.
   1314   ///
   1315   OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1316                           unsigned CollapsedNum, unsigned NumClauses)
   1317       : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
   1318                          StartLoc, EndLoc, CollapsedNum, NumClauses),
   1319         HasCancel(false) {}
   1320 
   1321   /// \brief Build an empty directive.
   1322   ///
   1323   /// \param CollapsedNum Number of collapsed nested loops.
   1324   /// \param NumClauses Number of clauses.
   1325   ///
   1326   explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
   1327       : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
   1328                          SourceLocation(), SourceLocation(), CollapsedNum,
   1329                          NumClauses),
   1330         HasCancel(false) {}
   1331 
   1332   /// \brief Set cancel state.
   1333   void setHasCancel(bool Has) { HasCancel = Has; }
   1334 
   1335 public:
   1336   /// \brief Creates directive with a list of \a Clauses.
   1337   ///
   1338   /// \param C AST context.
   1339   /// \param StartLoc Starting location of the directive kind.
   1340   /// \param EndLoc Ending Location of the directive.
   1341   /// \param CollapsedNum Number of collapsed loops.
   1342   /// \param Clauses List of clauses.
   1343   /// \param AssociatedStmt Statement, associated with the directive.
   1344   /// \param Exprs Helper expressions for CodeGen.
   1345   /// \param HasCancel true if current directive has inner cancel directive.
   1346   ///
   1347   static OMPParallelForDirective *
   1348   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1349          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   1350          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
   1351 
   1352   /// \brief Creates an empty directive with the place
   1353   /// for \a NumClauses clauses.
   1354   ///
   1355   /// \param C AST context.
   1356   /// \param CollapsedNum Number of collapsed nested loops.
   1357   /// \param NumClauses Number of clauses.
   1358   ///
   1359   static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
   1360                                               unsigned NumClauses,
   1361                                               unsigned CollapsedNum,
   1362                                               EmptyShell);
   1363 
   1364   /// \brief Return true if current directive has inner cancel directive.
   1365   bool hasCancel() const { return HasCancel; }
   1366 
   1367   static bool classof(const Stmt *T) {
   1368     return T->getStmtClass() == OMPParallelForDirectiveClass;
   1369   }
   1370 };
   1371 
   1372 /// \brief This represents '#pragma omp parallel for simd' directive.
   1373 ///
   1374 /// \code
   1375 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
   1376 /// \endcode
   1377 /// In this example directive '#pragma omp parallel for simd' has clauses
   1378 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
   1379 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and
   1380 /// 'd'.
   1381 ///
   1382 class OMPParallelForSimdDirective : public OMPLoopDirective {
   1383   friend class ASTStmtReader;
   1384   /// \brief Build directive with the given start and end location.
   1385   ///
   1386   /// \param StartLoc Starting location of the directive kind.
   1387   /// \param EndLoc Ending location of the directive.
   1388   /// \param CollapsedNum Number of collapsed nested loops.
   1389   /// \param NumClauses Number of clauses.
   1390   ///
   1391   OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1392                               unsigned CollapsedNum, unsigned NumClauses)
   1393       : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
   1394                          OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum,
   1395                          NumClauses) {}
   1396 
   1397   /// \brief Build an empty directive.
   1398   ///
   1399   /// \param CollapsedNum Number of collapsed nested loops.
   1400   /// \param NumClauses Number of clauses.
   1401   ///
   1402   explicit OMPParallelForSimdDirective(unsigned CollapsedNum,
   1403                                        unsigned NumClauses)
   1404       : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
   1405                          OMPD_parallel_for_simd, SourceLocation(),
   1406                          SourceLocation(), CollapsedNum, NumClauses) {}
   1407 
   1408 public:
   1409   /// \brief Creates directive with a list of \a Clauses.
   1410   ///
   1411   /// \param C AST context.
   1412   /// \param StartLoc Starting location of the directive kind.
   1413   /// \param EndLoc Ending Location of the directive.
   1414   /// \param CollapsedNum Number of collapsed loops.
   1415   /// \param Clauses List of clauses.
   1416   /// \param AssociatedStmt Statement, associated with the directive.
   1417   /// \param Exprs Helper expressions for CodeGen.
   1418   ///
   1419   static OMPParallelForSimdDirective *
   1420   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1421          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   1422          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   1423 
   1424   /// \brief Creates an empty directive with the place
   1425   /// for \a NumClauses clauses.
   1426   ///
   1427   /// \param C AST context.
   1428   /// \param CollapsedNum Number of collapsed nested loops.
   1429   /// \param NumClauses Number of clauses.
   1430   ///
   1431   static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
   1432                                                   unsigned NumClauses,
   1433                                                   unsigned CollapsedNum,
   1434                                                   EmptyShell);
   1435 
   1436   static bool classof(const Stmt *T) {
   1437     return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
   1438   }
   1439 };
   1440 
   1441 /// \brief This represents '#pragma omp parallel sections' directive.
   1442 ///
   1443 /// \code
   1444 /// #pragma omp parallel sections private(a,b) reduction(+:c,d)
   1445 /// \endcode
   1446 /// In this example directive '#pragma omp parallel sections' has clauses
   1447 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
   1448 /// and variables 'c' and 'd'.
   1449 ///
   1450 class OMPParallelSectionsDirective : public OMPExecutableDirective {
   1451   friend class ASTStmtReader;
   1452 
   1453   /// \brief true if current directive has inner cancel directive.
   1454   bool HasCancel;
   1455 
   1456   /// \brief Build directive with the given start and end location.
   1457   ///
   1458   /// \param StartLoc Starting location of the directive kind.
   1459   /// \param EndLoc Ending location of the directive.
   1460   /// \param NumClauses Number of clauses.
   1461   ///
   1462   OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1463                                unsigned NumClauses)
   1464       : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
   1465                                OMPD_parallel_sections, StartLoc, EndLoc,
   1466                                NumClauses, 1),
   1467         HasCancel(false) {}
   1468 
   1469   /// \brief Build an empty directive.
   1470   ///
   1471   /// \param NumClauses Number of clauses.
   1472   ///
   1473   explicit OMPParallelSectionsDirective(unsigned NumClauses)
   1474       : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
   1475                                OMPD_parallel_sections, SourceLocation(),
   1476                                SourceLocation(), NumClauses, 1),
   1477         HasCancel(false) {}
   1478 
   1479   /// \brief Set cancel state.
   1480   void setHasCancel(bool Has) { HasCancel = Has; }
   1481 
   1482 public:
   1483   /// \brief Creates directive with a list of \a Clauses.
   1484   ///
   1485   /// \param C AST context.
   1486   /// \param StartLoc Starting location of the directive kind.
   1487   /// \param EndLoc Ending Location of the directive.
   1488   /// \param Clauses List of clauses.
   1489   /// \param AssociatedStmt Statement, associated with the directive.
   1490   /// \param HasCancel true if current directive has inner cancel directive.
   1491   ///
   1492   static OMPParallelSectionsDirective *
   1493   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1494          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
   1495 
   1496   /// \brief Creates an empty directive with the place for \a NumClauses
   1497   /// clauses.
   1498   ///
   1499   /// \param C AST context.
   1500   /// \param NumClauses Number of clauses.
   1501   ///
   1502   static OMPParallelSectionsDirective *
   1503   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
   1504 
   1505   /// \brief Return true if current directive has inner cancel directive.
   1506   bool hasCancel() const { return HasCancel; }
   1507 
   1508   static bool classof(const Stmt *T) {
   1509     return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
   1510   }
   1511 };
   1512 
   1513 /// \brief This represents '#pragma omp task' directive.
   1514 ///
   1515 /// \code
   1516 /// #pragma omp task private(a,b) final(d)
   1517 /// \endcode
   1518 /// In this example directive '#pragma omp task' has clauses 'private' with the
   1519 /// variables 'a' and 'b' and 'final' with condition 'd'.
   1520 ///
   1521 class OMPTaskDirective : public OMPExecutableDirective {
   1522   friend class ASTStmtReader;
   1523   /// \brief true if this directive has inner cancel directive.
   1524   bool HasCancel;
   1525 
   1526   /// \brief Build directive with the given start and end location.
   1527   ///
   1528   /// \param StartLoc Starting location of the directive kind.
   1529   /// \param EndLoc Ending location of the directive.
   1530   /// \param NumClauses Number of clauses.
   1531   ///
   1532   OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1533                    unsigned NumClauses)
   1534       : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
   1535                                EndLoc, NumClauses, 1),
   1536         HasCancel(false) {}
   1537 
   1538   /// \brief Build an empty directive.
   1539   ///
   1540   /// \param NumClauses Number of clauses.
   1541   ///
   1542   explicit OMPTaskDirective(unsigned NumClauses)
   1543       : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
   1544                                SourceLocation(), SourceLocation(), NumClauses,
   1545                                1),
   1546         HasCancel(false) {}
   1547 
   1548   /// \brief Set cancel state.
   1549   void setHasCancel(bool Has) { HasCancel = Has; }
   1550 
   1551 public:
   1552   /// \brief Creates directive with a list of \a Clauses.
   1553   ///
   1554   /// \param C AST context.
   1555   /// \param StartLoc Starting location of the directive kind.
   1556   /// \param EndLoc Ending Location of the directive.
   1557   /// \param Clauses List of clauses.
   1558   /// \param AssociatedStmt Statement, associated with the directive.
   1559   /// \param HasCancel true, if current directive has inner cancel directive.
   1560   ///
   1561   static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
   1562                                   SourceLocation EndLoc,
   1563                                   ArrayRef<OMPClause *> Clauses,
   1564                                   Stmt *AssociatedStmt, bool HasCancel);
   1565 
   1566   /// \brief Creates an empty directive with the place for \a NumClauses
   1567   /// clauses.
   1568   ///
   1569   /// \param C AST context.
   1570   /// \param NumClauses Number of clauses.
   1571   ///
   1572   static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
   1573                                        EmptyShell);
   1574 
   1575   /// \brief Return true if current directive has inner cancel directive.
   1576   bool hasCancel() const { return HasCancel; }
   1577 
   1578   static bool classof(const Stmt *T) {
   1579     return T->getStmtClass() == OMPTaskDirectiveClass;
   1580   }
   1581 };
   1582 
   1583 /// \brief This represents '#pragma omp taskyield' directive.
   1584 ///
   1585 /// \code
   1586 /// #pragma omp taskyield
   1587 /// \endcode
   1588 ///
   1589 class OMPTaskyieldDirective : public OMPExecutableDirective {
   1590   friend class ASTStmtReader;
   1591   /// \brief Build directive with the given start and end location.
   1592   ///
   1593   /// \param StartLoc Starting location of the directive kind.
   1594   /// \param EndLoc Ending location of the directive.
   1595   ///
   1596   OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1597       : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
   1598                                StartLoc, EndLoc, 0, 0) {}
   1599 
   1600   /// \brief Build an empty directive.
   1601   ///
   1602   explicit OMPTaskyieldDirective()
   1603       : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
   1604                                SourceLocation(), SourceLocation(), 0, 0) {}
   1605 
   1606 public:
   1607   /// \brief Creates directive.
   1608   ///
   1609   /// \param C AST context.
   1610   /// \param StartLoc Starting location of the directive kind.
   1611   /// \param EndLoc Ending Location of the directive.
   1612   ///
   1613   static OMPTaskyieldDirective *
   1614   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
   1615 
   1616   /// \brief Creates an empty directive.
   1617   ///
   1618   /// \param C AST context.
   1619   ///
   1620   static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1621 
   1622   static bool classof(const Stmt *T) {
   1623     return T->getStmtClass() == OMPTaskyieldDirectiveClass;
   1624   }
   1625 };
   1626 
   1627 /// \brief This represents '#pragma omp barrier' directive.
   1628 ///
   1629 /// \code
   1630 /// #pragma omp barrier
   1631 /// \endcode
   1632 ///
   1633 class OMPBarrierDirective : public OMPExecutableDirective {
   1634   friend class ASTStmtReader;
   1635   /// \brief Build directive with the given start and end location.
   1636   ///
   1637   /// \param StartLoc Starting location of the directive kind.
   1638   /// \param EndLoc Ending location of the directive.
   1639   ///
   1640   OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1641       : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
   1642                                StartLoc, EndLoc, 0, 0) {}
   1643 
   1644   /// \brief Build an empty directive.
   1645   ///
   1646   explicit OMPBarrierDirective()
   1647       : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
   1648                                SourceLocation(), SourceLocation(), 0, 0) {}
   1649 
   1650 public:
   1651   /// \brief Creates directive.
   1652   ///
   1653   /// \param C AST context.
   1654   /// \param StartLoc Starting location of the directive kind.
   1655   /// \param EndLoc Ending Location of the directive.
   1656   ///
   1657   static OMPBarrierDirective *
   1658   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
   1659 
   1660   /// \brief Creates an empty directive.
   1661   ///
   1662   /// \param C AST context.
   1663   ///
   1664   static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1665 
   1666   static bool classof(const Stmt *T) {
   1667     return T->getStmtClass() == OMPBarrierDirectiveClass;
   1668   }
   1669 };
   1670 
   1671 /// \brief This represents '#pragma omp taskwait' directive.
   1672 ///
   1673 /// \code
   1674 /// #pragma omp taskwait
   1675 /// \endcode
   1676 ///
   1677 class OMPTaskwaitDirective : public OMPExecutableDirective {
   1678   friend class ASTStmtReader;
   1679   /// \brief Build directive with the given start and end location.
   1680   ///
   1681   /// \param StartLoc Starting location of the directive kind.
   1682   /// \param EndLoc Ending location of the directive.
   1683   ///
   1684   OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1685       : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
   1686                                StartLoc, EndLoc, 0, 0) {}
   1687 
   1688   /// \brief Build an empty directive.
   1689   ///
   1690   explicit OMPTaskwaitDirective()
   1691       : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
   1692                                SourceLocation(), SourceLocation(), 0, 0) {}
   1693 
   1694 public:
   1695   /// \brief Creates directive.
   1696   ///
   1697   /// \param C AST context.
   1698   /// \param StartLoc Starting location of the directive kind.
   1699   /// \param EndLoc Ending Location of the directive.
   1700   ///
   1701   static OMPTaskwaitDirective *
   1702   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
   1703 
   1704   /// \brief Creates an empty directive.
   1705   ///
   1706   /// \param C AST context.
   1707   ///
   1708   static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1709 
   1710   static bool classof(const Stmt *T) {
   1711     return T->getStmtClass() == OMPTaskwaitDirectiveClass;
   1712   }
   1713 };
   1714 
   1715 /// \brief This represents '#pragma omp taskgroup' directive.
   1716 ///
   1717 /// \code
   1718 /// #pragma omp taskgroup
   1719 /// \endcode
   1720 ///
   1721 class OMPTaskgroupDirective : public OMPExecutableDirective {
   1722   friend class ASTStmtReader;
   1723   /// \brief Build directive with the given start and end location.
   1724   ///
   1725   /// \param StartLoc Starting location of the directive kind.
   1726   /// \param EndLoc Ending location of the directive.
   1727   ///
   1728   OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1729       : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
   1730                                StartLoc, EndLoc, 0, 1) {}
   1731 
   1732   /// \brief Build an empty directive.
   1733   ///
   1734   explicit OMPTaskgroupDirective()
   1735       : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
   1736                                SourceLocation(), SourceLocation(), 0, 1) {}
   1737 
   1738 public:
   1739   /// \brief Creates directive.
   1740   ///
   1741   /// \param C AST context.
   1742   /// \param StartLoc Starting location of the directive kind.
   1743   /// \param EndLoc Ending Location of the directive.
   1744   /// \param AssociatedStmt Statement, associated with the directive.
   1745   ///
   1746   static OMPTaskgroupDirective *Create(const ASTContext &C,
   1747                                        SourceLocation StartLoc,
   1748                                        SourceLocation EndLoc,
   1749                                        Stmt *AssociatedStmt);
   1750 
   1751   /// \brief Creates an empty directive.
   1752   ///
   1753   /// \param C AST context.
   1754   ///
   1755   static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1756 
   1757   static bool classof(const Stmt *T) {
   1758     return T->getStmtClass() == OMPTaskgroupDirectiveClass;
   1759   }
   1760 };
   1761 
   1762 /// \brief This represents '#pragma omp flush' directive.
   1763 ///
   1764 /// \code
   1765 /// #pragma omp flush(a,b)
   1766 /// \endcode
   1767 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
   1768 /// and 'b'.
   1769 /// 'omp flush' directive does not have clauses but have an optional list of
   1770 /// variables to flush. This list of variables is stored within some fake clause
   1771 /// FlushClause.
   1772 class OMPFlushDirective : public OMPExecutableDirective {
   1773   friend class ASTStmtReader;
   1774   /// \brief Build directive with the given start and end location.
   1775   ///
   1776   /// \param StartLoc Starting location of the directive kind.
   1777   /// \param EndLoc Ending location of the directive.
   1778   /// \param NumClauses Number of clauses.
   1779   ///
   1780   OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1781                     unsigned NumClauses)
   1782       : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
   1783                                StartLoc, EndLoc, NumClauses, 0) {}
   1784 
   1785   /// \brief Build an empty directive.
   1786   ///
   1787   /// \param NumClauses Number of clauses.
   1788   ///
   1789   explicit OMPFlushDirective(unsigned NumClauses)
   1790       : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
   1791                                SourceLocation(), SourceLocation(), NumClauses,
   1792                                0) {}
   1793 
   1794 public:
   1795   /// \brief Creates directive with a list of \a Clauses.
   1796   ///
   1797   /// \param C AST context.
   1798   /// \param StartLoc Starting location of the directive kind.
   1799   /// \param EndLoc Ending Location of the directive.
   1800   /// \param Clauses List of clauses (only single OMPFlushClause clause is
   1801   /// allowed).
   1802   ///
   1803   static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
   1804                                    SourceLocation EndLoc,
   1805                                    ArrayRef<OMPClause *> Clauses);
   1806 
   1807   /// \brief Creates an empty directive with the place for \a NumClauses
   1808   /// clauses.
   1809   ///
   1810   /// \param C AST context.
   1811   /// \param NumClauses Number of clauses.
   1812   ///
   1813   static OMPFlushDirective *CreateEmpty(const ASTContext &C,
   1814                                         unsigned NumClauses, EmptyShell);
   1815 
   1816   static bool classof(const Stmt *T) {
   1817     return T->getStmtClass() == OMPFlushDirectiveClass;
   1818   }
   1819 };
   1820 
   1821 /// \brief This represents '#pragma omp ordered' directive.
   1822 ///
   1823 /// \code
   1824 /// #pragma omp ordered
   1825 /// \endcode
   1826 ///
   1827 class OMPOrderedDirective : public OMPExecutableDirective {
   1828   friend class ASTStmtReader;
   1829   /// \brief Build directive with the given start and end location.
   1830   ///
   1831   /// \param StartLoc Starting location of the directive kind.
   1832   /// \param EndLoc Ending location of the directive.
   1833   /// \param NumClauses Number of clauses.
   1834   ///
   1835   OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1836                       unsigned NumClauses)
   1837       : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
   1838                                StartLoc, EndLoc, NumClauses, 1) {}
   1839 
   1840   /// \brief Build an empty directive.
   1841   ///
   1842   /// \param NumClauses Number of clauses.
   1843   ///
   1844   explicit OMPOrderedDirective(unsigned NumClauses)
   1845       : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
   1846                                SourceLocation(), SourceLocation(), NumClauses,
   1847                                1) {}
   1848 
   1849 public:
   1850   /// \brief Creates directive.
   1851   ///
   1852   /// \param C AST context.
   1853   /// \param StartLoc Starting location of the directive kind.
   1854   /// \param EndLoc Ending Location of the directive.
   1855   /// \param Clauses List of clauses.
   1856   /// \param AssociatedStmt Statement, associated with the directive.
   1857   ///
   1858   static OMPOrderedDirective *
   1859   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1860          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   1861 
   1862   /// \brief Creates an empty directive.
   1863   ///
   1864   /// \param C AST context.
   1865   /// \param NumClauses Number of clauses.
   1866   ///
   1867   static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
   1868                                           unsigned NumClauses, EmptyShell);
   1869 
   1870   static bool classof(const Stmt *T) {
   1871     return T->getStmtClass() == OMPOrderedDirectiveClass;
   1872   }
   1873 };
   1874 
   1875 /// \brief This represents '#pragma omp atomic' directive.
   1876 ///
   1877 /// \code
   1878 /// #pragma omp atomic capture
   1879 /// \endcode
   1880 /// In this example directive '#pragma omp atomic' has clause 'capture'.
   1881 ///
   1882 class OMPAtomicDirective : public OMPExecutableDirective {
   1883   friend class ASTStmtReader;
   1884   /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
   1885   /// have atomic expressions of forms
   1886   /// \code
   1887   /// x = x binop expr;
   1888   /// x = expr binop x;
   1889   /// \endcode
   1890   /// This field is true for the first form of the expression and false for the
   1891   /// second. Required for correct codegen of non-associative operations (like
   1892   /// << or >>).
   1893   bool IsXLHSInRHSPart;
   1894   /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
   1895   /// have atomic expressions of forms
   1896   /// \code
   1897   /// v = x; <update x>;
   1898   /// <update x>; v = x;
   1899   /// \endcode
   1900   /// This field is true for the first(postfix) form of the expression and false
   1901   /// otherwise.
   1902   bool IsPostfixUpdate;
   1903 
   1904   /// \brief Build directive with the given start and end location.
   1905   ///
   1906   /// \param StartLoc Starting location of the directive kind.
   1907   /// \param EndLoc Ending location of the directive.
   1908   /// \param NumClauses Number of clauses.
   1909   ///
   1910   OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1911                      unsigned NumClauses)
   1912       : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
   1913                                StartLoc, EndLoc, NumClauses, 5),
   1914         IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
   1915 
   1916   /// \brief Build an empty directive.
   1917   ///
   1918   /// \param NumClauses Number of clauses.
   1919   ///
   1920   explicit OMPAtomicDirective(unsigned NumClauses)
   1921       : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
   1922                                SourceLocation(), SourceLocation(), NumClauses,
   1923                                5),
   1924         IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
   1925 
   1926   /// \brief Set 'x' part of the associated expression/statement.
   1927   void setX(Expr *X) { *std::next(child_begin()) = X; }
   1928   /// \brief Set helper expression of the form
   1929   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
   1930   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
   1931   void setUpdateExpr(Expr *UE) { *std::next(child_begin(), 2) = UE; }
   1932   /// \brief Set 'v' part of the associated expression/statement.
   1933   void setV(Expr *V) { *std::next(child_begin(), 3) = V; }
   1934   /// \brief Set 'expr' part of the associated expression/statement.
   1935   void setExpr(Expr *E) { *std::next(child_begin(), 4) = E; }
   1936 
   1937 public:
   1938   /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
   1939   /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
   1940   /// detailed description of 'x', 'v' and 'expr').
   1941   ///
   1942   /// \param C AST context.
   1943   /// \param StartLoc Starting location of the directive kind.
   1944   /// \param EndLoc Ending Location of the directive.
   1945   /// \param Clauses List of clauses.
   1946   /// \param AssociatedStmt Statement, associated with the directive.
   1947   /// \param X 'x' part of the associated expression/statement.
   1948   /// \param V 'v' part of the associated expression/statement.
   1949   /// \param E 'expr' part of the associated expression/statement.
   1950   /// \param UE Helper expression of the form
   1951   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
   1952   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
   1953   /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the
   1954   /// second.
   1955   /// \param IsPostfixUpdate true if original value of 'x' must be stored in
   1956   /// 'v', not an updated one.
   1957   static OMPAtomicDirective *
   1958   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1959          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
   1960          Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate);
   1961 
   1962   /// \brief Creates an empty directive with the place for \a NumClauses
   1963   /// clauses.
   1964   ///
   1965   /// \param C AST context.
   1966   /// \param NumClauses Number of clauses.
   1967   ///
   1968   static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
   1969                                          unsigned NumClauses, EmptyShell);
   1970 
   1971   /// \brief Get 'x' part of the associated expression/statement.
   1972   Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); }
   1973   const Expr *getX() const {
   1974     return cast_or_null<Expr>(*std::next(child_begin()));
   1975   }
   1976   /// \brief Get helper expression of the form
   1977   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
   1978   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
   1979   Expr *getUpdateExpr() {
   1980     return cast_or_null<Expr>(*std::next(child_begin(), 2));
   1981   }
   1982   const Expr *getUpdateExpr() const {
   1983     return cast_or_null<Expr>(*std::next(child_begin(), 2));
   1984   }
   1985   /// \brief Return true if helper update expression has form
   1986   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
   1987   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
   1988   bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
   1989   /// \brief Return true if 'v' expression must be updated to original value of
   1990   /// 'x', false if 'v' must be updated to the new value of 'x'.
   1991   bool isPostfixUpdate() const { return IsPostfixUpdate; }
   1992   /// \brief Get 'v' part of the associated expression/statement.
   1993   Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); }
   1994   const Expr *getV() const {
   1995     return cast_or_null<Expr>(*std::next(child_begin(), 3));
   1996   }
   1997   /// \brief Get 'expr' part of the associated expression/statement.
   1998   Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 4)); }
   1999   const Expr *getExpr() const {
   2000     return cast_or_null<Expr>(*std::next(child_begin(), 4));
   2001   }
   2002 
   2003   static bool classof(const Stmt *T) {
   2004     return T->getStmtClass() == OMPAtomicDirectiveClass;
   2005   }
   2006 };
   2007 
   2008 /// \brief This represents '#pragma omp target' directive.
   2009 ///
   2010 /// \code
   2011 /// #pragma omp target if(a)
   2012 /// \endcode
   2013 /// In this example directive '#pragma omp target' has clause 'if' with
   2014 /// condition 'a'.
   2015 ///
   2016 class OMPTargetDirective : public OMPExecutableDirective {
   2017   friend class ASTStmtReader;
   2018   /// \brief Build directive with the given start and end location.
   2019   ///
   2020   /// \param StartLoc Starting location of the directive kind.
   2021   /// \param EndLoc Ending location of the directive.
   2022   /// \param NumClauses Number of clauses.
   2023   ///
   2024   OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2025                      unsigned NumClauses)
   2026       : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
   2027                                StartLoc, EndLoc, NumClauses, 1) {}
   2028 
   2029   /// \brief Build an empty directive.
   2030   ///
   2031   /// \param NumClauses Number of clauses.
   2032   ///
   2033   explicit OMPTargetDirective(unsigned NumClauses)
   2034       : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
   2035                                SourceLocation(), SourceLocation(), NumClauses,
   2036                                1) {}
   2037 
   2038 public:
   2039   /// \brief Creates directive with a list of \a Clauses.
   2040   ///
   2041   /// \param C AST context.
   2042   /// \param StartLoc Starting location of the directive kind.
   2043   /// \param EndLoc Ending Location of the directive.
   2044   /// \param Clauses List of clauses.
   2045   /// \param AssociatedStmt Statement, associated with the directive.
   2046   ///
   2047   static OMPTargetDirective *
   2048   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2049          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   2050 
   2051   /// \brief Creates an empty directive with the place for \a NumClauses
   2052   /// clauses.
   2053   ///
   2054   /// \param C AST context.
   2055   /// \param NumClauses Number of clauses.
   2056   ///
   2057   static OMPTargetDirective *CreateEmpty(const ASTContext &C,
   2058                                          unsigned NumClauses, EmptyShell);
   2059 
   2060   static bool classof(const Stmt *T) {
   2061     return T->getStmtClass() == OMPTargetDirectiveClass;
   2062   }
   2063 };
   2064 
   2065 /// \brief This represents '#pragma omp target data' directive.
   2066 ///
   2067 /// \code
   2068 /// #pragma omp target data device(0) if(a) map(b[:])
   2069 /// \endcode
   2070 /// In this example directive '#pragma omp target data' has clauses 'device'
   2071 /// with the value '0', 'if' with condition 'a' and 'map' with array
   2072 /// section 'b[:]'.
   2073 ///
   2074 class OMPTargetDataDirective : public OMPExecutableDirective {
   2075   friend class ASTStmtReader;
   2076   /// \brief Build directive with the given start and end location.
   2077   ///
   2078   /// \param StartLoc Starting location of the directive kind.
   2079   /// \param EndLoc Ending Location of the directive.
   2080   /// \param NumClauses The number of clauses.
   2081   ///
   2082   OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2083                          unsigned NumClauses)
   2084       : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
   2085                                OMPD_target_data, StartLoc, EndLoc, NumClauses,
   2086                                1) {}
   2087 
   2088   /// \brief Build an empty directive.
   2089   ///
   2090   /// \param NumClauses Number of clauses.
   2091   ///
   2092   explicit OMPTargetDataDirective(unsigned NumClauses)
   2093       : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
   2094                                OMPD_target_data, SourceLocation(),
   2095                                SourceLocation(), NumClauses, 1) {}
   2096 
   2097 public:
   2098   /// \brief Creates directive with a list of \a Clauses.
   2099   ///
   2100   /// \param C AST context.
   2101   /// \param StartLoc Starting location of the directive kind.
   2102   /// \param EndLoc Ending Location of the directive.
   2103   /// \param Clauses List of clauses.
   2104   /// \param AssociatedStmt Statement, associated with the directive.
   2105   ///
   2106   static OMPTargetDataDirective *
   2107   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2108          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   2109 
   2110   /// \brief Creates an empty directive with the place for \a N clauses.
   2111   ///
   2112   /// \param C AST context.
   2113   /// \param N The number of clauses.
   2114   ///
   2115   static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
   2116                                              EmptyShell);
   2117 
   2118   static bool classof(const Stmt *T) {
   2119     return T->getStmtClass() == OMPTargetDataDirectiveClass;
   2120   }
   2121 };
   2122 
   2123 /// \brief This represents '#pragma omp target enter data' directive.
   2124 ///
   2125 /// \code
   2126 /// #pragma omp target enter data device(0) if(a) map(b[:])
   2127 /// \endcode
   2128 /// In this example directive '#pragma omp target enter data' has clauses
   2129 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
   2130 /// section 'b[:]'.
   2131 ///
   2132 class OMPTargetEnterDataDirective : public OMPExecutableDirective {
   2133   friend class ASTStmtReader;
   2134   /// \brief Build directive with the given start and end location.
   2135   ///
   2136   /// \param StartLoc Starting location of the directive kind.
   2137   /// \param EndLoc Ending Location of the directive.
   2138   /// \param NumClauses The number of clauses.
   2139   ///
   2140   OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2141                               unsigned NumClauses)
   2142       : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
   2143                                OMPD_target_enter_data, StartLoc, EndLoc,
   2144                                NumClauses, /*NumChildren=*/0) {}
   2145 
   2146   /// \brief Build an empty directive.
   2147   ///
   2148   /// \param NumClauses Number of clauses.
   2149   ///
   2150   explicit OMPTargetEnterDataDirective(unsigned NumClauses)
   2151       : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
   2152                                OMPD_target_enter_data, SourceLocation(),
   2153                                SourceLocation(), NumClauses,
   2154                                /*NumChildren=*/0) {}
   2155 
   2156 public:
   2157   /// \brief Creates directive with a list of \a Clauses.
   2158   ///
   2159   /// \param C AST context.
   2160   /// \param StartLoc Starting location of the directive kind.
   2161   /// \param EndLoc Ending Location of the directive.
   2162   /// \param Clauses List of clauses.
   2163   ///
   2164   static OMPTargetEnterDataDirective *Create(const ASTContext &C,
   2165                                              SourceLocation StartLoc,
   2166                                              SourceLocation EndLoc,
   2167                                              ArrayRef<OMPClause *> Clauses);
   2168 
   2169   /// \brief Creates an empty directive with the place for \a N clauses.
   2170   ///
   2171   /// \param C AST context.
   2172   /// \param N The number of clauses.
   2173   ///
   2174   static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C,
   2175                                                   unsigned N, EmptyShell);
   2176 
   2177   static bool classof(const Stmt *T) {
   2178     return T->getStmtClass() == OMPTargetEnterDataDirectiveClass;
   2179   }
   2180 };
   2181 
   2182 /// \brief This represents '#pragma omp target exit data' directive.
   2183 ///
   2184 /// \code
   2185 /// #pragma omp target exit data device(0) if(a) map(b[:])
   2186 /// \endcode
   2187 /// In this example directive '#pragma omp target exit data' has clauses
   2188 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
   2189 /// section 'b[:]'.
   2190 ///
   2191 class OMPTargetExitDataDirective : public OMPExecutableDirective {
   2192   friend class ASTStmtReader;
   2193   /// \brief Build directive with the given start and end location.
   2194   ///
   2195   /// \param StartLoc Starting location of the directive kind.
   2196   /// \param EndLoc Ending Location of the directive.
   2197   /// \param NumClauses The number of clauses.
   2198   ///
   2199   OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2200                              unsigned NumClauses)
   2201       : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
   2202                                OMPD_target_exit_data, StartLoc, EndLoc,
   2203                                NumClauses, /*NumChildren=*/0) {}
   2204 
   2205   /// \brief Build an empty directive.
   2206   ///
   2207   /// \param NumClauses Number of clauses.
   2208   ///
   2209   explicit OMPTargetExitDataDirective(unsigned NumClauses)
   2210       : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
   2211                                OMPD_target_exit_data, SourceLocation(),
   2212                                SourceLocation(), NumClauses,
   2213                                /*NumChildren=*/0) {}
   2214 
   2215 public:
   2216   /// \brief Creates directive with a list of \a Clauses.
   2217   ///
   2218   /// \param C AST context.
   2219   /// \param StartLoc Starting location of the directive kind.
   2220   /// \param EndLoc Ending Location of the directive.
   2221   /// \param Clauses List of clauses.
   2222   ///
   2223   static OMPTargetExitDataDirective *Create(const ASTContext &C,
   2224                                             SourceLocation StartLoc,
   2225                                             SourceLocation EndLoc,
   2226                                             ArrayRef<OMPClause *> Clauses);
   2227 
   2228   /// \brief Creates an empty directive with the place for \a N clauses.
   2229   ///
   2230   /// \param C AST context.
   2231   /// \param N The number of clauses.
   2232   ///
   2233   static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
   2234                                                  unsigned N, EmptyShell);
   2235 
   2236   static bool classof(const Stmt *T) {
   2237     return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
   2238   }
   2239 };
   2240 
   2241 /// \brief This represents '#pragma omp target parallel' directive.
   2242 ///
   2243 /// \code
   2244 /// #pragma omp target parallel if(a)
   2245 /// \endcode
   2246 /// In this example directive '#pragma omp target parallel' has clause 'if' with
   2247 /// condition 'a'.
   2248 ///
   2249 class OMPTargetParallelDirective : public OMPExecutableDirective {
   2250   friend class ASTStmtReader;
   2251   /// \brief Build directive with the given start and end location.
   2252   ///
   2253   /// \param StartLoc Starting location of the directive kind.
   2254   /// \param EndLoc Ending location of the directive.
   2255   /// \param NumClauses Number of clauses.
   2256   ///
   2257   OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2258                              unsigned NumClauses)
   2259       : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass,
   2260                                OMPD_target_parallel, StartLoc, EndLoc,
   2261                                NumClauses, /*NumChildren=*/1) {}
   2262 
   2263   /// \brief Build an empty directive.
   2264   ///
   2265   /// \param NumClauses Number of clauses.
   2266   ///
   2267   explicit OMPTargetParallelDirective(unsigned NumClauses)
   2268       : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass,
   2269                                OMPD_target_parallel, SourceLocation(),
   2270                                SourceLocation(), NumClauses,
   2271                                /*NumChildren=*/1) {}
   2272 
   2273 public:
   2274   /// \brief Creates directive with a list of \a Clauses.
   2275   ///
   2276   /// \param C AST context.
   2277   /// \param StartLoc Starting location of the directive kind.
   2278   /// \param EndLoc Ending Location of the directive.
   2279   /// \param Clauses List of clauses.
   2280   /// \param AssociatedStmt Statement, associated with the directive.
   2281   ///
   2282   static OMPTargetParallelDirective *
   2283   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2284          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   2285 
   2286   /// \brief Creates an empty directive with the place for \a NumClauses
   2287   /// clauses.
   2288   ///
   2289   /// \param C AST context.
   2290   /// \param NumClauses Number of clauses.
   2291   ///
   2292   static OMPTargetParallelDirective *
   2293   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
   2294 
   2295   static bool classof(const Stmt *T) {
   2296     return T->getStmtClass() == OMPTargetParallelDirectiveClass;
   2297   }
   2298 };
   2299 
   2300 /// \brief This represents '#pragma omp target parallel for' directive.
   2301 ///
   2302 /// \code
   2303 /// #pragma omp target parallel for private(a,b) reduction(+:c,d)
   2304 /// \endcode
   2305 /// In this example directive '#pragma omp target parallel for' has clauses
   2306 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
   2307 /// and variables 'c' and 'd'.
   2308 ///
   2309 class OMPTargetParallelForDirective : public OMPLoopDirective {
   2310   friend class ASTStmtReader;
   2311 
   2312   /// \brief true if current region has inner cancel directive.
   2313   bool HasCancel;
   2314 
   2315   /// \brief Build directive with the given start and end location.
   2316   ///
   2317   /// \param StartLoc Starting location of the directive kind.
   2318   /// \param EndLoc Ending location of the directive.
   2319   /// \param CollapsedNum Number of collapsed nested loops.
   2320   /// \param NumClauses Number of clauses.
   2321   ///
   2322   OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2323                                 unsigned CollapsedNum, unsigned NumClauses)
   2324       : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass,
   2325                          OMPD_target_parallel_for, StartLoc, EndLoc,
   2326                          CollapsedNum, NumClauses),
   2327         HasCancel(false) {}
   2328 
   2329   /// \brief Build an empty directive.
   2330   ///
   2331   /// \param CollapsedNum Number of collapsed nested loops.
   2332   /// \param NumClauses Number of clauses.
   2333   ///
   2334   explicit OMPTargetParallelForDirective(unsigned CollapsedNum,
   2335                                          unsigned NumClauses)
   2336       : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass,
   2337                          OMPD_target_parallel_for, SourceLocation(),
   2338                          SourceLocation(), CollapsedNum, NumClauses),
   2339         HasCancel(false) {}
   2340 
   2341   /// \brief Set cancel state.
   2342   void setHasCancel(bool Has) { HasCancel = Has; }
   2343 
   2344 public:
   2345   /// \brief Creates directive with a list of \a Clauses.
   2346   ///
   2347   /// \param C AST context.
   2348   /// \param StartLoc Starting location of the directive kind.
   2349   /// \param EndLoc Ending Location of the directive.
   2350   /// \param CollapsedNum Number of collapsed loops.
   2351   /// \param Clauses List of clauses.
   2352   /// \param AssociatedStmt Statement, associated with the directive.
   2353   /// \param Exprs Helper expressions for CodeGen.
   2354   /// \param HasCancel true if current directive has inner cancel directive.
   2355   ///
   2356   static OMPTargetParallelForDirective *
   2357   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2358          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   2359          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
   2360 
   2361   /// \brief Creates an empty directive with the place
   2362   /// for \a NumClauses clauses.
   2363   ///
   2364   /// \param C AST context.
   2365   /// \param CollapsedNum Number of collapsed nested loops.
   2366   /// \param NumClauses Number of clauses.
   2367   ///
   2368   static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C,
   2369                                                     unsigned NumClauses,
   2370                                                     unsigned CollapsedNum,
   2371                                                     EmptyShell);
   2372 
   2373   /// \brief Return true if current directive has inner cancel directive.
   2374   bool hasCancel() const { return HasCancel; }
   2375 
   2376   static bool classof(const Stmt *T) {
   2377     return T->getStmtClass() == OMPTargetParallelForDirectiveClass;
   2378   }
   2379 };
   2380 
   2381 /// \brief This represents '#pragma omp teams' directive.
   2382 ///
   2383 /// \code
   2384 /// #pragma omp teams if(a)
   2385 /// \endcode
   2386 /// In this example directive '#pragma omp teams' has clause 'if' with
   2387 /// condition 'a'.
   2388 ///
   2389 class OMPTeamsDirective : public OMPExecutableDirective {
   2390   friend class ASTStmtReader;
   2391   /// \brief Build directive with the given start and end location.
   2392   ///
   2393   /// \param StartLoc Starting location of the directive kind.
   2394   /// \param EndLoc Ending location of the directive.
   2395   /// \param NumClauses Number of clauses.
   2396   ///
   2397   OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2398                     unsigned NumClauses)
   2399       : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
   2400                                StartLoc, EndLoc, NumClauses, 1) {}
   2401 
   2402   /// \brief Build an empty directive.
   2403   ///
   2404   /// \param NumClauses Number of clauses.
   2405   ///
   2406   explicit OMPTeamsDirective(unsigned NumClauses)
   2407       : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
   2408                                SourceLocation(), SourceLocation(), NumClauses,
   2409                                1) {}
   2410 
   2411 public:
   2412   /// \brief Creates directive with a list of \a Clauses.
   2413   ///
   2414   /// \param C AST context.
   2415   /// \param StartLoc Starting location of the directive kind.
   2416   /// \param EndLoc Ending Location of the directive.
   2417   /// \param Clauses List of clauses.
   2418   /// \param AssociatedStmt Statement, associated with the directive.
   2419   ///
   2420   static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
   2421                                    SourceLocation EndLoc,
   2422                                    ArrayRef<OMPClause *> Clauses,
   2423                                    Stmt *AssociatedStmt);
   2424 
   2425   /// \brief Creates an empty directive with the place for \a NumClauses
   2426   /// clauses.
   2427   ///
   2428   /// \param C AST context.
   2429   /// \param NumClauses Number of clauses.
   2430   ///
   2431   static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
   2432                                         unsigned NumClauses, EmptyShell);
   2433 
   2434   static bool classof(const Stmt *T) {
   2435     return T->getStmtClass() == OMPTeamsDirectiveClass;
   2436   }
   2437 };
   2438 
   2439 /// \brief This represents '#pragma omp cancellation point' directive.
   2440 ///
   2441 /// \code
   2442 /// #pragma omp cancellation point for
   2443 /// \endcode
   2444 ///
   2445 /// In this example a cancellation point is created for innermost 'for' region.
   2446 class OMPCancellationPointDirective : public OMPExecutableDirective {
   2447   friend class ASTStmtReader;
   2448   OpenMPDirectiveKind CancelRegion;
   2449   /// \brief Build directive with the given start and end location.
   2450   ///
   2451   /// \param StartLoc Starting location of the directive kind.
   2452   /// \param EndLoc Ending location of the directive.
   2453   ///
   2454   OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   2455       : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
   2456                                OMPD_cancellation_point, StartLoc, EndLoc, 0, 0),
   2457         CancelRegion(OMPD_unknown) {}
   2458 
   2459   /// \brief Build an empty directive.
   2460   ///
   2461   explicit OMPCancellationPointDirective()
   2462       : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
   2463                                OMPD_cancellation_point, SourceLocation(),
   2464                                SourceLocation(), 0, 0),
   2465         CancelRegion(OMPD_unknown) {}
   2466 
   2467   /// \brief Set cancel region for current cancellation point.
   2468   /// \param CR Cancellation region.
   2469   void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
   2470 
   2471 public:
   2472   /// \brief Creates directive.
   2473   ///
   2474   /// \param C AST context.
   2475   /// \param StartLoc Starting location of the directive kind.
   2476   /// \param EndLoc Ending Location of the directive.
   2477   ///
   2478   static OMPCancellationPointDirective *
   2479   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2480          OpenMPDirectiveKind CancelRegion);
   2481 
   2482   /// \brief Creates an empty directive.
   2483   ///
   2484   /// \param C AST context.
   2485   ///
   2486   static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
   2487                                                     EmptyShell);
   2488 
   2489   /// \brief Get cancellation region for the current cancellation point.
   2490   OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
   2491 
   2492   static bool classof(const Stmt *T) {
   2493     return T->getStmtClass() == OMPCancellationPointDirectiveClass;
   2494   }
   2495 };
   2496 
   2497 /// \brief This represents '#pragma omp cancel' directive.
   2498 ///
   2499 /// \code
   2500 /// #pragma omp cancel for
   2501 /// \endcode
   2502 ///
   2503 /// In this example a cancel is created for innermost 'for' region.
   2504 class OMPCancelDirective : public OMPExecutableDirective {
   2505   friend class ASTStmtReader;
   2506   OpenMPDirectiveKind CancelRegion;
   2507   /// \brief Build directive with the given start and end location.
   2508   ///
   2509   /// \param StartLoc Starting location of the directive kind.
   2510   /// \param EndLoc Ending location of the directive.
   2511   /// \param NumClauses Number of clauses.
   2512   ///
   2513   OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2514                      unsigned NumClauses)
   2515       : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
   2516                                StartLoc, EndLoc, NumClauses, 0),
   2517         CancelRegion(OMPD_unknown) {}
   2518 
   2519   /// \brief Build an empty directive.
   2520   ///
   2521   /// \param NumClauses Number of clauses.
   2522   explicit OMPCancelDirective(unsigned NumClauses)
   2523       : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
   2524                                SourceLocation(), SourceLocation(), NumClauses,
   2525                                0),
   2526         CancelRegion(OMPD_unknown) {}
   2527 
   2528   /// \brief Set cancel region for current cancellation point.
   2529   /// \param CR Cancellation region.
   2530   void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
   2531 
   2532 public:
   2533   /// \brief Creates directive.
   2534   ///
   2535   /// \param C AST context.
   2536   /// \param StartLoc Starting location of the directive kind.
   2537   /// \param EndLoc Ending Location of the directive.
   2538   /// \param Clauses List of clauses.
   2539   ///
   2540   static OMPCancelDirective *
   2541   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2542          ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
   2543 
   2544   /// \brief Creates an empty directive.
   2545   ///
   2546   /// \param C AST context.
   2547   /// \param NumClauses Number of clauses.
   2548   ///
   2549   static OMPCancelDirective *CreateEmpty(const ASTContext &C,
   2550                                          unsigned NumClauses, EmptyShell);
   2551 
   2552   /// \brief Get cancellation region for the current cancellation point.
   2553   OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
   2554 
   2555   static bool classof(const Stmt *T) {
   2556     return T->getStmtClass() == OMPCancelDirectiveClass;
   2557   }
   2558 };
   2559 
   2560 /// \brief This represents '#pragma omp taskloop' directive.
   2561 ///
   2562 /// \code
   2563 /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
   2564 /// \endcode
   2565 /// In this example directive '#pragma omp taskloop' has clauses 'private'
   2566 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
   2567 /// 'num_tasks' with expression 'num'.
   2568 ///
   2569 class OMPTaskLoopDirective : public OMPLoopDirective {
   2570   friend class ASTStmtReader;
   2571   /// \brief Build directive with the given start and end location.
   2572   ///
   2573   /// \param StartLoc Starting location of the directive kind.
   2574   /// \param EndLoc Ending location of the directive.
   2575   /// \param CollapsedNum Number of collapsed nested loops.
   2576   /// \param NumClauses Number of clauses.
   2577   ///
   2578   OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2579                        unsigned CollapsedNum, unsigned NumClauses)
   2580       : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
   2581                          StartLoc, EndLoc, CollapsedNum, NumClauses) {}
   2582 
   2583   /// \brief Build an empty directive.
   2584   ///
   2585   /// \param CollapsedNum Number of collapsed nested loops.
   2586   /// \param NumClauses Number of clauses.
   2587   ///
   2588   explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses)
   2589       : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
   2590                          SourceLocation(), SourceLocation(), CollapsedNum,
   2591                          NumClauses) {}
   2592 
   2593 public:
   2594   /// \brief Creates directive with a list of \a Clauses.
   2595   ///
   2596   /// \param C AST context.
   2597   /// \param StartLoc Starting location of the directive kind.
   2598   /// \param EndLoc Ending Location of the directive.
   2599   /// \param CollapsedNum Number of collapsed loops.
   2600   /// \param Clauses List of clauses.
   2601   /// \param AssociatedStmt Statement, associated with the directive.
   2602   /// \param Exprs Helper expressions for CodeGen.
   2603   ///
   2604   static OMPTaskLoopDirective *
   2605   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2606          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   2607          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   2608 
   2609   /// \brief Creates an empty directive with the place
   2610   /// for \a NumClauses clauses.
   2611   ///
   2612   /// \param C AST context.
   2613   /// \param CollapsedNum Number of collapsed nested loops.
   2614   /// \param NumClauses Number of clauses.
   2615   ///
   2616   static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
   2617                                            unsigned NumClauses,
   2618                                            unsigned CollapsedNum, EmptyShell);
   2619 
   2620   static bool classof(const Stmt *T) {
   2621     return T->getStmtClass() == OMPTaskLoopDirectiveClass;
   2622   }
   2623 };
   2624 
   2625 /// \brief This represents '#pragma omp taskloop simd' directive.
   2626 ///
   2627 /// \code
   2628 /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
   2629 /// \endcode
   2630 /// In this example directive '#pragma omp taskloop simd' has clauses 'private'
   2631 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
   2632 /// 'num_tasks' with expression 'num'.
   2633 ///
   2634 class OMPTaskLoopSimdDirective : public OMPLoopDirective {
   2635   friend class ASTStmtReader;
   2636   /// \brief Build directive with the given start and end location.
   2637   ///
   2638   /// \param StartLoc Starting location of the directive kind.
   2639   /// \param EndLoc Ending location of the directive.
   2640   /// \param CollapsedNum Number of collapsed nested loops.
   2641   /// \param NumClauses Number of clauses.
   2642   ///
   2643   OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2644                            unsigned CollapsedNum, unsigned NumClauses)
   2645       : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
   2646                          OMPD_taskloop_simd, StartLoc, EndLoc, CollapsedNum,
   2647                          NumClauses) {}
   2648 
   2649   /// \brief Build an empty directive.
   2650   ///
   2651   /// \param CollapsedNum Number of collapsed nested loops.
   2652   /// \param NumClauses Number of clauses.
   2653   ///
   2654   explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
   2655       : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
   2656                          OMPD_taskloop_simd, SourceLocation(), SourceLocation(),
   2657                          CollapsedNum, NumClauses) {}
   2658 
   2659 public:
   2660   /// \brief Creates directive with a list of \a Clauses.
   2661   ///
   2662   /// \param C AST context.
   2663   /// \param StartLoc Starting location of the directive kind.
   2664   /// \param EndLoc Ending Location of the directive.
   2665   /// \param CollapsedNum Number of collapsed loops.
   2666   /// \param Clauses List of clauses.
   2667   /// \param AssociatedStmt Statement, associated with the directive.
   2668   /// \param Exprs Helper expressions for CodeGen.
   2669   ///
   2670   static OMPTaskLoopSimdDirective *
   2671   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2672          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   2673          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   2674 
   2675   /// \brief Creates an empty directive with the place
   2676   /// for \a NumClauses clauses.
   2677   ///
   2678   /// \param C AST context.
   2679   /// \param CollapsedNum Number of collapsed nested loops.
   2680   /// \param NumClauses Number of clauses.
   2681   ///
   2682   static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
   2683                                                unsigned NumClauses,
   2684                                                unsigned CollapsedNum,
   2685                                                EmptyShell);
   2686 
   2687   static bool classof(const Stmt *T) {
   2688     return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
   2689   }
   2690 };
   2691 
   2692 /// \brief This represents '#pragma omp distribute' directive.
   2693 ///
   2694 /// \code
   2695 /// #pragma omp distribute private(a,b)
   2696 /// \endcode
   2697 /// In this example directive '#pragma omp distribute' has clauses 'private'
   2698 /// with the variables 'a' and 'b'
   2699 ///
   2700 class OMPDistributeDirective : public OMPLoopDirective {
   2701   friend class ASTStmtReader;
   2702 
   2703   /// \brief Build directive with the given start and end location.
   2704   ///
   2705   /// \param StartLoc Starting location of the directive kind.
   2706   /// \param EndLoc Ending location of the directive.
   2707   /// \param CollapsedNum Number of collapsed nested loops.
   2708   /// \param NumClauses Number of clauses.
   2709   ///
   2710   OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2711                          unsigned CollapsedNum, unsigned NumClauses)
   2712       : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
   2713                          StartLoc, EndLoc, CollapsedNum, NumClauses)
   2714         {}
   2715 
   2716   /// \brief Build an empty directive.
   2717   ///
   2718   /// \param CollapsedNum Number of collapsed nested loops.
   2719   /// \param NumClauses Number of clauses.
   2720   ///
   2721   explicit OMPDistributeDirective(unsigned CollapsedNum, unsigned NumClauses)
   2722       : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
   2723                          SourceLocation(), SourceLocation(), CollapsedNum,
   2724                          NumClauses)
   2725         {}
   2726 
   2727 public:
   2728   /// \brief Creates directive with a list of \a Clauses.
   2729   ///
   2730   /// \param C AST context.
   2731   /// \param StartLoc Starting location of the directive kind.
   2732   /// \param EndLoc Ending Location of the directive.
   2733   /// \param CollapsedNum Number of collapsed loops.
   2734   /// \param Clauses List of clauses.
   2735   /// \param AssociatedStmt Statement, associated with the directive.
   2736   /// \param Exprs Helper expressions for CodeGen.
   2737   ///
   2738   static OMPDistributeDirective *
   2739   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2740          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   2741          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   2742 
   2743   /// \brief Creates an empty directive with the place
   2744   /// for \a NumClauses clauses.
   2745   ///
   2746   /// \param C AST context.
   2747   /// \param CollapsedNum Number of collapsed nested loops.
   2748   /// \param NumClauses Number of clauses.
   2749   ///
   2750   static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
   2751                                              unsigned NumClauses,
   2752                                              unsigned CollapsedNum, EmptyShell);
   2753 
   2754   static bool classof(const Stmt *T) {
   2755     return T->getStmtClass() == OMPDistributeDirectiveClass;
   2756   }
   2757 };
   2758 
   2759 /// \brief This represents '#pragma omp target update' directive.
   2760 ///
   2761 /// \code
   2762 /// #pragma omp target update to(a) from(b) device(1)
   2763 /// \endcode
   2764 /// In this example directive '#pragma omp target update' has clause 'to' with
   2765 /// argument 'a', clause 'from' with argument 'b' and clause 'device' with
   2766 /// argument '1'.
   2767 ///
   2768 class OMPTargetUpdateDirective : public OMPExecutableDirective {
   2769   friend class ASTStmtReader;
   2770   /// \brief Build directive with the given start and end location.
   2771   ///
   2772   /// \param StartLoc Starting location of the directive kind.
   2773   /// \param EndLoc Ending Location of the directive.
   2774   /// \param NumClauses The number of clauses.
   2775   ///
   2776   OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2777                            unsigned NumClauses)
   2778       : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
   2779                                OMPD_target_update, StartLoc, EndLoc, NumClauses,
   2780                                0) {}
   2781 
   2782   /// \brief Build an empty directive.
   2783   ///
   2784   /// \param NumClauses Number of clauses.
   2785   ///
   2786   explicit OMPTargetUpdateDirective(unsigned NumClauses)
   2787       : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
   2788                                OMPD_target_update, SourceLocation(),
   2789                                SourceLocation(), NumClauses, 0) {}
   2790 
   2791 public:
   2792   /// \brief Creates directive with a list of \a Clauses.
   2793   ///
   2794   /// \param C AST context.
   2795   /// \param StartLoc Starting location of the directive kind.
   2796   /// \param EndLoc Ending Location of the directive.
   2797   /// \param Clauses List of clauses.
   2798   ///
   2799   static OMPTargetUpdateDirective *Create(const ASTContext &C,
   2800                                           SourceLocation StartLoc,
   2801                                           SourceLocation EndLoc,
   2802                                           ArrayRef<OMPClause *> Clauses);
   2803 
   2804   /// \brief Creates an empty directive with the place for \a NumClauses
   2805   /// clauses.
   2806   ///
   2807   /// \param C AST context.
   2808   /// \param NumClauses The number of clauses.
   2809   ///
   2810   static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C,
   2811                                                unsigned NumClauses, EmptyShell);
   2812 
   2813   static bool classof(const Stmt *T) {
   2814     return T->getStmtClass() == OMPTargetUpdateDirectiveClass;
   2815   }
   2816 };
   2817 
   2818 /// \brief This represents '#pragma omp distribute parallel for' composite
   2819 ///  directive.
   2820 ///
   2821 /// \code
   2822 /// #pragma omp distribute parallel for private(a,b)
   2823 /// \endcode
   2824 /// In this example directive '#pragma omp distribute parallel for' has clause
   2825 /// 'private' with the variables 'a' and 'b'
   2826 ///
   2827 class OMPDistributeParallelForDirective : public OMPLoopDirective {
   2828   friend class ASTStmtReader;
   2829 
   2830   /// \brief Build directive with the given start and end location.
   2831   ///
   2832   /// \param StartLoc Starting location of the directive kind.
   2833   /// \param EndLoc Ending location of the directive.
   2834   /// \param CollapsedNum Number of collapsed nested loops.
   2835   /// \param NumClauses Number of clauses.
   2836   ///
   2837   OMPDistributeParallelForDirective(SourceLocation StartLoc,
   2838                                     SourceLocation EndLoc,
   2839                                     unsigned CollapsedNum, unsigned NumClauses)
   2840       : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass,
   2841                          OMPD_distribute_parallel_for, StartLoc, EndLoc,
   2842                          CollapsedNum, NumClauses) {}
   2843 
   2844   /// \brief Build an empty directive.
   2845   ///
   2846   /// \param CollapsedNum Number of collapsed nested loops.
   2847   /// \param NumClauses Number of clauses.
   2848   ///
   2849   explicit OMPDistributeParallelForDirective(unsigned CollapsedNum,
   2850                                              unsigned NumClauses)
   2851       : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass,
   2852                          OMPD_distribute_parallel_for, SourceLocation(),
   2853                          SourceLocation(), CollapsedNum, NumClauses) {}
   2854 
   2855 public:
   2856   /// \brief Creates directive with a list of \a Clauses.
   2857   ///
   2858   /// \param C AST context.
   2859   /// \param StartLoc Starting location of the directive kind.
   2860   /// \param EndLoc Ending Location of the directive.
   2861   /// \param CollapsedNum Number of collapsed loops.
   2862   /// \param Clauses List of clauses.
   2863   /// \param AssociatedStmt Statement, associated with the directive.
   2864   /// \param Exprs Helper expressions for CodeGen.
   2865   ///
   2866   static OMPDistributeParallelForDirective *
   2867   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2868          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   2869          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   2870 
   2871   /// \brief Creates an empty directive with the place
   2872   /// for \a NumClauses clauses.
   2873   ///
   2874   /// \param C AST context.
   2875   /// \param CollapsedNum Number of collapsed nested loops.
   2876   /// \param NumClauses Number of clauses.
   2877   ///
   2878   static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C,
   2879                                                         unsigned NumClauses,
   2880                                                         unsigned CollapsedNum,
   2881                                                         EmptyShell);
   2882 
   2883   static bool classof(const Stmt *T) {
   2884     return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
   2885   }
   2886 };
   2887 
   2888 /// This represents '#pragma omp distribute parallel for simd' composite
   2889 /// directive.
   2890 ///
   2891 /// \code
   2892 /// #pragma omp distribute parallel for simd private(x)
   2893 /// \endcode
   2894 /// In this example directive '#pragma omp distribute parallel for simd' has
   2895 /// clause 'private' with the variables 'x'
   2896 ///
   2897 class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective {
   2898   friend class ASTStmtReader;
   2899 
   2900   /// Build directive with the given start and end location.
   2901   ///
   2902   /// \param StartLoc Starting location of the directive kind.
   2903   /// \param EndLoc Ending location of the directive.
   2904   /// \param CollapsedNum Number of collapsed nested loops.
   2905   /// \param NumClauses Number of clauses.
   2906   ///
   2907   OMPDistributeParallelForSimdDirective(SourceLocation StartLoc,
   2908                                         SourceLocation EndLoc,
   2909                                         unsigned CollapsedNum,
   2910                                         unsigned NumClauses)
   2911       : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass,
   2912                          OMPD_distribute_parallel_for_simd, StartLoc,
   2913                          EndLoc, CollapsedNum, NumClauses) {}
   2914 
   2915   /// Build an empty directive.
   2916   ///
   2917   /// \param CollapsedNum Number of collapsed nested loops.
   2918   /// \param NumClauses Number of clauses.
   2919   ///
   2920   explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum,
   2921                                                  unsigned NumClauses)
   2922       : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass,
   2923                          OMPD_distribute_parallel_for_simd,
   2924                          SourceLocation(), SourceLocation(), CollapsedNum,
   2925                          NumClauses) {}
   2926 
   2927 public:
   2928   /// Creates directive with a list of \a Clauses.
   2929   ///
   2930   /// \param C AST context.
   2931   /// \param StartLoc Starting location of the directive kind.
   2932   /// \param EndLoc Ending Location of the directive.
   2933   /// \param CollapsedNum Number of collapsed loops.
   2934   /// \param Clauses List of clauses.
   2935   /// \param AssociatedStmt Statement, associated with the directive.
   2936   /// \param Exprs Helper expressions for CodeGen.
   2937   ///
   2938   static OMPDistributeParallelForSimdDirective *Create(
   2939       const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2940       unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   2941       Stmt *AssociatedStmt, const HelperExprs &Exprs);
   2942 
   2943   /// Creates an empty directive with the place for \a NumClauses clauses.
   2944   ///
   2945   /// \param C AST context.
   2946   /// \param CollapsedNum Number of collapsed nested loops.
   2947   /// \param NumClauses Number of clauses.
   2948   ///
   2949   static OMPDistributeParallelForSimdDirective *CreateEmpty(
   2950       const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
   2951       EmptyShell);
   2952 
   2953   static bool classof(const Stmt *T) {
   2954     return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass;
   2955   }
   2956 };
   2957 
   2958 /// This represents '#pragma omp distribute simd' composite directive.
   2959 ///
   2960 /// \code
   2961 /// #pragma omp distribute simd private(x)
   2962 /// \endcode
   2963 /// In this example directive '#pragma omp distribute simd' has clause
   2964 /// 'private' with the variables 'x'
   2965 ///
   2966 class OMPDistributeSimdDirective final : public OMPLoopDirective {
   2967   friend class ASTStmtReader;
   2968 
   2969   /// Build directive with the given start and end location.
   2970   ///
   2971   /// \param StartLoc Starting location of the directive kind.
   2972   /// \param EndLoc Ending location of the directive.
   2973   /// \param CollapsedNum Number of collapsed nested loops.
   2974   /// \param NumClauses Number of clauses.
   2975   ///
   2976   OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2977                              unsigned CollapsedNum, unsigned NumClauses)
   2978       : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass,
   2979                          OMPD_distribute_simd, StartLoc, EndLoc, CollapsedNum,
   2980                          NumClauses) {}
   2981 
   2982   /// Build an empty directive.
   2983   ///
   2984   /// \param CollapsedNum Number of collapsed nested loops.
   2985   /// \param NumClauses Number of clauses.
   2986   ///
   2987   explicit OMPDistributeSimdDirective(unsigned CollapsedNum,
   2988                                       unsigned NumClauses)
   2989       : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass,
   2990                          OMPD_distribute_simd, SourceLocation(),
   2991                          SourceLocation(), CollapsedNum, NumClauses) {}
   2992 
   2993 public:
   2994   /// Creates directive with a list of \a Clauses.
   2995   ///
   2996   /// \param C AST context.
   2997   /// \param StartLoc Starting location of the directive kind.
   2998   /// \param EndLoc Ending Location of the directive.
   2999   /// \param CollapsedNum Number of collapsed loops.
   3000   /// \param Clauses List of clauses.
   3001   /// \param AssociatedStmt Statement, associated with the directive.
   3002   /// \param Exprs Helper expressions for CodeGen.
   3003   ///
   3004   static OMPDistributeSimdDirective *
   3005   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3006          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3007          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3008 
   3009   /// Creates an empty directive with the place for \a NumClauses clauses.
   3010   ///
   3011   /// \param C AST context.
   3012   /// \param CollapsedNum Number of collapsed nested loops.
   3013   /// \param NumClauses Number of clauses.
   3014   ///
   3015   static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C,
   3016                                                  unsigned NumClauses,
   3017                                                  unsigned CollapsedNum,
   3018                                                  EmptyShell);
   3019 
   3020   static bool classof(const Stmt *T) {
   3021     return T->getStmtClass() == OMPDistributeSimdDirectiveClass;
   3022   }
   3023 };
   3024 
   3025 /// This represents '#pragma omp target parallel for simd' directive.
   3026 ///
   3027 /// \code
   3028 /// #pragma omp target parallel for simd private(a) map(b) safelen(c)
   3029 /// \endcode
   3030 /// In this example directive '#pragma omp target parallel for simd' has clauses
   3031 /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen'
   3032 /// with the variable 'c'.
   3033 ///
   3034 class OMPTargetParallelForSimdDirective final : public OMPLoopDirective {
   3035   friend class ASTStmtReader;
   3036 
   3037   /// Build directive with the given start and end location.
   3038   ///
   3039   /// \param StartLoc Starting location of the directive kind.
   3040   /// \param EndLoc Ending location of the directive.
   3041   /// \param CollapsedNum Number of collapsed nested loops.
   3042   /// \param NumClauses Number of clauses.
   3043   ///
   3044   OMPTargetParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   3045                                 unsigned CollapsedNum, unsigned NumClauses)
   3046       : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass,
   3047                          OMPD_target_parallel_for_simd, StartLoc, EndLoc,
   3048                          CollapsedNum, NumClauses) {}
   3049 
   3050   /// Build an empty directive.
   3051   ///
   3052   /// \param CollapsedNum Number of collapsed nested loops.
   3053   /// \param NumClauses Number of clauses.
   3054   ///
   3055   explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum,
   3056                                              unsigned NumClauses)
   3057       : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass,
   3058                          OMPD_target_parallel_for_simd, SourceLocation(),
   3059                          SourceLocation(), CollapsedNum, NumClauses) {}
   3060 
   3061 public:
   3062   /// Creates directive with a list of \a Clauses.
   3063   ///
   3064   /// \param C AST context.
   3065   /// \param StartLoc Starting location of the directive kind.
   3066   /// \param EndLoc Ending Location of the directive.
   3067   /// \param CollapsedNum Number of collapsed loops.
   3068   /// \param Clauses List of clauses.
   3069   /// \param AssociatedStmt Statement, associated with the directive.
   3070   /// \param Exprs Helper expressions for CodeGen.
   3071   ///
   3072   static OMPTargetParallelForSimdDirective *
   3073   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3074          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3075          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3076 
   3077   /// Creates an empty directive with the place for \a NumClauses clauses.
   3078   ///
   3079   /// \param C AST context.
   3080   /// \param CollapsedNum Number of collapsed nested loops.
   3081   /// \param NumClauses Number of clauses.
   3082   ///
   3083   static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C,
   3084                                                         unsigned NumClauses,
   3085                                                         unsigned CollapsedNum,
   3086                                                         EmptyShell);
   3087 
   3088   static bool classof(const Stmt *T) {
   3089     return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
   3090   }
   3091 };
   3092 
   3093 } // end namespace clang
   3094 
   3095 #endif
   3096