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::RoundUpToAlignment(sizeof(T),
     74                                                llvm::alignOf<OMPClause *>())) {}
     75 
     76   /// \brief Sets the list of variables for this clause.
     77   ///
     78   /// \param Clauses The list of clauses for the directive.
     79   ///
     80   void setClauses(ArrayRef<OMPClause *> Clauses);
     81 
     82   /// \brief Set the associated statement for the directive.
     83   ///
     84   /// /param S Associated statement.
     85   ///
     86   void setAssociatedStmt(Stmt *S) {
     87     assert(hasAssociatedStmt() && "no associated statement.");
     88     *child_begin() = S;
     89   }
     90 
     91 public:
     92   /// \brief Iterates over a filtered subrange of clauses applied to a
     93   /// directive.
     94   ///
     95   /// This iterator visits only clauses of type SpecificClause.
     96   template <typename SpecificClause>
     97   class specific_clause_iterator
     98       : public llvm::iterator_adaptor_base<
     99             specific_clause_iterator<SpecificClause>,
    100             ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag,
    101             const SpecificClause *, ptrdiff_t, const SpecificClause *,
    102             const SpecificClause *> {
    103     ArrayRef<OMPClause *>::const_iterator End;
    104 
    105     void SkipToNextClause() {
    106       while (this->I != End && !isa<SpecificClause>(*this->I))
    107         ++this->I;
    108     }
    109 
    110   public:
    111     explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses)
    112         : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()),
    113           End(Clauses.end()) {
    114       SkipToNextClause();
    115     }
    116 
    117     const SpecificClause *operator*() const {
    118       return cast<SpecificClause>(*this->I);
    119     }
    120     const SpecificClause *operator->() const { return **this; }
    121 
    122     specific_clause_iterator &operator++() {
    123       ++this->I;
    124       SkipToNextClause();
    125       return *this;
    126     }
    127   };
    128 
    129   template <typename SpecificClause>
    130   static llvm::iterator_range<specific_clause_iterator<SpecificClause>>
    131   getClausesOfKind(ArrayRef<OMPClause *> Clauses) {
    132     return {specific_clause_iterator<SpecificClause>(Clauses),
    133             specific_clause_iterator<SpecificClause>(
    134                 llvm::makeArrayRef(Clauses.end(), 0))};
    135   }
    136 
    137   template <typename SpecificClause>
    138   llvm::iterator_range<specific_clause_iterator<SpecificClause>>
    139   getClausesOfKind() const {
    140     return getClausesOfKind<SpecificClause>(clauses());
    141   }
    142 
    143   /// Gets a single clause of the specified kind associated with the
    144   /// current directive iff there is only one clause of this kind (and assertion
    145   /// is fired if there is more than one clause is associated with the
    146   /// directive). Returns nullptr if no clause of this kind is associated with
    147   /// the directive.
    148   template <typename SpecificClause>
    149   const SpecificClause *getSingleClause() const {
    150     auto Clauses = getClausesOfKind<SpecificClause>();
    151 
    152     if (Clauses.begin() != Clauses.end()) {
    153       assert(std::next(Clauses.begin()) == Clauses.end() &&
    154              "There are at least 2 clauses of the specified kind");
    155       return *Clauses.begin();
    156     }
    157     return nullptr;
    158   }
    159 
    160   /// Returns true if the current directive has one or more clauses of a
    161   /// specific kind.
    162   template <typename SpecificClause>
    163   bool hasClausesOfKind() const {
    164     auto Clauses = getClausesOfKind<SpecificClause>();
    165     return Clauses.begin() != Clauses.end();
    166   }
    167 
    168   /// \brief Returns starting location of directive kind.
    169   SourceLocation getLocStart() const { return StartLoc; }
    170   /// \brief Returns ending location of directive.
    171   SourceLocation getLocEnd() const { return EndLoc; }
    172 
    173   /// \brief Set starting location of directive kind.
    174   ///
    175   /// \param Loc New starting location of directive.
    176   ///
    177   void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
    178   /// \brief Set ending location of directive.
    179   ///
    180   /// \param Loc New ending location of directive.
    181   ///
    182   void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
    183 
    184   /// \brief Get number of clauses.
    185   unsigned getNumClauses() const { return NumClauses; }
    186 
    187   /// \brief Returns specified clause.
    188   ///
    189   /// \param i Number of clause.
    190   ///
    191   OMPClause *getClause(unsigned i) const { return clauses()[i]; }
    192 
    193   /// \brief Returns true if directive has associated statement.
    194   bool hasAssociatedStmt() const { return NumChildren > 0; }
    195 
    196   /// \brief Returns statement associated with the directive.
    197   Stmt *getAssociatedStmt() const {
    198     assert(hasAssociatedStmt() && "no associated statement.");
    199     return const_cast<Stmt *>(*child_begin());
    200   }
    201 
    202   OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
    203 
    204   static bool classof(const Stmt *S) {
    205     return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
    206            S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
    207   }
    208 
    209   child_range children() {
    210     if (!hasAssociatedStmt())
    211       return child_range(child_iterator(), child_iterator());
    212     Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
    213     return child_range(ChildStorage, ChildStorage + NumChildren);
    214   }
    215 
    216   ArrayRef<OMPClause *> clauses() { return getClauses(); }
    217 
    218   ArrayRef<OMPClause *> clauses() const {
    219     return const_cast<OMPExecutableDirective *>(this)->getClauses();
    220   }
    221 };
    222 
    223 /// \brief This represents '#pragma omp parallel' directive.
    224 ///
    225 /// \code
    226 /// #pragma omp parallel private(a,b) reduction(+: c,d)
    227 /// \endcode
    228 /// In this example directive '#pragma omp parallel' has clauses 'private'
    229 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
    230 /// variables 'c' and 'd'.
    231 ///
    232 class OMPParallelDirective : public OMPExecutableDirective {
    233   friend class ASTStmtReader;
    234   /// \brief true if the construct has inner cancel directive.
    235   bool HasCancel;
    236 
    237   /// \brief Build directive with the given start and end location.
    238   ///
    239   /// \param StartLoc Starting location of the directive (directive keyword).
    240   /// \param EndLoc Ending Location of the directive.
    241   ///
    242   OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    243                        unsigned NumClauses)
    244       : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
    245                                StartLoc, EndLoc, NumClauses, 1),
    246         HasCancel(false) {}
    247 
    248   /// \brief Build an empty directive.
    249   ///
    250   /// \param NumClauses Number of clauses.
    251   ///
    252   explicit OMPParallelDirective(unsigned NumClauses)
    253       : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
    254                                SourceLocation(), SourceLocation(), NumClauses,
    255                                1),
    256         HasCancel(false) {}
    257 
    258   /// \brief Set cancel state.
    259   void setHasCancel(bool Has) { HasCancel = Has; }
    260 
    261 public:
    262   /// \brief Creates directive with a list of \a Clauses.
    263   ///
    264   /// \param C AST context.
    265   /// \param StartLoc Starting location of the directive kind.
    266   /// \param EndLoc Ending Location of the directive.
    267   /// \param Clauses List of clauses.
    268   /// \param AssociatedStmt Statement associated with the directive.
    269   /// \param HasCancel true if this directive has inner cancel directive.
    270   ///
    271   static OMPParallelDirective *
    272   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
    273          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
    274 
    275   /// \brief Creates an empty directive with the place for \a N clauses.
    276   ///
    277   /// \param C AST context.
    278   /// \param NumClauses Number of clauses.
    279   ///
    280   static OMPParallelDirective *CreateEmpty(const ASTContext &C,
    281                                            unsigned NumClauses, EmptyShell);
    282 
    283   /// \brief Return true if current directive has inner cancel directive.
    284   bool hasCancel() const { return HasCancel; }
    285 
    286   static bool classof(const Stmt *T) {
    287     return T->getStmtClass() == OMPParallelDirectiveClass;
    288   }
    289 };
    290 
    291 /// \brief This is a common base class for loop directives ('omp simd', 'omp
    292 /// for', 'omp for simd' etc.). It is responsible for the loop code generation.
    293 ///
    294 class OMPLoopDirective : public OMPExecutableDirective {
    295   friend class ASTStmtReader;
    296   /// \brief Number of collapsed loops as specified by 'collapse' clause.
    297   unsigned CollapsedNum;
    298 
    299   /// \brief Offsets to the stored exprs.
    300   /// This enumeration contains offsets to all the pointers to children
    301   /// expressions stored in OMPLoopDirective.
    302   /// The first 9 children are nesessary for all the loop directives, and
    303   /// the next 7 are specific to the worksharing ones.
    304   /// After the fixed children, three arrays of length CollapsedNum are
    305   /// allocated: loop counters, their updates and final values.
    306   ///
    307   enum {
    308     AssociatedStmtOffset = 0,
    309     IterationVariableOffset = 1,
    310     LastIterationOffset = 2,
    311     CalcLastIterationOffset = 3,
    312     PreConditionOffset = 4,
    313     CondOffset = 5,
    314     InitOffset = 6,
    315     IncOffset = 7,
    316     // The '...End' enumerators do not correspond to child expressions - they
    317     // specify the offset to the end (and start of the following counters/
    318     // updates/finals arrays).
    319     DefaultEnd = 8,
    320     // The following 7 exprs are used by worksharing loops only.
    321     IsLastIterVariableOffset = 8,
    322     LowerBoundVariableOffset = 9,
    323     UpperBoundVariableOffset = 10,
    324     StrideVariableOffset = 11,
    325     EnsureUpperBoundOffset = 12,
    326     NextLowerBoundOffset = 13,
    327     NextUpperBoundOffset = 14,
    328     // Offset to the end (and start of the following counters/updates/finals
    329     // arrays) for worksharing loop directives.
    330     WorksharingEnd = 15,
    331   };
    332 
    333   /// \brief Get the counters storage.
    334   MutableArrayRef<Expr *> getCounters() {
    335     Expr **Storage = reinterpret_cast<Expr **>(
    336         &(*(std::next(child_begin(), getArraysOffset(getDirectiveKind())))));
    337     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
    338   }
    339 
    340   /// \brief Get the private counters storage.
    341   MutableArrayRef<Expr *> getPrivateCounters() {
    342     Expr **Storage = reinterpret_cast<Expr **>(&*std::next(
    343         child_begin(), getArraysOffset(getDirectiveKind()) + CollapsedNum));
    344     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
    345   }
    346 
    347   /// \brief Get the updates storage.
    348   MutableArrayRef<Expr *> getInits() {
    349     Expr **Storage = reinterpret_cast<Expr **>(
    350         &*std::next(child_begin(),
    351                     getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum));
    352     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
    353   }
    354 
    355   /// \brief Get the updates storage.
    356   MutableArrayRef<Expr *> getUpdates() {
    357     Expr **Storage = reinterpret_cast<Expr **>(
    358         &*std::next(child_begin(),
    359                     getArraysOffset(getDirectiveKind()) + 3 * CollapsedNum));
    360     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
    361   }
    362 
    363   /// \brief Get the final counter updates storage.
    364   MutableArrayRef<Expr *> getFinals() {
    365     Expr **Storage = reinterpret_cast<Expr **>(
    366         &*std::next(child_begin(),
    367                     getArraysOffset(getDirectiveKind()) + 4 * CollapsedNum));
    368     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
    369   }
    370 
    371 protected:
    372   /// \brief Build instance of loop directive of class \a Kind.
    373   ///
    374   /// \param SC Statement class.
    375   /// \param Kind Kind of OpenMP directive.
    376   /// \param StartLoc Starting location of the directive (directive keyword).
    377   /// \param EndLoc Ending location of the directive.
    378   /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
    379   /// \param NumClauses Number of clauses.
    380   /// \param NumSpecialChildren Number of additional directive-specific stmts.
    381   ///
    382   template <typename T>
    383   OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind,
    384                    SourceLocation StartLoc, SourceLocation EndLoc,
    385                    unsigned CollapsedNum, unsigned NumClauses,
    386                    unsigned NumSpecialChildren = 0)
    387       : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses,
    388                                numLoopChildren(CollapsedNum, Kind) +
    389                                    NumSpecialChildren),
    390         CollapsedNum(CollapsedNum) {}
    391 
    392   /// \brief Offset to the start of children expression arrays.
    393   static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
    394     return (isOpenMPWorksharingDirective(Kind) ||
    395             isOpenMPTaskLoopDirective(Kind) ||
    396             isOpenMPDistributeDirective(Kind))
    397                ? WorksharingEnd
    398                : DefaultEnd;
    399   }
    400 
    401   /// \brief Children number.
    402   static unsigned numLoopChildren(unsigned CollapsedNum,
    403                                   OpenMPDirectiveKind Kind) {
    404     return getArraysOffset(Kind) + 5 * CollapsedNum; // Counters,
    405                                                      // PrivateCounters, Inits,
    406                                                      // Updates and Finals
    407   }
    408 
    409   void setIterationVariable(Expr *IV) {
    410     *std::next(child_begin(), IterationVariableOffset) = IV;
    411   }
    412   void setLastIteration(Expr *LI) {
    413     *std::next(child_begin(), LastIterationOffset) = LI;
    414   }
    415   void setCalcLastIteration(Expr *CLI) {
    416     *std::next(child_begin(), CalcLastIterationOffset) = CLI;
    417   }
    418   void setPreCond(Expr *PC) {
    419     *std::next(child_begin(), PreConditionOffset) = PC;
    420   }
    421   void setCond(Expr *Cond) {
    422     *std::next(child_begin(), CondOffset) = Cond;
    423   }
    424   void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; }
    425   void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; }
    426   void setIsLastIterVariable(Expr *IL) {
    427     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    428             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    429             isOpenMPDistributeDirective(getDirectiveKind())) &&
    430            "expected worksharing loop directive");
    431     *std::next(child_begin(), IsLastIterVariableOffset) = IL;
    432   }
    433   void setLowerBoundVariable(Expr *LB) {
    434     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    435             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    436             isOpenMPDistributeDirective(getDirectiveKind())) &&
    437            "expected worksharing loop directive");
    438     *std::next(child_begin(), LowerBoundVariableOffset) = LB;
    439   }
    440   void setUpperBoundVariable(Expr *UB) {
    441     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    442             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    443             isOpenMPDistributeDirective(getDirectiveKind())) &&
    444            "expected worksharing loop directive");
    445     *std::next(child_begin(), UpperBoundVariableOffset) = UB;
    446   }
    447   void setStrideVariable(Expr *ST) {
    448     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    449             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    450             isOpenMPDistributeDirective(getDirectiveKind())) &&
    451            "expected worksharing loop directive");
    452     *std::next(child_begin(), StrideVariableOffset) = ST;
    453   }
    454   void setEnsureUpperBound(Expr *EUB) {
    455     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    456             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    457             isOpenMPDistributeDirective(getDirectiveKind())) &&
    458            "expected worksharing loop directive");
    459     *std::next(child_begin(), EnsureUpperBoundOffset) = EUB;
    460   }
    461   void setNextLowerBound(Expr *NLB) {
    462     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    463             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    464             isOpenMPDistributeDirective(getDirectiveKind())) &&
    465            "expected worksharing loop directive");
    466     *std::next(child_begin(), NextLowerBoundOffset) = NLB;
    467   }
    468   void setNextUpperBound(Expr *NUB) {
    469     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    470             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    471             isOpenMPDistributeDirective(getDirectiveKind())) &&
    472            "expected worksharing loop directive");
    473     *std::next(child_begin(), NextUpperBoundOffset) = NUB;
    474   }
    475   void setCounters(ArrayRef<Expr *> A);
    476   void setPrivateCounters(ArrayRef<Expr *> A);
    477   void setInits(ArrayRef<Expr *> A);
    478   void setUpdates(ArrayRef<Expr *> A);
    479   void setFinals(ArrayRef<Expr *> A);
    480 
    481 public:
    482   /// \brief The expressions built for the OpenMP loop CodeGen for the
    483   /// whole collapsed loop nest.
    484   struct HelperExprs {
    485     /// \brief Loop iteration variable.
    486     Expr *IterationVarRef;
    487     /// \brief Loop last iteration number.
    488     Expr *LastIteration;
    489     /// \brief Loop number of iterations.
    490     Expr *NumIterations;
    491     /// \brief Calculation of last iteration.
    492     Expr *CalcLastIteration;
    493     /// \brief Loop pre-condition.
    494     Expr *PreCond;
    495     /// \brief Loop condition.
    496     Expr *Cond;
    497     /// \brief Loop iteration variable init.
    498     Expr *Init;
    499     /// \brief Loop increment.
    500     Expr *Inc;
    501     /// \brief IsLastIteration - local flag variable passed to runtime.
    502     Expr *IL;
    503     /// \brief LowerBound - local variable passed to runtime.
    504     Expr *LB;
    505     /// \brief UpperBound - local variable passed to runtime.
    506     Expr *UB;
    507     /// \brief Stride - local variable passed to runtime.
    508     Expr *ST;
    509     /// \brief EnsureUpperBound -- expression LB = min(LB, NumIterations).
    510     Expr *EUB;
    511     /// \brief Update of LowerBound for statically sheduled 'omp for' loops.
    512     Expr *NLB;
    513     /// \brief Update of UpperBound for statically sheduled 'omp for' loops.
    514     Expr *NUB;
    515     /// \brief Counters Loop counters.
    516     SmallVector<Expr *, 4> Counters;
    517     /// \brief PrivateCounters Loop counters.
    518     SmallVector<Expr *, 4> PrivateCounters;
    519     /// \brief Expressions for loop counters inits for CodeGen.
    520     SmallVector<Expr *, 4> Inits;
    521     /// \brief Expressions for loop counters update for CodeGen.
    522     SmallVector<Expr *, 4> Updates;
    523     /// \brief Final loop counter values for GodeGen.
    524     SmallVector<Expr *, 4> Finals;
    525 
    526     /// \brief Check if all the expressions are built (does not check the
    527     /// worksharing ones).
    528     bool builtAll() {
    529       return IterationVarRef != nullptr && LastIteration != nullptr &&
    530              NumIterations != nullptr && PreCond != nullptr &&
    531              Cond != nullptr && Init != nullptr && Inc != nullptr;
    532     }
    533 
    534     /// \brief Initialize all the fields to null.
    535     /// \param Size Number of elements in the counters/finals/updates arrays.
    536     void clear(unsigned Size) {
    537       IterationVarRef = nullptr;
    538       LastIteration = nullptr;
    539       CalcLastIteration = nullptr;
    540       PreCond = nullptr;
    541       Cond = nullptr;
    542       Init = nullptr;
    543       Inc = nullptr;
    544       IL = nullptr;
    545       LB = nullptr;
    546       UB = nullptr;
    547       ST = nullptr;
    548       EUB = nullptr;
    549       NLB = nullptr;
    550       NUB = nullptr;
    551       Counters.resize(Size);
    552       PrivateCounters.resize(Size);
    553       Inits.resize(Size);
    554       Updates.resize(Size);
    555       Finals.resize(Size);
    556       for (unsigned i = 0; i < Size; ++i) {
    557         Counters[i] = nullptr;
    558         PrivateCounters[i] = nullptr;
    559         Inits[i] = nullptr;
    560         Updates[i] = nullptr;
    561         Finals[i] = nullptr;
    562       }
    563     }
    564   };
    565 
    566   /// \brief Get number of collapsed loops.
    567   unsigned getCollapsedNumber() const { return CollapsedNum; }
    568 
    569   Expr *getIterationVariable() const {
    570     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    571         *std::next(child_begin(), IterationVariableOffset)));
    572   }
    573   Expr *getLastIteration() const {
    574     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    575         *std::next(child_begin(), LastIterationOffset)));
    576   }
    577   Expr *getCalcLastIteration() const {
    578     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    579         *std::next(child_begin(), CalcLastIterationOffset)));
    580   }
    581   Expr *getPreCond() const {
    582     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    583         *std::next(child_begin(), PreConditionOffset)));
    584   }
    585   Expr *getCond() const {
    586     return const_cast<Expr *>(
    587         reinterpret_cast<const Expr *>(*std::next(child_begin(), CondOffset)));
    588   }
    589   Expr *getInit() const {
    590     return const_cast<Expr *>(
    591         reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset)));
    592   }
    593   Expr *getInc() const {
    594     return const_cast<Expr *>(
    595         reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset)));
    596   }
    597   Expr *getIsLastIterVariable() const {
    598     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    599             isOpenMPTaskLoopDirective(getDirectiveKind())) &&
    600            "expected worksharing loop directive");
    601     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    602         *std::next(child_begin(), IsLastIterVariableOffset)));
    603   }
    604   Expr *getLowerBoundVariable() const {
    605     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    606             isOpenMPTaskLoopDirective(getDirectiveKind())) &&
    607            "expected worksharing loop directive");
    608     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    609         *std::next(child_begin(), LowerBoundVariableOffset)));
    610   }
    611   Expr *getUpperBoundVariable() const {
    612     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    613             isOpenMPTaskLoopDirective(getDirectiveKind())) &&
    614            "expected worksharing loop directive");
    615     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    616         *std::next(child_begin(), UpperBoundVariableOffset)));
    617   }
    618   Expr *getStrideVariable() const {
    619     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    620             isOpenMPTaskLoopDirective(getDirectiveKind())) &&
    621            "expected worksharing loop directive");
    622     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    623         *std::next(child_begin(), StrideVariableOffset)));
    624   }
    625   Expr *getEnsureUpperBound() const {
    626     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    627             isOpenMPTaskLoopDirective(getDirectiveKind())) &&
    628            "expected worksharing loop directive");
    629     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    630         *std::next(child_begin(), EnsureUpperBoundOffset)));
    631   }
    632   Expr *getNextLowerBound() const {
    633     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    634             isOpenMPTaskLoopDirective(getDirectiveKind())) &&
    635            "expected worksharing loop directive");
    636     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    637         *std::next(child_begin(), NextLowerBoundOffset)));
    638   }
    639   Expr *getNextUpperBound() const {
    640     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    641             isOpenMPTaskLoopDirective(getDirectiveKind())) &&
    642            "expected worksharing loop directive");
    643     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    644         *std::next(child_begin(), NextUpperBoundOffset)));
    645   }
    646   const Stmt *getBody() const {
    647     // This relies on the loop form is already checked by Sema.
    648     Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
    649     Body = cast<ForStmt>(Body)->getBody();
    650     for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
    651       Body = Body->IgnoreContainers();
    652       Body = cast<ForStmt>(Body)->getBody();
    653     }
    654     return Body;
    655   }
    656 
    657   ArrayRef<Expr *> counters() { return getCounters(); }
    658 
    659   ArrayRef<Expr *> counters() const {
    660     return const_cast<OMPLoopDirective *>(this)->getCounters();
    661   }
    662 
    663   ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
    664 
    665   ArrayRef<Expr *> private_counters() const {
    666     return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
    667   }
    668 
    669   ArrayRef<Expr *> inits() { return getInits(); }
    670 
    671   ArrayRef<Expr *> inits() const {
    672     return const_cast<OMPLoopDirective *>(this)->getInits();
    673   }
    674 
    675   ArrayRef<Expr *> updates() { return getUpdates(); }
    676 
    677   ArrayRef<Expr *> updates() const {
    678     return const_cast<OMPLoopDirective *>(this)->getUpdates();
    679   }
    680 
    681   ArrayRef<Expr *> finals() { return getFinals(); }
    682 
    683   ArrayRef<Expr *> finals() const {
    684     return const_cast<OMPLoopDirective *>(this)->getFinals();
    685   }
    686 
    687   static bool classof(const Stmt *T) {
    688     return T->getStmtClass() == OMPSimdDirectiveClass ||
    689            T->getStmtClass() == OMPForDirectiveClass ||
    690            T->getStmtClass() == OMPForSimdDirectiveClass ||
    691            T->getStmtClass() == OMPParallelForDirectiveClass ||
    692            T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
    693            T->getStmtClass() == OMPTaskLoopDirectiveClass ||
    694            T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
    695            T->getStmtClass() == OMPDistributeDirectiveClass;
    696   }
    697 };
    698 
    699 /// \brief This represents '#pragma omp simd' directive.
    700 ///
    701 /// \code
    702 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
    703 /// \endcode
    704 /// In this example directive '#pragma omp simd' has clauses 'private'
    705 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
    706 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
    707 ///
    708 class OMPSimdDirective : public OMPLoopDirective {
    709   friend class ASTStmtReader;
    710   /// \brief Build directive with the given start and end location.
    711   ///
    712   /// \param StartLoc Starting location of the directive kind.
    713   /// \param EndLoc Ending location of the directive.
    714   /// \param CollapsedNum Number of collapsed nested loops.
    715   /// \param NumClauses Number of clauses.
    716   ///
    717   OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    718                    unsigned CollapsedNum, unsigned NumClauses)
    719       : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
    720                          EndLoc, CollapsedNum, NumClauses) {}
    721 
    722   /// \brief Build an empty directive.
    723   ///
    724   /// \param CollapsedNum Number of collapsed nested loops.
    725   /// \param NumClauses Number of clauses.
    726   ///
    727   explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
    728       : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd,
    729                          SourceLocation(), SourceLocation(), CollapsedNum,
    730                          NumClauses) {}
    731 
    732 public:
    733   /// \brief Creates directive with a list of \a Clauses.
    734   ///
    735   /// \param C AST context.
    736   /// \param StartLoc Starting location of the directive kind.
    737   /// \param EndLoc Ending Location of the directive.
    738   /// \param CollapsedNum Number of collapsed loops.
    739   /// \param Clauses List of clauses.
    740   /// \param AssociatedStmt Statement, associated with the directive.
    741   /// \param Exprs Helper expressions for CodeGen.
    742   ///
    743   static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
    744                                   SourceLocation EndLoc, unsigned CollapsedNum,
    745                                   ArrayRef<OMPClause *> Clauses,
    746                                   Stmt *AssociatedStmt,
    747                                   const HelperExprs &Exprs);
    748 
    749   /// \brief Creates an empty directive with the place
    750   /// for \a NumClauses clauses.
    751   ///
    752   /// \param C AST context.
    753   /// \param CollapsedNum Number of collapsed nested loops.
    754   /// \param NumClauses Number of clauses.
    755   ///
    756   static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
    757                                        unsigned CollapsedNum, EmptyShell);
    758 
    759   static bool classof(const Stmt *T) {
    760     return T->getStmtClass() == OMPSimdDirectiveClass;
    761   }
    762 };
    763 
    764 /// \brief This represents '#pragma omp for' directive.
    765 ///
    766 /// \code
    767 /// #pragma omp for private(a,b) reduction(+:c,d)
    768 /// \endcode
    769 /// In this example directive '#pragma omp for' has clauses 'private' with the
    770 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
    771 /// and 'd'.
    772 ///
    773 class OMPForDirective : public OMPLoopDirective {
    774   friend class ASTStmtReader;
    775 
    776   /// \brief true if current directive has inner cancel directive.
    777   bool HasCancel;
    778 
    779   /// \brief Build directive with the given start and end location.
    780   ///
    781   /// \param StartLoc Starting location of the directive kind.
    782   /// \param EndLoc Ending location of the directive.
    783   /// \param CollapsedNum Number of collapsed nested loops.
    784   /// \param NumClauses Number of clauses.
    785   ///
    786   OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    787                   unsigned CollapsedNum, unsigned NumClauses)
    788       : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc,
    789                          CollapsedNum, NumClauses),
    790         HasCancel(false) {}
    791 
    792   /// \brief Build an empty directive.
    793   ///
    794   /// \param CollapsedNum Number of collapsed nested loops.
    795   /// \param NumClauses Number of clauses.
    796   ///
    797   explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
    798       : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(),
    799                          SourceLocation(), CollapsedNum, NumClauses),
    800         HasCancel(false) {}
    801 
    802   /// \brief Set cancel state.
    803   void setHasCancel(bool Has) { HasCancel = Has; }
    804 
    805 public:
    806   /// \brief Creates directive with a list of \a Clauses.
    807   ///
    808   /// \param C AST context.
    809   /// \param StartLoc Starting location of the directive kind.
    810   /// \param EndLoc Ending Location of the directive.
    811   /// \param CollapsedNum Number of collapsed loops.
    812   /// \param Clauses List of clauses.
    813   /// \param AssociatedStmt Statement, associated with the directive.
    814   /// \param Exprs Helper expressions for CodeGen.
    815   /// \param HasCancel true if current directive has inner cancel directive.
    816   ///
    817   static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
    818                                  SourceLocation EndLoc, unsigned CollapsedNum,
    819                                  ArrayRef<OMPClause *> Clauses,
    820                                  Stmt *AssociatedStmt, const HelperExprs &Exprs,
    821                                  bool HasCancel);
    822 
    823   /// \brief Creates an empty directive with the place
    824   /// for \a NumClauses clauses.
    825   ///
    826   /// \param C AST context.
    827   /// \param CollapsedNum Number of collapsed nested loops.
    828   /// \param NumClauses Number of clauses.
    829   ///
    830   static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
    831                                       unsigned CollapsedNum, EmptyShell);
    832 
    833   /// \brief Return true if current directive has inner cancel directive.
    834   bool hasCancel() const { return HasCancel; }
    835 
    836   static bool classof(const Stmt *T) {
    837     return T->getStmtClass() == OMPForDirectiveClass;
    838   }
    839 };
    840 
    841 /// \brief This represents '#pragma omp for simd' directive.
    842 ///
    843 /// \code
    844 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
    845 /// \endcode
    846 /// In this example directive '#pragma omp for simd' has clauses 'private'
    847 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
    848 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
    849 ///
    850 class OMPForSimdDirective : public OMPLoopDirective {
    851   friend class ASTStmtReader;
    852   /// \brief Build directive with the given start and end location.
    853   ///
    854   /// \param StartLoc Starting location of the directive kind.
    855   /// \param EndLoc Ending location of the directive.
    856   /// \param CollapsedNum Number of collapsed nested loops.
    857   /// \param NumClauses Number of clauses.
    858   ///
    859   OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    860                       unsigned CollapsedNum, unsigned NumClauses)
    861       : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
    862                          StartLoc, EndLoc, CollapsedNum, NumClauses) {}
    863 
    864   /// \brief Build an empty directive.
    865   ///
    866   /// \param CollapsedNum Number of collapsed nested loops.
    867   /// \param NumClauses Number of clauses.
    868   ///
    869   explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
    870       : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
    871                          SourceLocation(), SourceLocation(), CollapsedNum,
    872                          NumClauses) {}
    873 
    874 public:
    875   /// \brief Creates directive with a list of \a Clauses.
    876   ///
    877   /// \param C AST context.
    878   /// \param StartLoc Starting location of the directive kind.
    879   /// \param EndLoc Ending Location of the directive.
    880   /// \param CollapsedNum Number of collapsed loops.
    881   /// \param Clauses List of clauses.
    882   /// \param AssociatedStmt Statement, associated with the directive.
    883   /// \param Exprs Helper expressions for CodeGen.
    884   ///
    885   static OMPForSimdDirective *
    886   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
    887          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
    888          Stmt *AssociatedStmt, const HelperExprs &Exprs);
    889 
    890   /// \brief Creates an empty directive with the place
    891   /// for \a NumClauses clauses.
    892   ///
    893   /// \param C AST context.
    894   /// \param CollapsedNum Number of collapsed nested loops.
    895   /// \param NumClauses Number of clauses.
    896   ///
    897   static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
    898                                           unsigned NumClauses,
    899                                           unsigned CollapsedNum, EmptyShell);
    900 
    901   static bool classof(const Stmt *T) {
    902     return T->getStmtClass() == OMPForSimdDirectiveClass;
    903   }
    904 };
    905 
    906 /// \brief This represents '#pragma omp sections' directive.
    907 ///
    908 /// \code
    909 /// #pragma omp sections private(a,b) reduction(+:c,d)
    910 /// \endcode
    911 /// In this example directive '#pragma omp sections' has clauses 'private' with
    912 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
    913 /// 'c' and 'd'.
    914 ///
    915 class OMPSectionsDirective : public OMPExecutableDirective {
    916   friend class ASTStmtReader;
    917 
    918   /// \brief true if current directive has inner cancel directive.
    919   bool HasCancel;
    920 
    921   /// \brief Build directive with the given start and end location.
    922   ///
    923   /// \param StartLoc Starting location of the directive kind.
    924   /// \param EndLoc Ending location of the directive.
    925   /// \param NumClauses Number of clauses.
    926   ///
    927   OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    928                        unsigned NumClauses)
    929       : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
    930                                StartLoc, EndLoc, NumClauses, 1),
    931         HasCancel(false) {}
    932 
    933   /// \brief Build an empty directive.
    934   ///
    935   /// \param NumClauses Number of clauses.
    936   ///
    937   explicit OMPSectionsDirective(unsigned NumClauses)
    938       : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
    939                                SourceLocation(), SourceLocation(), NumClauses,
    940                                1),
    941         HasCancel(false) {}
    942 
    943   /// \brief Set cancel state.
    944   void setHasCancel(bool Has) { HasCancel = Has; }
    945 
    946 public:
    947   /// \brief Creates directive with a list of \a Clauses.
    948   ///
    949   /// \param C AST context.
    950   /// \param StartLoc Starting location of the directive kind.
    951   /// \param EndLoc Ending Location of the directive.
    952   /// \param Clauses List of clauses.
    953   /// \param AssociatedStmt Statement, associated with the directive.
    954   /// \param HasCancel true if current directive has inner directive.
    955   ///
    956   static OMPSectionsDirective *
    957   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
    958          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
    959 
    960   /// \brief Creates an empty directive with the place for \a NumClauses
    961   /// clauses.
    962   ///
    963   /// \param C AST context.
    964   /// \param NumClauses Number of clauses.
    965   ///
    966   static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
    967                                            unsigned NumClauses, EmptyShell);
    968 
    969   /// \brief Return true if current directive has inner cancel directive.
    970   bool hasCancel() const { return HasCancel; }
    971 
    972   static bool classof(const Stmt *T) {
    973     return T->getStmtClass() == OMPSectionsDirectiveClass;
    974   }
    975 };
    976 
    977 /// \brief This represents '#pragma omp section' directive.
    978 ///
    979 /// \code
    980 /// #pragma omp section
    981 /// \endcode
    982 ///
    983 class OMPSectionDirective : public OMPExecutableDirective {
    984   friend class ASTStmtReader;
    985 
    986   /// \brief true if current directive has inner cancel directive.
    987   bool HasCancel;
    988 
    989   /// \brief Build directive with the given start and end location.
    990   ///
    991   /// \param StartLoc Starting location of the directive kind.
    992   /// \param EndLoc Ending location of the directive.
    993   ///
    994   OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
    995       : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
    996                                StartLoc, EndLoc, 0, 1),
    997         HasCancel(false) {}
    998 
    999   /// \brief Build an empty directive.
   1000   ///
   1001   explicit OMPSectionDirective()
   1002       : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
   1003                                SourceLocation(), SourceLocation(), 0, 1),
   1004         HasCancel(false) {}
   1005 
   1006 public:
   1007   /// \brief Creates directive.
   1008   ///
   1009   /// \param C AST context.
   1010   /// \param StartLoc Starting location of the directive kind.
   1011   /// \param EndLoc Ending Location of the directive.
   1012   /// \param AssociatedStmt Statement, associated with the directive.
   1013   /// \param HasCancel true if current directive has inner directive.
   1014   ///
   1015   static OMPSectionDirective *Create(const ASTContext &C,
   1016                                      SourceLocation StartLoc,
   1017                                      SourceLocation EndLoc,
   1018                                      Stmt *AssociatedStmt, bool HasCancel);
   1019 
   1020   /// \brief Creates an empty directive.
   1021   ///
   1022   /// \param C AST context.
   1023   ///
   1024   static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1025 
   1026   /// \brief Set cancel state.
   1027   void setHasCancel(bool Has) { HasCancel = Has; }
   1028 
   1029   /// \brief Return true if current directive has inner cancel directive.
   1030   bool hasCancel() const { return HasCancel; }
   1031 
   1032   static bool classof(const Stmt *T) {
   1033     return T->getStmtClass() == OMPSectionDirectiveClass;
   1034   }
   1035 };
   1036 
   1037 /// \brief This represents '#pragma omp single' directive.
   1038 ///
   1039 /// \code
   1040 /// #pragma omp single private(a,b) copyprivate(c,d)
   1041 /// \endcode
   1042 /// In this example directive '#pragma omp single' has clauses 'private' with
   1043 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
   1044 ///
   1045 class OMPSingleDirective : public OMPExecutableDirective {
   1046   friend class ASTStmtReader;
   1047   /// \brief Build directive with the given start and end location.
   1048   ///
   1049   /// \param StartLoc Starting location of the directive kind.
   1050   /// \param EndLoc Ending location of the directive.
   1051   /// \param NumClauses Number of clauses.
   1052   ///
   1053   OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1054                      unsigned NumClauses)
   1055       : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
   1056                                StartLoc, EndLoc, NumClauses, 1) {}
   1057 
   1058   /// \brief Build an empty directive.
   1059   ///
   1060   /// \param NumClauses Number of clauses.
   1061   ///
   1062   explicit OMPSingleDirective(unsigned NumClauses)
   1063       : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
   1064                                SourceLocation(), SourceLocation(), NumClauses,
   1065                                1) {}
   1066 
   1067 public:
   1068   /// \brief Creates directive with a list of \a Clauses.
   1069   ///
   1070   /// \param C AST context.
   1071   /// \param StartLoc Starting location of the directive kind.
   1072   /// \param EndLoc Ending Location of the directive.
   1073   /// \param Clauses List of clauses.
   1074   /// \param AssociatedStmt Statement, associated with the directive.
   1075   ///
   1076   static OMPSingleDirective *
   1077   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1078          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   1079 
   1080   /// \brief Creates an empty directive with the place for \a NumClauses
   1081   /// clauses.
   1082   ///
   1083   /// \param C AST context.
   1084   /// \param NumClauses Number of clauses.
   1085   ///
   1086   static OMPSingleDirective *CreateEmpty(const ASTContext &C,
   1087                                          unsigned NumClauses, EmptyShell);
   1088 
   1089   static bool classof(const Stmt *T) {
   1090     return T->getStmtClass() == OMPSingleDirectiveClass;
   1091   }
   1092 };
   1093 
   1094 /// \brief This represents '#pragma omp master' directive.
   1095 ///
   1096 /// \code
   1097 /// #pragma omp master
   1098 /// \endcode
   1099 ///
   1100 class OMPMasterDirective : public OMPExecutableDirective {
   1101   friend class ASTStmtReader;
   1102   /// \brief Build directive with the given start and end location.
   1103   ///
   1104   /// \param StartLoc Starting location of the directive kind.
   1105   /// \param EndLoc Ending location of the directive.
   1106   ///
   1107   OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1108       : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
   1109                                StartLoc, EndLoc, 0, 1) {}
   1110 
   1111   /// \brief Build an empty directive.
   1112   ///
   1113   explicit OMPMasterDirective()
   1114       : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
   1115                                SourceLocation(), SourceLocation(), 0, 1) {}
   1116 
   1117 public:
   1118   /// \brief Creates directive.
   1119   ///
   1120   /// \param C AST context.
   1121   /// \param StartLoc Starting location of the directive kind.
   1122   /// \param EndLoc Ending Location of the directive.
   1123   /// \param AssociatedStmt Statement, associated with the directive.
   1124   ///
   1125   static OMPMasterDirective *Create(const ASTContext &C,
   1126                                     SourceLocation StartLoc,
   1127                                     SourceLocation EndLoc,
   1128                                     Stmt *AssociatedStmt);
   1129 
   1130   /// \brief Creates an empty directive.
   1131   ///
   1132   /// \param C AST context.
   1133   ///
   1134   static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1135 
   1136   static bool classof(const Stmt *T) {
   1137     return T->getStmtClass() == OMPMasterDirectiveClass;
   1138   }
   1139 };
   1140 
   1141 /// \brief This represents '#pragma omp critical' directive.
   1142 ///
   1143 /// \code
   1144 /// #pragma omp critical
   1145 /// \endcode
   1146 ///
   1147 class OMPCriticalDirective : public OMPExecutableDirective {
   1148   friend class ASTStmtReader;
   1149   /// \brief Name of the directive.
   1150   DeclarationNameInfo DirName;
   1151   /// \brief Build directive with the given start and end location.
   1152   ///
   1153   /// \param Name Name of the directive.
   1154   /// \param StartLoc Starting location of the directive kind.
   1155   /// \param EndLoc Ending location of the directive.
   1156   /// \param NumClauses Number of clauses.
   1157   ///
   1158   OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
   1159                        SourceLocation EndLoc, unsigned NumClauses)
   1160       : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
   1161                                StartLoc, EndLoc, NumClauses, 1),
   1162         DirName(Name) {}
   1163 
   1164   /// \brief Build an empty directive.
   1165   ///
   1166   /// \param NumClauses Number of clauses.
   1167   ///
   1168   explicit OMPCriticalDirective(unsigned NumClauses)
   1169       : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
   1170                                SourceLocation(), SourceLocation(), NumClauses,
   1171                                1),
   1172         DirName() {}
   1173 
   1174   /// \brief Set name of the directive.
   1175   ///
   1176   /// \param Name Name of the directive.
   1177   ///
   1178   void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
   1179 
   1180 public:
   1181   /// \brief Creates directive.
   1182   ///
   1183   /// \param C AST context.
   1184   /// \param Name Name of the directive.
   1185   /// \param StartLoc Starting location of the directive kind.
   1186   /// \param EndLoc Ending Location of the directive.
   1187   /// \param Clauses List of clauses.
   1188   /// \param AssociatedStmt Statement, associated with the directive.
   1189   ///
   1190   static OMPCriticalDirective *
   1191   Create(const ASTContext &C, const DeclarationNameInfo &Name,
   1192          SourceLocation StartLoc, SourceLocation EndLoc,
   1193          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   1194 
   1195   /// \brief Creates an empty directive.
   1196   ///
   1197   /// \param C AST context.
   1198   /// \param NumClauses Number of clauses.
   1199   ///
   1200   static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
   1201                                            unsigned NumClauses, EmptyShell);
   1202 
   1203   /// \brief Return name of the directive.
   1204   ///
   1205   DeclarationNameInfo getDirectiveName() const { return DirName; }
   1206 
   1207   static bool classof(const Stmt *T) {
   1208     return T->getStmtClass() == OMPCriticalDirectiveClass;
   1209   }
   1210 };
   1211 
   1212 /// \brief This represents '#pragma omp parallel for' directive.
   1213 ///
   1214 /// \code
   1215 /// #pragma omp parallel for private(a,b) reduction(+:c,d)
   1216 /// \endcode
   1217 /// In this example directive '#pragma omp parallel for' has clauses 'private'
   1218 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
   1219 /// variables 'c' and 'd'.
   1220 ///
   1221 class OMPParallelForDirective : public OMPLoopDirective {
   1222   friend class ASTStmtReader;
   1223 
   1224   /// \brief true if current region has inner cancel directive.
   1225   bool HasCancel;
   1226 
   1227   /// \brief Build directive with the given start and end location.
   1228   ///
   1229   /// \param StartLoc Starting location of the directive kind.
   1230   /// \param EndLoc Ending location of the directive.
   1231   /// \param CollapsedNum Number of collapsed nested loops.
   1232   /// \param NumClauses Number of clauses.
   1233   ///
   1234   OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1235                           unsigned CollapsedNum, unsigned NumClauses)
   1236       : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
   1237                          StartLoc, EndLoc, CollapsedNum, NumClauses),
   1238         HasCancel(false) {}
   1239 
   1240   /// \brief Build an empty directive.
   1241   ///
   1242   /// \param CollapsedNum Number of collapsed nested loops.
   1243   /// \param NumClauses Number of clauses.
   1244   ///
   1245   explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
   1246       : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
   1247                          SourceLocation(), SourceLocation(), CollapsedNum,
   1248                          NumClauses),
   1249         HasCancel(false) {}
   1250 
   1251   /// \brief Set cancel state.
   1252   void setHasCancel(bool Has) { HasCancel = Has; }
   1253 
   1254 public:
   1255   /// \brief Creates directive with a list of \a Clauses.
   1256   ///
   1257   /// \param C AST context.
   1258   /// \param StartLoc Starting location of the directive kind.
   1259   /// \param EndLoc Ending Location of the directive.
   1260   /// \param CollapsedNum Number of collapsed loops.
   1261   /// \param Clauses List of clauses.
   1262   /// \param AssociatedStmt Statement, associated with the directive.
   1263   /// \param Exprs Helper expressions for CodeGen.
   1264   /// \param HasCancel true if current directive has inner cancel directive.
   1265   ///
   1266   static OMPParallelForDirective *
   1267   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1268          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   1269          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
   1270 
   1271   /// \brief Creates an empty directive with the place
   1272   /// for \a NumClauses clauses.
   1273   ///
   1274   /// \param C AST context.
   1275   /// \param CollapsedNum Number of collapsed nested loops.
   1276   /// \param NumClauses Number of clauses.
   1277   ///
   1278   static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
   1279                                               unsigned NumClauses,
   1280                                               unsigned CollapsedNum,
   1281                                               EmptyShell);
   1282 
   1283   /// \brief Return true if current directive has inner cancel directive.
   1284   bool hasCancel() const { return HasCancel; }
   1285 
   1286   static bool classof(const Stmt *T) {
   1287     return T->getStmtClass() == OMPParallelForDirectiveClass;
   1288   }
   1289 };
   1290 
   1291 /// \brief This represents '#pragma omp parallel for simd' directive.
   1292 ///
   1293 /// \code
   1294 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
   1295 /// \endcode
   1296 /// In this example directive '#pragma omp parallel for simd' has clauses
   1297 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
   1298 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and
   1299 /// 'd'.
   1300 ///
   1301 class OMPParallelForSimdDirective : public OMPLoopDirective {
   1302   friend class ASTStmtReader;
   1303   /// \brief Build directive with the given start and end location.
   1304   ///
   1305   /// \param StartLoc Starting location of the directive kind.
   1306   /// \param EndLoc Ending location of the directive.
   1307   /// \param CollapsedNum Number of collapsed nested loops.
   1308   /// \param NumClauses Number of clauses.
   1309   ///
   1310   OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1311                               unsigned CollapsedNum, unsigned NumClauses)
   1312       : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
   1313                          OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum,
   1314                          NumClauses) {}
   1315 
   1316   /// \brief Build an empty directive.
   1317   ///
   1318   /// \param CollapsedNum Number of collapsed nested loops.
   1319   /// \param NumClauses Number of clauses.
   1320   ///
   1321   explicit OMPParallelForSimdDirective(unsigned CollapsedNum,
   1322                                        unsigned NumClauses)
   1323       : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
   1324                          OMPD_parallel_for_simd, SourceLocation(),
   1325                          SourceLocation(), CollapsedNum, NumClauses) {}
   1326 
   1327 public:
   1328   /// \brief Creates directive with a list of \a Clauses.
   1329   ///
   1330   /// \param C AST context.
   1331   /// \param StartLoc Starting location of the directive kind.
   1332   /// \param EndLoc Ending Location of the directive.
   1333   /// \param CollapsedNum Number of collapsed loops.
   1334   /// \param Clauses List of clauses.
   1335   /// \param AssociatedStmt Statement, associated with the directive.
   1336   /// \param Exprs Helper expressions for CodeGen.
   1337   ///
   1338   static OMPParallelForSimdDirective *
   1339   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1340          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   1341          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   1342 
   1343   /// \brief Creates an empty directive with the place
   1344   /// for \a NumClauses clauses.
   1345   ///
   1346   /// \param C AST context.
   1347   /// \param CollapsedNum Number of collapsed nested loops.
   1348   /// \param NumClauses Number of clauses.
   1349   ///
   1350   static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
   1351                                                   unsigned NumClauses,
   1352                                                   unsigned CollapsedNum,
   1353                                                   EmptyShell);
   1354 
   1355   static bool classof(const Stmt *T) {
   1356     return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
   1357   }
   1358 };
   1359 
   1360 /// \brief This represents '#pragma omp parallel sections' directive.
   1361 ///
   1362 /// \code
   1363 /// #pragma omp parallel sections private(a,b) reduction(+:c,d)
   1364 /// \endcode
   1365 /// In this example directive '#pragma omp parallel sections' has clauses
   1366 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
   1367 /// and variables 'c' and 'd'.
   1368 ///
   1369 class OMPParallelSectionsDirective : public OMPExecutableDirective {
   1370   friend class ASTStmtReader;
   1371 
   1372   /// \brief true if current directive has inner cancel directive.
   1373   bool HasCancel;
   1374 
   1375   /// \brief Build directive with the given start and end location.
   1376   ///
   1377   /// \param StartLoc Starting location of the directive kind.
   1378   /// \param EndLoc Ending location of the directive.
   1379   /// \param NumClauses Number of clauses.
   1380   ///
   1381   OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1382                                unsigned NumClauses)
   1383       : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
   1384                                OMPD_parallel_sections, StartLoc, EndLoc,
   1385                                NumClauses, 1),
   1386         HasCancel(false) {}
   1387 
   1388   /// \brief Build an empty directive.
   1389   ///
   1390   /// \param NumClauses Number of clauses.
   1391   ///
   1392   explicit OMPParallelSectionsDirective(unsigned NumClauses)
   1393       : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
   1394                                OMPD_parallel_sections, SourceLocation(),
   1395                                SourceLocation(), NumClauses, 1),
   1396         HasCancel(false) {}
   1397 
   1398   /// \brief Set cancel state.
   1399   void setHasCancel(bool Has) { HasCancel = Has; }
   1400 
   1401 public:
   1402   /// \brief Creates directive with a list of \a Clauses.
   1403   ///
   1404   /// \param C AST context.
   1405   /// \param StartLoc Starting location of the directive kind.
   1406   /// \param EndLoc Ending Location of the directive.
   1407   /// \param Clauses List of clauses.
   1408   /// \param AssociatedStmt Statement, associated with the directive.
   1409   /// \param HasCancel true if current directive has inner cancel directive.
   1410   ///
   1411   static OMPParallelSectionsDirective *
   1412   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1413          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
   1414 
   1415   /// \brief Creates an empty directive with the place for \a NumClauses
   1416   /// clauses.
   1417   ///
   1418   /// \param C AST context.
   1419   /// \param NumClauses Number of clauses.
   1420   ///
   1421   static OMPParallelSectionsDirective *
   1422   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
   1423 
   1424   /// \brief Return true if current directive has inner cancel directive.
   1425   bool hasCancel() const { return HasCancel; }
   1426 
   1427   static bool classof(const Stmt *T) {
   1428     return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
   1429   }
   1430 };
   1431 
   1432 /// \brief This represents '#pragma omp task' directive.
   1433 ///
   1434 /// \code
   1435 /// #pragma omp task private(a,b) final(d)
   1436 /// \endcode
   1437 /// In this example directive '#pragma omp task' has clauses 'private' with the
   1438 /// variables 'a' and 'b' and 'final' with condition 'd'.
   1439 ///
   1440 class OMPTaskDirective : public OMPExecutableDirective {
   1441   friend class ASTStmtReader;
   1442   /// \brief true if this directive has inner cancel directive.
   1443   bool HasCancel;
   1444 
   1445   /// \brief Build directive with the given start and end location.
   1446   ///
   1447   /// \param StartLoc Starting location of the directive kind.
   1448   /// \param EndLoc Ending location of the directive.
   1449   /// \param NumClauses Number of clauses.
   1450   ///
   1451   OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1452                    unsigned NumClauses)
   1453       : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
   1454                                EndLoc, NumClauses, 1),
   1455         HasCancel(false) {}
   1456 
   1457   /// \brief Build an empty directive.
   1458   ///
   1459   /// \param NumClauses Number of clauses.
   1460   ///
   1461   explicit OMPTaskDirective(unsigned NumClauses)
   1462       : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
   1463                                SourceLocation(), SourceLocation(), NumClauses,
   1464                                1),
   1465         HasCancel(false) {}
   1466 
   1467   /// \brief Set cancel state.
   1468   void setHasCancel(bool Has) { HasCancel = Has; }
   1469 
   1470 public:
   1471   /// \brief Creates directive with a list of \a Clauses.
   1472   ///
   1473   /// \param C AST context.
   1474   /// \param StartLoc Starting location of the directive kind.
   1475   /// \param EndLoc Ending Location of the directive.
   1476   /// \param Clauses List of clauses.
   1477   /// \param AssociatedStmt Statement, associated with the directive.
   1478   /// \param HasCancel true, if current directive has inner cancel directive.
   1479   ///
   1480   static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
   1481                                   SourceLocation EndLoc,
   1482                                   ArrayRef<OMPClause *> Clauses,
   1483                                   Stmt *AssociatedStmt, bool HasCancel);
   1484 
   1485   /// \brief Creates an empty directive with the place for \a NumClauses
   1486   /// clauses.
   1487   ///
   1488   /// \param C AST context.
   1489   /// \param NumClauses Number of clauses.
   1490   ///
   1491   static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
   1492                                        EmptyShell);
   1493 
   1494   /// \brief Return true if current directive has inner cancel directive.
   1495   bool hasCancel() const { return HasCancel; }
   1496 
   1497   static bool classof(const Stmt *T) {
   1498     return T->getStmtClass() == OMPTaskDirectiveClass;
   1499   }
   1500 };
   1501 
   1502 /// \brief This represents '#pragma omp taskyield' directive.
   1503 ///
   1504 /// \code
   1505 /// #pragma omp taskyield
   1506 /// \endcode
   1507 ///
   1508 class OMPTaskyieldDirective : public OMPExecutableDirective {
   1509   friend class ASTStmtReader;
   1510   /// \brief Build directive with the given start and end location.
   1511   ///
   1512   /// \param StartLoc Starting location of the directive kind.
   1513   /// \param EndLoc Ending location of the directive.
   1514   ///
   1515   OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1516       : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
   1517                                StartLoc, EndLoc, 0, 0) {}
   1518 
   1519   /// \brief Build an empty directive.
   1520   ///
   1521   explicit OMPTaskyieldDirective()
   1522       : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
   1523                                SourceLocation(), SourceLocation(), 0, 0) {}
   1524 
   1525 public:
   1526   /// \brief Creates directive.
   1527   ///
   1528   /// \param C AST context.
   1529   /// \param StartLoc Starting location of the directive kind.
   1530   /// \param EndLoc Ending Location of the directive.
   1531   ///
   1532   static OMPTaskyieldDirective *
   1533   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
   1534 
   1535   /// \brief Creates an empty directive.
   1536   ///
   1537   /// \param C AST context.
   1538   ///
   1539   static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1540 
   1541   static bool classof(const Stmt *T) {
   1542     return T->getStmtClass() == OMPTaskyieldDirectiveClass;
   1543   }
   1544 };
   1545 
   1546 /// \brief This represents '#pragma omp barrier' directive.
   1547 ///
   1548 /// \code
   1549 /// #pragma omp barrier
   1550 /// \endcode
   1551 ///
   1552 class OMPBarrierDirective : public OMPExecutableDirective {
   1553   friend class ASTStmtReader;
   1554   /// \brief Build directive with the given start and end location.
   1555   ///
   1556   /// \param StartLoc Starting location of the directive kind.
   1557   /// \param EndLoc Ending location of the directive.
   1558   ///
   1559   OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1560       : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
   1561                                StartLoc, EndLoc, 0, 0) {}
   1562 
   1563   /// \brief Build an empty directive.
   1564   ///
   1565   explicit OMPBarrierDirective()
   1566       : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
   1567                                SourceLocation(), SourceLocation(), 0, 0) {}
   1568 
   1569 public:
   1570   /// \brief Creates directive.
   1571   ///
   1572   /// \param C AST context.
   1573   /// \param StartLoc Starting location of the directive kind.
   1574   /// \param EndLoc Ending Location of the directive.
   1575   ///
   1576   static OMPBarrierDirective *
   1577   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
   1578 
   1579   /// \brief Creates an empty directive.
   1580   ///
   1581   /// \param C AST context.
   1582   ///
   1583   static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1584 
   1585   static bool classof(const Stmt *T) {
   1586     return T->getStmtClass() == OMPBarrierDirectiveClass;
   1587   }
   1588 };
   1589 
   1590 /// \brief This represents '#pragma omp taskwait' directive.
   1591 ///
   1592 /// \code
   1593 /// #pragma omp taskwait
   1594 /// \endcode
   1595 ///
   1596 class OMPTaskwaitDirective : public OMPExecutableDirective {
   1597   friend class ASTStmtReader;
   1598   /// \brief Build directive with the given start and end location.
   1599   ///
   1600   /// \param StartLoc Starting location of the directive kind.
   1601   /// \param EndLoc Ending location of the directive.
   1602   ///
   1603   OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1604       : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
   1605                                StartLoc, EndLoc, 0, 0) {}
   1606 
   1607   /// \brief Build an empty directive.
   1608   ///
   1609   explicit OMPTaskwaitDirective()
   1610       : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
   1611                                SourceLocation(), SourceLocation(), 0, 0) {}
   1612 
   1613 public:
   1614   /// \brief Creates directive.
   1615   ///
   1616   /// \param C AST context.
   1617   /// \param StartLoc Starting location of the directive kind.
   1618   /// \param EndLoc Ending Location of the directive.
   1619   ///
   1620   static OMPTaskwaitDirective *
   1621   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
   1622 
   1623   /// \brief Creates an empty directive.
   1624   ///
   1625   /// \param C AST context.
   1626   ///
   1627   static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1628 
   1629   static bool classof(const Stmt *T) {
   1630     return T->getStmtClass() == OMPTaskwaitDirectiveClass;
   1631   }
   1632 };
   1633 
   1634 /// \brief This represents '#pragma omp taskgroup' directive.
   1635 ///
   1636 /// \code
   1637 /// #pragma omp taskgroup
   1638 /// \endcode
   1639 ///
   1640 class OMPTaskgroupDirective : public OMPExecutableDirective {
   1641   friend class ASTStmtReader;
   1642   /// \brief Build directive with the given start and end location.
   1643   ///
   1644   /// \param StartLoc Starting location of the directive kind.
   1645   /// \param EndLoc Ending location of the directive.
   1646   ///
   1647   OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1648       : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
   1649                                StartLoc, EndLoc, 0, 1) {}
   1650 
   1651   /// \brief Build an empty directive.
   1652   ///
   1653   explicit OMPTaskgroupDirective()
   1654       : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
   1655                                SourceLocation(), SourceLocation(), 0, 1) {}
   1656 
   1657 public:
   1658   /// \brief Creates directive.
   1659   ///
   1660   /// \param C AST context.
   1661   /// \param StartLoc Starting location of the directive kind.
   1662   /// \param EndLoc Ending Location of the directive.
   1663   /// \param AssociatedStmt Statement, associated with the directive.
   1664   ///
   1665   static OMPTaskgroupDirective *Create(const ASTContext &C,
   1666                                        SourceLocation StartLoc,
   1667                                        SourceLocation EndLoc,
   1668                                        Stmt *AssociatedStmt);
   1669 
   1670   /// \brief Creates an empty directive.
   1671   ///
   1672   /// \param C AST context.
   1673   ///
   1674   static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1675 
   1676   static bool classof(const Stmt *T) {
   1677     return T->getStmtClass() == OMPTaskgroupDirectiveClass;
   1678   }
   1679 };
   1680 
   1681 /// \brief This represents '#pragma omp flush' directive.
   1682 ///
   1683 /// \code
   1684 /// #pragma omp flush(a,b)
   1685 /// \endcode
   1686 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
   1687 /// and 'b'.
   1688 /// 'omp flush' directive does not have clauses but have an optional list of
   1689 /// variables to flush. This list of variables is stored within some fake clause
   1690 /// FlushClause.
   1691 class OMPFlushDirective : public OMPExecutableDirective {
   1692   friend class ASTStmtReader;
   1693   /// \brief Build directive with the given start and end location.
   1694   ///
   1695   /// \param StartLoc Starting location of the directive kind.
   1696   /// \param EndLoc Ending location of the directive.
   1697   /// \param NumClauses Number of clauses.
   1698   ///
   1699   OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1700                     unsigned NumClauses)
   1701       : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
   1702                                StartLoc, EndLoc, NumClauses, 0) {}
   1703 
   1704   /// \brief Build an empty directive.
   1705   ///
   1706   /// \param NumClauses Number of clauses.
   1707   ///
   1708   explicit OMPFlushDirective(unsigned NumClauses)
   1709       : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
   1710                                SourceLocation(), SourceLocation(), NumClauses,
   1711                                0) {}
   1712 
   1713 public:
   1714   /// \brief Creates directive with a list of \a Clauses.
   1715   ///
   1716   /// \param C AST context.
   1717   /// \param StartLoc Starting location of the directive kind.
   1718   /// \param EndLoc Ending Location of the directive.
   1719   /// \param Clauses List of clauses (only single OMPFlushClause clause is
   1720   /// allowed).
   1721   ///
   1722   static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
   1723                                    SourceLocation EndLoc,
   1724                                    ArrayRef<OMPClause *> Clauses);
   1725 
   1726   /// \brief Creates an empty directive with the place for \a NumClauses
   1727   /// clauses.
   1728   ///
   1729   /// \param C AST context.
   1730   /// \param NumClauses Number of clauses.
   1731   ///
   1732   static OMPFlushDirective *CreateEmpty(const ASTContext &C,
   1733                                         unsigned NumClauses, EmptyShell);
   1734 
   1735   static bool classof(const Stmt *T) {
   1736     return T->getStmtClass() == OMPFlushDirectiveClass;
   1737   }
   1738 };
   1739 
   1740 /// \brief This represents '#pragma omp ordered' directive.
   1741 ///
   1742 /// \code
   1743 /// #pragma omp ordered
   1744 /// \endcode
   1745 ///
   1746 class OMPOrderedDirective : public OMPExecutableDirective {
   1747   friend class ASTStmtReader;
   1748   /// \brief Build directive with the given start and end location.
   1749   ///
   1750   /// \param StartLoc Starting location of the directive kind.
   1751   /// \param EndLoc Ending location of the directive.
   1752   /// \param NumClauses Number of clauses.
   1753   ///
   1754   OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1755                       unsigned NumClauses)
   1756       : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
   1757                                StartLoc, EndLoc, NumClauses, 1) {}
   1758 
   1759   /// \brief Build an empty directive.
   1760   ///
   1761   /// \param NumClauses Number of clauses.
   1762   ///
   1763   explicit OMPOrderedDirective(unsigned NumClauses)
   1764       : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
   1765                                SourceLocation(), SourceLocation(), NumClauses,
   1766                                1) {}
   1767 
   1768 public:
   1769   /// \brief Creates directive.
   1770   ///
   1771   /// \param C AST context.
   1772   /// \param StartLoc Starting location of the directive kind.
   1773   /// \param EndLoc Ending Location of the directive.
   1774   /// \param Clauses List of clauses.
   1775   /// \param AssociatedStmt Statement, associated with the directive.
   1776   ///
   1777   static OMPOrderedDirective *
   1778   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1779          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   1780 
   1781   /// \brief Creates an empty directive.
   1782   ///
   1783   /// \param C AST context.
   1784   /// \param NumClauses Number of clauses.
   1785   ///
   1786   static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
   1787                                           unsigned NumClauses, EmptyShell);
   1788 
   1789   static bool classof(const Stmt *T) {
   1790     return T->getStmtClass() == OMPOrderedDirectiveClass;
   1791   }
   1792 };
   1793 
   1794 /// \brief This represents '#pragma omp atomic' directive.
   1795 ///
   1796 /// \code
   1797 /// #pragma omp atomic capture
   1798 /// \endcode
   1799 /// In this example directive '#pragma omp atomic' has clause 'capture'.
   1800 ///
   1801 class OMPAtomicDirective : public OMPExecutableDirective {
   1802   friend class ASTStmtReader;
   1803   /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
   1804   /// have atomic expressions of forms
   1805   /// \code
   1806   /// x = x binop expr;
   1807   /// x = expr binop x;
   1808   /// \endcode
   1809   /// This field is true for the first form of the expression and false for the
   1810   /// second. Required for correct codegen of non-associative operations (like
   1811   /// << or >>).
   1812   bool IsXLHSInRHSPart;
   1813   /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
   1814   /// have atomic expressions of forms
   1815   /// \code
   1816   /// v = x; <update x>;
   1817   /// <update x>; v = x;
   1818   /// \endcode
   1819   /// This field is true for the first(postfix) form of the expression and false
   1820   /// otherwise.
   1821   bool IsPostfixUpdate;
   1822 
   1823   /// \brief Build directive with the given start and end location.
   1824   ///
   1825   /// \param StartLoc Starting location of the directive kind.
   1826   /// \param EndLoc Ending location of the directive.
   1827   /// \param NumClauses Number of clauses.
   1828   ///
   1829   OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1830                      unsigned NumClauses)
   1831       : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
   1832                                StartLoc, EndLoc, NumClauses, 5),
   1833         IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
   1834 
   1835   /// \brief Build an empty directive.
   1836   ///
   1837   /// \param NumClauses Number of clauses.
   1838   ///
   1839   explicit OMPAtomicDirective(unsigned NumClauses)
   1840       : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
   1841                                SourceLocation(), SourceLocation(), NumClauses,
   1842                                5),
   1843         IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
   1844 
   1845   /// \brief Set 'x' part of the associated expression/statement.
   1846   void setX(Expr *X) { *std::next(child_begin()) = X; }
   1847   /// \brief Set helper expression of the form
   1848   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
   1849   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
   1850   void setUpdateExpr(Expr *UE) { *std::next(child_begin(), 2) = UE; }
   1851   /// \brief Set 'v' part of the associated expression/statement.
   1852   void setV(Expr *V) { *std::next(child_begin(), 3) = V; }
   1853   /// \brief Set 'expr' part of the associated expression/statement.
   1854   void setExpr(Expr *E) { *std::next(child_begin(), 4) = E; }
   1855 
   1856 public:
   1857   /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
   1858   /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
   1859   /// detailed description of 'x', 'v' and 'expr').
   1860   ///
   1861   /// \param C AST context.
   1862   /// \param StartLoc Starting location of the directive kind.
   1863   /// \param EndLoc Ending Location of the directive.
   1864   /// \param Clauses List of clauses.
   1865   /// \param AssociatedStmt Statement, associated with the directive.
   1866   /// \param X 'x' part of the associated expression/statement.
   1867   /// \param V 'v' part of the associated expression/statement.
   1868   /// \param E 'expr' part of the associated expression/statement.
   1869   /// \param UE Helper expression of the form
   1870   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
   1871   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
   1872   /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the
   1873   /// second.
   1874   /// \param IsPostfixUpdate true if original value of 'x' must be stored in
   1875   /// 'v', not an updated one.
   1876   static OMPAtomicDirective *
   1877   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1878          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
   1879          Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate);
   1880 
   1881   /// \brief Creates an empty directive with the place for \a NumClauses
   1882   /// clauses.
   1883   ///
   1884   /// \param C AST context.
   1885   /// \param NumClauses Number of clauses.
   1886   ///
   1887   static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
   1888                                          unsigned NumClauses, EmptyShell);
   1889 
   1890   /// \brief Get 'x' part of the associated expression/statement.
   1891   Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); }
   1892   const Expr *getX() const {
   1893     return cast_or_null<Expr>(*std::next(child_begin()));
   1894   }
   1895   /// \brief Get helper expression of the form
   1896   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
   1897   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
   1898   Expr *getUpdateExpr() {
   1899     return cast_or_null<Expr>(*std::next(child_begin(), 2));
   1900   }
   1901   const Expr *getUpdateExpr() const {
   1902     return cast_or_null<Expr>(*std::next(child_begin(), 2));
   1903   }
   1904   /// \brief Return true if helper update expression has form
   1905   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
   1906   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
   1907   bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
   1908   /// \brief Return true if 'v' expression must be updated to original value of
   1909   /// 'x', false if 'v' must be updated to the new value of 'x'.
   1910   bool isPostfixUpdate() const { return IsPostfixUpdate; }
   1911   /// \brief Get 'v' part of the associated expression/statement.
   1912   Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); }
   1913   const Expr *getV() const {
   1914     return cast_or_null<Expr>(*std::next(child_begin(), 3));
   1915   }
   1916   /// \brief Get 'expr' part of the associated expression/statement.
   1917   Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 4)); }
   1918   const Expr *getExpr() const {
   1919     return cast_or_null<Expr>(*std::next(child_begin(), 4));
   1920   }
   1921 
   1922   static bool classof(const Stmt *T) {
   1923     return T->getStmtClass() == OMPAtomicDirectiveClass;
   1924   }
   1925 };
   1926 
   1927 /// \brief This represents '#pragma omp target' directive.
   1928 ///
   1929 /// \code
   1930 /// #pragma omp target if(a)
   1931 /// \endcode
   1932 /// In this example directive '#pragma omp target' has clause 'if' with
   1933 /// condition 'a'.
   1934 ///
   1935 class OMPTargetDirective : public OMPExecutableDirective {
   1936   friend class ASTStmtReader;
   1937   /// \brief Build directive with the given start and end location.
   1938   ///
   1939   /// \param StartLoc Starting location of the directive kind.
   1940   /// \param EndLoc Ending location of the directive.
   1941   /// \param NumClauses Number of clauses.
   1942   ///
   1943   OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1944                      unsigned NumClauses)
   1945       : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
   1946                                StartLoc, EndLoc, NumClauses, 1) {}
   1947 
   1948   /// \brief Build an empty directive.
   1949   ///
   1950   /// \param NumClauses Number of clauses.
   1951   ///
   1952   explicit OMPTargetDirective(unsigned NumClauses)
   1953       : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
   1954                                SourceLocation(), SourceLocation(), NumClauses,
   1955                                1) {}
   1956 
   1957 public:
   1958   /// \brief Creates directive with a list of \a Clauses.
   1959   ///
   1960   /// \param C AST context.
   1961   /// \param StartLoc Starting location of the directive kind.
   1962   /// \param EndLoc Ending Location of the directive.
   1963   /// \param Clauses List of clauses.
   1964   /// \param AssociatedStmt Statement, associated with the directive.
   1965   ///
   1966   static OMPTargetDirective *
   1967   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1968          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   1969 
   1970   /// \brief Creates an empty directive with the place for \a NumClauses
   1971   /// clauses.
   1972   ///
   1973   /// \param C AST context.
   1974   /// \param NumClauses Number of clauses.
   1975   ///
   1976   static OMPTargetDirective *CreateEmpty(const ASTContext &C,
   1977                                          unsigned NumClauses, EmptyShell);
   1978 
   1979   static bool classof(const Stmt *T) {
   1980     return T->getStmtClass() == OMPTargetDirectiveClass;
   1981   }
   1982 };
   1983 
   1984 /// \brief This represents '#pragma omp target data' directive.
   1985 ///
   1986 /// \code
   1987 /// #pragma omp target data device(0) if(a) map(b[:])
   1988 /// \endcode
   1989 /// In this example directive '#pragma omp target data' has clauses 'device'
   1990 /// with the value '0', 'if' with condition 'a' and 'map' with array
   1991 /// section 'b[:]'.
   1992 ///
   1993 class OMPTargetDataDirective : public OMPExecutableDirective {
   1994   friend class ASTStmtReader;
   1995   /// \brief Build directive with the given start and end location.
   1996   ///
   1997   /// \param StartLoc Starting location of the directive kind.
   1998   /// \param EndLoc Ending Location of the directive.
   1999   /// \param NumClauses The number of clauses.
   2000   ///
   2001   OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2002                          unsigned NumClauses)
   2003       : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
   2004                                OMPD_target_data, StartLoc, EndLoc, NumClauses,
   2005                                1) {}
   2006 
   2007   /// \brief Build an empty directive.
   2008   ///
   2009   /// \param NumClauses Number of clauses.
   2010   ///
   2011   explicit OMPTargetDataDirective(unsigned NumClauses)
   2012       : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
   2013                                OMPD_target_data, SourceLocation(),
   2014                                SourceLocation(), NumClauses, 1) {}
   2015 
   2016 public:
   2017   /// \brief Creates directive with a list of \a Clauses.
   2018   ///
   2019   /// \param C AST context.
   2020   /// \param StartLoc Starting location of the directive kind.
   2021   /// \param EndLoc Ending Location of the directive.
   2022   /// \param Clauses List of clauses.
   2023   /// \param AssociatedStmt Statement, associated with the directive.
   2024   ///
   2025   static OMPTargetDataDirective *
   2026   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2027          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   2028 
   2029   /// \brief Creates an empty directive with the place for \a N clauses.
   2030   ///
   2031   /// \param C AST context.
   2032   /// \param N The number of clauses.
   2033   ///
   2034   static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
   2035                                              EmptyShell);
   2036 
   2037   static bool classof(const Stmt *T) {
   2038     return T->getStmtClass() == OMPTargetDataDirectiveClass;
   2039   }
   2040 };
   2041 
   2042 /// \brief This represents '#pragma omp teams' directive.
   2043 ///
   2044 /// \code
   2045 /// #pragma omp teams if(a)
   2046 /// \endcode
   2047 /// In this example directive '#pragma omp teams' has clause 'if' with
   2048 /// condition 'a'.
   2049 ///
   2050 class OMPTeamsDirective : public OMPExecutableDirective {
   2051   friend class ASTStmtReader;
   2052   /// \brief Build directive with the given start and end location.
   2053   ///
   2054   /// \param StartLoc Starting location of the directive kind.
   2055   /// \param EndLoc Ending location of the directive.
   2056   /// \param NumClauses Number of clauses.
   2057   ///
   2058   OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2059                     unsigned NumClauses)
   2060       : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
   2061                                StartLoc, EndLoc, NumClauses, 1) {}
   2062 
   2063   /// \brief Build an empty directive.
   2064   ///
   2065   /// \param NumClauses Number of clauses.
   2066   ///
   2067   explicit OMPTeamsDirective(unsigned NumClauses)
   2068       : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
   2069                                SourceLocation(), SourceLocation(), NumClauses,
   2070                                1) {}
   2071 
   2072 public:
   2073   /// \brief Creates directive with a list of \a Clauses.
   2074   ///
   2075   /// \param C AST context.
   2076   /// \param StartLoc Starting location of the directive kind.
   2077   /// \param EndLoc Ending Location of the directive.
   2078   /// \param Clauses List of clauses.
   2079   /// \param AssociatedStmt Statement, associated with the directive.
   2080   ///
   2081   static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
   2082                                    SourceLocation EndLoc,
   2083                                    ArrayRef<OMPClause *> Clauses,
   2084                                    Stmt *AssociatedStmt);
   2085 
   2086   /// \brief Creates an empty directive with the place for \a NumClauses
   2087   /// clauses.
   2088   ///
   2089   /// \param C AST context.
   2090   /// \param NumClauses Number of clauses.
   2091   ///
   2092   static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
   2093                                         unsigned NumClauses, EmptyShell);
   2094 
   2095   static bool classof(const Stmt *T) {
   2096     return T->getStmtClass() == OMPTeamsDirectiveClass;
   2097   }
   2098 };
   2099 
   2100 /// \brief This represents '#pragma omp cancellation point' directive.
   2101 ///
   2102 /// \code
   2103 /// #pragma omp cancellation point for
   2104 /// \endcode
   2105 ///
   2106 /// In this example a cancellation point is created for innermost 'for' region.
   2107 class OMPCancellationPointDirective : public OMPExecutableDirective {
   2108   friend class ASTStmtReader;
   2109   OpenMPDirectiveKind CancelRegion;
   2110   /// \brief Build directive with the given start and end location.
   2111   ///
   2112   /// \param StartLoc Starting location of the directive kind.
   2113   /// \param EndLoc Ending location of the directive.
   2114   ///
   2115   OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   2116       : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
   2117                                OMPD_cancellation_point, StartLoc, EndLoc, 0, 0),
   2118         CancelRegion(OMPD_unknown) {}
   2119 
   2120   /// \brief Build an empty directive.
   2121   ///
   2122   explicit OMPCancellationPointDirective()
   2123       : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
   2124                                OMPD_cancellation_point, SourceLocation(),
   2125                                SourceLocation(), 0, 0),
   2126         CancelRegion(OMPD_unknown) {}
   2127 
   2128   /// \brief Set cancel region for current cancellation point.
   2129   /// \param CR Cancellation region.
   2130   void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
   2131 
   2132 public:
   2133   /// \brief Creates directive.
   2134   ///
   2135   /// \param C AST context.
   2136   /// \param StartLoc Starting location of the directive kind.
   2137   /// \param EndLoc Ending Location of the directive.
   2138   ///
   2139   static OMPCancellationPointDirective *
   2140   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2141          OpenMPDirectiveKind CancelRegion);
   2142 
   2143   /// \brief Creates an empty directive.
   2144   ///
   2145   /// \param C AST context.
   2146   ///
   2147   static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
   2148                                                     EmptyShell);
   2149 
   2150   /// \brief Get cancellation region for the current cancellation point.
   2151   OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
   2152 
   2153   static bool classof(const Stmt *T) {
   2154     return T->getStmtClass() == OMPCancellationPointDirectiveClass;
   2155   }
   2156 };
   2157 
   2158 /// \brief This represents '#pragma omp cancel' directive.
   2159 ///
   2160 /// \code
   2161 /// #pragma omp cancel for
   2162 /// \endcode
   2163 ///
   2164 /// In this example a cancel is created for innermost 'for' region.
   2165 class OMPCancelDirective : public OMPExecutableDirective {
   2166   friend class ASTStmtReader;
   2167   OpenMPDirectiveKind CancelRegion;
   2168   /// \brief Build directive with the given start and end location.
   2169   ///
   2170   /// \param StartLoc Starting location of the directive kind.
   2171   /// \param EndLoc Ending location of the directive.
   2172   /// \param NumClauses Number of clauses.
   2173   ///
   2174   OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2175                      unsigned NumClauses)
   2176       : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
   2177                                StartLoc, EndLoc, NumClauses, 0),
   2178         CancelRegion(OMPD_unknown) {}
   2179 
   2180   /// \brief Build an empty directive.
   2181   ///
   2182   /// \param NumClauses Number of clauses.
   2183   explicit OMPCancelDirective(unsigned NumClauses)
   2184       : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
   2185                                SourceLocation(), SourceLocation(), NumClauses,
   2186                                0),
   2187         CancelRegion(OMPD_unknown) {}
   2188 
   2189   /// \brief Set cancel region for current cancellation point.
   2190   /// \param CR Cancellation region.
   2191   void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
   2192 
   2193 public:
   2194   /// \brief Creates directive.
   2195   ///
   2196   /// \param C AST context.
   2197   /// \param StartLoc Starting location of the directive kind.
   2198   /// \param EndLoc Ending Location of the directive.
   2199   /// \param Clauses List of clauses.
   2200   ///
   2201   static OMPCancelDirective *
   2202   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2203          ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
   2204 
   2205   /// \brief Creates an empty directive.
   2206   ///
   2207   /// \param C AST context.
   2208   /// \param NumClauses Number of clauses.
   2209   ///
   2210   static OMPCancelDirective *CreateEmpty(const ASTContext &C,
   2211                                          unsigned NumClauses, EmptyShell);
   2212 
   2213   /// \brief Get cancellation region for the current cancellation point.
   2214   OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
   2215 
   2216   static bool classof(const Stmt *T) {
   2217     return T->getStmtClass() == OMPCancelDirectiveClass;
   2218   }
   2219 };
   2220 
   2221 /// \brief This represents '#pragma omp taskloop' directive.
   2222 ///
   2223 /// \code
   2224 /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
   2225 /// \endcode
   2226 /// In this example directive '#pragma omp taskloop' has clauses 'private'
   2227 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
   2228 /// 'num_tasks' with expression 'num'.
   2229 ///
   2230 class OMPTaskLoopDirective : public OMPLoopDirective {
   2231   friend class ASTStmtReader;
   2232   /// \brief Build directive with the given start and end location.
   2233   ///
   2234   /// \param StartLoc Starting location of the directive kind.
   2235   /// \param EndLoc Ending location of the directive.
   2236   /// \param CollapsedNum Number of collapsed nested loops.
   2237   /// \param NumClauses Number of clauses.
   2238   ///
   2239   OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2240                        unsigned CollapsedNum, unsigned NumClauses)
   2241       : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
   2242                          StartLoc, EndLoc, CollapsedNum, NumClauses) {}
   2243 
   2244   /// \brief Build an empty directive.
   2245   ///
   2246   /// \param CollapsedNum Number of collapsed nested loops.
   2247   /// \param NumClauses Number of clauses.
   2248   ///
   2249   explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses)
   2250       : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
   2251                          SourceLocation(), SourceLocation(), CollapsedNum,
   2252                          NumClauses) {}
   2253 
   2254 public:
   2255   /// \brief Creates directive with a list of \a Clauses.
   2256   ///
   2257   /// \param C AST context.
   2258   /// \param StartLoc Starting location of the directive kind.
   2259   /// \param EndLoc Ending Location of the directive.
   2260   /// \param CollapsedNum Number of collapsed loops.
   2261   /// \param Clauses List of clauses.
   2262   /// \param AssociatedStmt Statement, associated with the directive.
   2263   /// \param Exprs Helper expressions for CodeGen.
   2264   ///
   2265   static OMPTaskLoopDirective *
   2266   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2267          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   2268          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   2269 
   2270   /// \brief Creates an empty directive with the place
   2271   /// for \a NumClauses clauses.
   2272   ///
   2273   /// \param C AST context.
   2274   /// \param CollapsedNum Number of collapsed nested loops.
   2275   /// \param NumClauses Number of clauses.
   2276   ///
   2277   static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
   2278                                            unsigned NumClauses,
   2279                                            unsigned CollapsedNum, EmptyShell);
   2280 
   2281   static bool classof(const Stmt *T) {
   2282     return T->getStmtClass() == OMPTaskLoopDirectiveClass;
   2283   }
   2284 };
   2285 
   2286 /// \brief This represents '#pragma omp taskloop simd' directive.
   2287 ///
   2288 /// \code
   2289 /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
   2290 /// \endcode
   2291 /// In this example directive '#pragma omp taskloop simd' has clauses 'private'
   2292 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
   2293 /// 'num_tasks' with expression 'num'.
   2294 ///
   2295 class OMPTaskLoopSimdDirective : public OMPLoopDirective {
   2296   friend class ASTStmtReader;
   2297   /// \brief Build directive with the given start and end location.
   2298   ///
   2299   /// \param StartLoc Starting location of the directive kind.
   2300   /// \param EndLoc Ending location of the directive.
   2301   /// \param CollapsedNum Number of collapsed nested loops.
   2302   /// \param NumClauses Number of clauses.
   2303   ///
   2304   OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2305                            unsigned CollapsedNum, unsigned NumClauses)
   2306       : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
   2307                          OMPD_taskloop_simd, StartLoc, EndLoc, CollapsedNum,
   2308                          NumClauses) {}
   2309 
   2310   /// \brief Build an empty directive.
   2311   ///
   2312   /// \param CollapsedNum Number of collapsed nested loops.
   2313   /// \param NumClauses Number of clauses.
   2314   ///
   2315   explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
   2316       : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
   2317                          OMPD_taskloop_simd, SourceLocation(), SourceLocation(),
   2318                          CollapsedNum, NumClauses) {}
   2319 
   2320 public:
   2321   /// \brief Creates directive with a list of \a Clauses.
   2322   ///
   2323   /// \param C AST context.
   2324   /// \param StartLoc Starting location of the directive kind.
   2325   /// \param EndLoc Ending Location of the directive.
   2326   /// \param CollapsedNum Number of collapsed loops.
   2327   /// \param Clauses List of clauses.
   2328   /// \param AssociatedStmt Statement, associated with the directive.
   2329   /// \param Exprs Helper expressions for CodeGen.
   2330   ///
   2331   static OMPTaskLoopSimdDirective *
   2332   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2333          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   2334          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   2335 
   2336   /// \brief Creates an empty directive with the place
   2337   /// for \a NumClauses clauses.
   2338   ///
   2339   /// \param C AST context.
   2340   /// \param CollapsedNum Number of collapsed nested loops.
   2341   /// \param NumClauses Number of clauses.
   2342   ///
   2343   static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
   2344                                                unsigned NumClauses,
   2345                                                unsigned CollapsedNum,
   2346                                                EmptyShell);
   2347 
   2348   static bool classof(const Stmt *T) {
   2349     return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
   2350   }
   2351 };
   2352 
   2353 /// \brief This represents '#pragma omp distribute' directive.
   2354 ///
   2355 /// \code
   2356 /// #pragma omp distribute private(a,b)
   2357 /// \endcode
   2358 /// In this example directive '#pragma omp distribute' has clauses 'private'
   2359 /// with the variables 'a' and 'b'
   2360 ///
   2361 class OMPDistributeDirective : public OMPLoopDirective {
   2362   friend class ASTStmtReader;
   2363 
   2364   /// \brief Build directive with the given start and end location.
   2365   ///
   2366   /// \param StartLoc Starting location of the directive kind.
   2367   /// \param EndLoc Ending location of the directive.
   2368   /// \param CollapsedNum Number of collapsed nested loops.
   2369   /// \param NumClauses Number of clauses.
   2370   ///
   2371   OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2372                          unsigned CollapsedNum, unsigned NumClauses)
   2373       : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
   2374                          StartLoc, EndLoc, CollapsedNum, NumClauses)
   2375         {}
   2376 
   2377   /// \brief Build an empty directive.
   2378   ///
   2379   /// \param CollapsedNum Number of collapsed nested loops.
   2380   /// \param NumClauses Number of clauses.
   2381   ///
   2382   explicit OMPDistributeDirective(unsigned CollapsedNum, unsigned NumClauses)
   2383       : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
   2384                          SourceLocation(), SourceLocation(), CollapsedNum,
   2385                          NumClauses)
   2386         {}
   2387 
   2388 public:
   2389   /// \brief Creates directive with a list of \a Clauses.
   2390   ///
   2391   /// \param C AST context.
   2392   /// \param StartLoc Starting location of the directive kind.
   2393   /// \param EndLoc Ending Location of the directive.
   2394   /// \param CollapsedNum Number of collapsed loops.
   2395   /// \param Clauses List of clauses.
   2396   /// \param AssociatedStmt Statement, associated with the directive.
   2397   /// \param Exprs Helper expressions for CodeGen.
   2398     ///
   2399   static OMPDistributeDirective *
   2400   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2401          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   2402          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   2403 
   2404   /// \brief Creates an empty directive with the place
   2405   /// for \a NumClauses clauses.
   2406   ///
   2407   /// \param C AST context.
   2408   /// \param CollapsedNum Number of collapsed nested loops.
   2409   /// \param NumClauses Number of clauses.
   2410   ///
   2411   static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
   2412                                              unsigned NumClauses,
   2413                                              unsigned CollapsedNum, EmptyShell);
   2414 
   2415   static bool classof(const Stmt *T) {
   2416     return T->getStmtClass() == OMPDistributeDirectiveClass;
   2417   }
   2418 };
   2419 
   2420 } // end namespace clang
   2421 
   2422 #endif
   2423