Home | History | Annotate | Download | only in AST
      1 //===- StmtOpenMP.h - Classes for OpenMP directives  ------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 /// \file
     10 /// \brief This file defines OpenMP AST classes for executable directives and
     11 /// clauses.
     12 ///
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_CLANG_AST_STMTOPENMP_H
     16 #define LLVM_CLANG_AST_STMTOPENMP_H
     17 
     18 #include "clang/AST/Expr.h"
     19 #include "clang/AST/OpenMPClause.h"
     20 #include "clang/AST/Stmt.h"
     21 #include "clang/Basic/OpenMPKinds.h"
     22 #include "clang/Basic/SourceLocation.h"
     23 
     24 namespace clang {
     25 
     26 //===----------------------------------------------------------------------===//
     27 // AST classes for directives.
     28 //===----------------------------------------------------------------------===//
     29 
     30 /// \brief This is a basic class for representing single OpenMP executable
     31 /// directive.
     32 ///
     33 class OMPExecutableDirective : public Stmt {
     34   friend class ASTStmtReader;
     35   /// \brief Kind of the directive.
     36   OpenMPDirectiveKind Kind;
     37   /// \brief Starting location of the directive (directive keyword).
     38   SourceLocation StartLoc;
     39   /// \brief Ending location of the directive.
     40   SourceLocation EndLoc;
     41   /// \brief Numbers of clauses.
     42   const unsigned NumClauses;
     43   /// \brief Number of child expressions/stmts.
     44   const unsigned NumChildren;
     45   /// \brief Offset from this to the start of clauses.
     46   /// There are NumClauses pointers to clauses, they are followed by
     47   /// NumChildren pointers to child stmts/exprs (if the directive type
     48   /// requires an associated stmt, then it has to be the first of them).
     49   const unsigned ClausesOffset;
     50 
     51   /// \brief Get the clauses storage.
     52   MutableArrayRef<OMPClause *> getClauses() {
     53     OMPClause **ClauseStorage = reinterpret_cast<OMPClause **>(
     54         reinterpret_cast<char *>(this) + ClausesOffset);
     55     return MutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);
     56   }
     57 
     58 protected:
     59   /// \brief Build instance of directive of class \a K.
     60   ///
     61   /// \param SC Statement class.
     62   /// \param K Kind of OpenMP directive.
     63   /// \param StartLoc Starting location of the directive (directive keyword).
     64   /// \param EndLoc Ending location of the directive.
     65   ///
     66   template <typename T>
     67   OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K,
     68                          SourceLocation StartLoc, SourceLocation EndLoc,
     69                          unsigned NumClauses, unsigned NumChildren)
     70       : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
     71         EndLoc(std::move(EndLoc)), NumClauses(NumClauses),
     72         NumChildren(NumChildren),
     73         ClausesOffset(llvm::alignTo(sizeof(T), alignof(OMPClause *))) {}
     74 
     75   /// \brief Sets the list of variables for this clause.
     76   ///
     77   /// \param Clauses The list of clauses for the directive.
     78   ///
     79   void setClauses(ArrayRef<OMPClause *> Clauses);
     80 
     81   /// \brief Set the associated statement for the directive.
     82   ///
     83   /// /param S Associated statement.
     84   ///
     85   void setAssociatedStmt(Stmt *S) {
     86     assert(hasAssociatedStmt() && "no associated statement.");
     87     *child_begin() = S;
     88   }
     89 
     90 public:
     91   /// \brief Iterates over a filtered subrange of clauses applied to a
     92   /// directive.
     93   ///
     94   /// This iterator visits only clauses of type SpecificClause.
     95   template <typename SpecificClause>
     96   class specific_clause_iterator
     97       : public llvm::iterator_adaptor_base<
     98             specific_clause_iterator<SpecificClause>,
     99             ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag,
    100             const SpecificClause *, ptrdiff_t, const SpecificClause *,
    101             const SpecificClause *> {
    102     ArrayRef<OMPClause *>::const_iterator End;
    103 
    104     void SkipToNextClause() {
    105       while (this->I != End && !isa<SpecificClause>(*this->I))
    106         ++this->I;
    107     }
    108 
    109   public:
    110     explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses)
    111         : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()),
    112           End(Clauses.end()) {
    113       SkipToNextClause();
    114     }
    115 
    116     const SpecificClause *operator*() const {
    117       return cast<SpecificClause>(*this->I);
    118     }
    119     const SpecificClause *operator->() const { return **this; }
    120 
    121     specific_clause_iterator &operator++() {
    122       ++this->I;
    123       SkipToNextClause();
    124       return *this;
    125     }
    126   };
    127 
    128   template <typename SpecificClause>
    129   static llvm::iterator_range<specific_clause_iterator<SpecificClause>>
    130   getClausesOfKind(ArrayRef<OMPClause *> Clauses) {
    131     return {specific_clause_iterator<SpecificClause>(Clauses),
    132             specific_clause_iterator<SpecificClause>(
    133                 llvm::makeArrayRef(Clauses.end(), 0))};
    134   }
    135 
    136   template <typename SpecificClause>
    137   llvm::iterator_range<specific_clause_iterator<SpecificClause>>
    138   getClausesOfKind() const {
    139     return getClausesOfKind<SpecificClause>(clauses());
    140   }
    141 
    142   /// Gets a single clause of the specified kind associated with the
    143   /// current directive iff there is only one clause of this kind (and assertion
    144   /// is fired if there is more than one clause is associated with the
    145   /// directive). Returns nullptr if no clause of this kind is associated with
    146   /// the directive.
    147   template <typename SpecificClause>
    148   const SpecificClause *getSingleClause() const {
    149     auto Clauses = getClausesOfKind<SpecificClause>();
    150 
    151     if (Clauses.begin() != Clauses.end()) {
    152       assert(std::next(Clauses.begin()) == Clauses.end() &&
    153              "There are at least 2 clauses of the specified kind");
    154       return *Clauses.begin();
    155     }
    156     return nullptr;
    157   }
    158 
    159   /// Returns true if the current directive has one or more clauses of a
    160   /// specific kind.
    161   template <typename SpecificClause>
    162   bool hasClausesOfKind() const {
    163     auto Clauses = getClausesOfKind<SpecificClause>();
    164     return Clauses.begin() != Clauses.end();
    165   }
    166 
    167   /// \brief Returns starting location of directive kind.
    168   SourceLocation getLocStart() const { return StartLoc; }
    169   /// \brief Returns ending location of directive.
    170   SourceLocation getLocEnd() const { return EndLoc; }
    171 
    172   /// \brief Set starting location of directive kind.
    173   ///
    174   /// \param Loc New starting location of directive.
    175   ///
    176   void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
    177   /// \brief Set ending location of directive.
    178   ///
    179   /// \param Loc New ending location of directive.
    180   ///
    181   void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
    182 
    183   /// \brief Get number of clauses.
    184   unsigned getNumClauses() const { return NumClauses; }
    185 
    186   /// \brief Returns specified clause.
    187   ///
    188   /// \param i Number of clause.
    189   ///
    190   OMPClause *getClause(unsigned i) const { return clauses()[i]; }
    191 
    192   /// \brief Returns true if directive has associated statement.
    193   bool hasAssociatedStmt() const { return NumChildren > 0; }
    194 
    195   /// \brief Returns statement associated with the directive.
    196   Stmt *getAssociatedStmt() const {
    197     assert(hasAssociatedStmt() && "no associated statement.");
    198     return const_cast<Stmt *>(*child_begin());
    199   }
    200 
    201   /// \brief Returns the captured statement associated with the
    202   /// component region within the (combined) directive.
    203   //
    204   // \param RegionKind Component region kind.
    205   CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const {
    206     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
    207     getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind());
    208     assert(std::any_of(
    209                CaptureRegions.begin(), CaptureRegions.end(),
    210                [=](const OpenMPDirectiveKind K) { return K == RegionKind; }) &&
    211            "RegionKind not found in OpenMP CaptureRegions.");
    212     auto *CS = cast<CapturedStmt>(getAssociatedStmt());
    213     for (auto ThisCaptureRegion : CaptureRegions) {
    214       if (ThisCaptureRegion == RegionKind)
    215         return CS;
    216       CS = cast<CapturedStmt>(CS->getCapturedStmt());
    217     }
    218     llvm_unreachable("Incorrect RegionKind specified for directive.");
    219   }
    220 
    221   OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
    222 
    223   static bool classof(const Stmt *S) {
    224     return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
    225            S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
    226   }
    227 
    228   child_range children() {
    229     if (!hasAssociatedStmt())
    230       return child_range(child_iterator(), child_iterator());
    231     Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
    232     return child_range(ChildStorage, ChildStorage + NumChildren);
    233   }
    234 
    235   ArrayRef<OMPClause *> clauses() { return getClauses(); }
    236 
    237   ArrayRef<OMPClause *> clauses() const {
    238     return const_cast<OMPExecutableDirective *>(this)->getClauses();
    239   }
    240 };
    241 
    242 /// \brief This represents '#pragma omp parallel' directive.
    243 ///
    244 /// \code
    245 /// #pragma omp parallel private(a,b) reduction(+: c,d)
    246 /// \endcode
    247 /// In this example directive '#pragma omp parallel' has clauses 'private'
    248 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
    249 /// variables 'c' and 'd'.
    250 ///
    251 class OMPParallelDirective : public OMPExecutableDirective {
    252   friend class ASTStmtReader;
    253   /// \brief true if the construct has inner cancel directive.
    254   bool HasCancel;
    255 
    256   /// \brief Build directive with the given start and end location.
    257   ///
    258   /// \param StartLoc Starting location of the directive (directive keyword).
    259   /// \param EndLoc Ending Location of the directive.
    260   ///
    261   OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    262                        unsigned NumClauses)
    263       : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
    264                                StartLoc, EndLoc, NumClauses, 1),
    265         HasCancel(false) {}
    266 
    267   /// \brief Build an empty directive.
    268   ///
    269   /// \param NumClauses Number of clauses.
    270   ///
    271   explicit OMPParallelDirective(unsigned NumClauses)
    272       : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
    273                                SourceLocation(), SourceLocation(), NumClauses,
    274                                1),
    275         HasCancel(false) {}
    276 
    277   /// \brief Set cancel state.
    278   void setHasCancel(bool Has) { HasCancel = Has; }
    279 
    280 public:
    281   /// \brief Creates directive with a list of \a Clauses.
    282   ///
    283   /// \param C AST context.
    284   /// \param StartLoc Starting location of the directive kind.
    285   /// \param EndLoc Ending Location of the directive.
    286   /// \param Clauses List of clauses.
    287   /// \param AssociatedStmt Statement associated with the directive.
    288   /// \param HasCancel true if this directive has inner cancel directive.
    289   ///
    290   static OMPParallelDirective *
    291   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
    292          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
    293 
    294   /// \brief Creates an empty directive with the place for \a N clauses.
    295   ///
    296   /// \param C AST context.
    297   /// \param NumClauses Number of clauses.
    298   ///
    299   static OMPParallelDirective *CreateEmpty(const ASTContext &C,
    300                                            unsigned NumClauses, EmptyShell);
    301 
    302   /// \brief Return true if current directive has inner cancel directive.
    303   bool hasCancel() const { return HasCancel; }
    304 
    305   static bool classof(const Stmt *T) {
    306     return T->getStmtClass() == OMPParallelDirectiveClass;
    307   }
    308 };
    309 
    310 /// \brief This is a common base class for loop directives ('omp simd', 'omp
    311 /// for', 'omp for simd' etc.). It is responsible for the loop code generation.
    312 ///
    313 class OMPLoopDirective : public OMPExecutableDirective {
    314   friend class ASTStmtReader;
    315   /// \brief Number of collapsed loops as specified by 'collapse' clause.
    316   unsigned CollapsedNum;
    317 
    318   /// \brief Offsets to the stored exprs.
    319   /// This enumeration contains offsets to all the pointers to children
    320   /// expressions stored in OMPLoopDirective.
    321   /// The first 9 children are necessary for all the loop directives,
    322   /// the next 8 are specific to the worksharing ones, and the next 11 are
    323   /// used for combined constructs containing two pragmas associated to loops.
    324   /// After the fixed children, three arrays of length CollapsedNum are
    325   /// allocated: loop counters, their updates and final values.
    326   /// PrevLowerBound and PrevUpperBound are used to communicate blocking
    327   /// information in composite constructs which require loop blocking
    328   /// DistInc is used to generate the increment expression for the distribute
    329   /// loop when combined with a further nested loop
    330   /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the
    331   /// for loop when combined with a previous distribute loop in the same pragma
    332   /// (e.g. 'distribute parallel for')
    333   ///
    334   enum {
    335     AssociatedStmtOffset = 0,
    336     IterationVariableOffset = 1,
    337     LastIterationOffset = 2,
    338     CalcLastIterationOffset = 3,
    339     PreConditionOffset = 4,
    340     CondOffset = 5,
    341     InitOffset = 6,
    342     IncOffset = 7,
    343     PreInitsOffset = 8,
    344     // The '...End' enumerators do not correspond to child expressions - they
    345     // specify the offset to the end (and start of the following counters/
    346     // updates/finals arrays).
    347     DefaultEnd = 9,
    348     // The following 8 exprs are used by worksharing and distribute loops only.
    349     IsLastIterVariableOffset = 9,
    350     LowerBoundVariableOffset = 10,
    351     UpperBoundVariableOffset = 11,
    352     StrideVariableOffset = 12,
    353     EnsureUpperBoundOffset = 13,
    354     NextLowerBoundOffset = 14,
    355     NextUpperBoundOffset = 15,
    356     NumIterationsOffset = 16,
    357     // Offset to the end for worksharing loop directives.
    358     WorksharingEnd = 17,
    359     PrevLowerBoundVariableOffset = 17,
    360     PrevUpperBoundVariableOffset = 18,
    361     DistIncOffset = 19,
    362     PrevEnsureUpperBoundOffset = 20,
    363     CombinedLowerBoundVariableOffset = 21,
    364     CombinedUpperBoundVariableOffset = 22,
    365     CombinedEnsureUpperBoundOffset = 23,
    366     CombinedInitOffset = 24,
    367     CombinedConditionOffset = 25,
    368     CombinedNextLowerBoundOffset = 26,
    369     CombinedNextUpperBoundOffset = 27,
    370     // Offset to the end (and start of the following counters/updates/finals
    371     // arrays) for combined distribute loop directives.
    372     CombinedDistributeEnd = 28,
    373   };
    374 
    375   /// \brief Get the counters storage.
    376   MutableArrayRef<Expr *> getCounters() {
    377     Expr **Storage = reinterpret_cast<Expr **>(
    378         &(*(std::next(child_begin(), getArraysOffset(getDirectiveKind())))));
    379     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
    380   }
    381 
    382   /// \brief Get the private counters storage.
    383   MutableArrayRef<Expr *> getPrivateCounters() {
    384     Expr **Storage = reinterpret_cast<Expr **>(&*std::next(
    385         child_begin(), getArraysOffset(getDirectiveKind()) + CollapsedNum));
    386     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
    387   }
    388 
    389   /// \brief Get the updates storage.
    390   MutableArrayRef<Expr *> getInits() {
    391     Expr **Storage = reinterpret_cast<Expr **>(
    392         &*std::next(child_begin(),
    393                     getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum));
    394     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
    395   }
    396 
    397   /// \brief Get the updates storage.
    398   MutableArrayRef<Expr *> getUpdates() {
    399     Expr **Storage = reinterpret_cast<Expr **>(
    400         &*std::next(child_begin(),
    401                     getArraysOffset(getDirectiveKind()) + 3 * CollapsedNum));
    402     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
    403   }
    404 
    405   /// \brief Get the final counter updates storage.
    406   MutableArrayRef<Expr *> getFinals() {
    407     Expr **Storage = reinterpret_cast<Expr **>(
    408         &*std::next(child_begin(),
    409                     getArraysOffset(getDirectiveKind()) + 4 * CollapsedNum));
    410     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
    411   }
    412 
    413 protected:
    414   /// \brief Build instance of loop directive of class \a Kind.
    415   ///
    416   /// \param SC Statement class.
    417   /// \param Kind Kind of OpenMP directive.
    418   /// \param StartLoc Starting location of the directive (directive keyword).
    419   /// \param EndLoc Ending location of the directive.
    420   /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
    421   /// \param NumClauses Number of clauses.
    422   /// \param NumSpecialChildren Number of additional directive-specific stmts.
    423   ///
    424   template <typename T>
    425   OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind,
    426                    SourceLocation StartLoc, SourceLocation EndLoc,
    427                    unsigned CollapsedNum, unsigned NumClauses,
    428                    unsigned NumSpecialChildren = 0)
    429       : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses,
    430                                numLoopChildren(CollapsedNum, Kind) +
    431                                    NumSpecialChildren),
    432         CollapsedNum(CollapsedNum) {}
    433 
    434   /// \brief Offset to the start of children expression arrays.
    435   static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
    436     if (isOpenMPLoopBoundSharingDirective(Kind))
    437       return CombinedDistributeEnd;
    438     if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) ||
    439         isOpenMPDistributeDirective(Kind))
    440       return WorksharingEnd;
    441     return DefaultEnd;
    442   }
    443 
    444   /// \brief Children number.
    445   static unsigned numLoopChildren(unsigned CollapsedNum,
    446                                   OpenMPDirectiveKind Kind) {
    447     return getArraysOffset(Kind) + 5 * CollapsedNum; // Counters,
    448                                                      // PrivateCounters, Inits,
    449                                                      // Updates and Finals
    450   }
    451 
    452   void setIterationVariable(Expr *IV) {
    453     *std::next(child_begin(), IterationVariableOffset) = IV;
    454   }
    455   void setLastIteration(Expr *LI) {
    456     *std::next(child_begin(), LastIterationOffset) = LI;
    457   }
    458   void setCalcLastIteration(Expr *CLI) {
    459     *std::next(child_begin(), CalcLastIterationOffset) = CLI;
    460   }
    461   void setPreCond(Expr *PC) {
    462     *std::next(child_begin(), PreConditionOffset) = PC;
    463   }
    464   void setCond(Expr *Cond) {
    465     *std::next(child_begin(), CondOffset) = Cond;
    466   }
    467   void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; }
    468   void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; }
    469   void setPreInits(Stmt *PreInits) {
    470     *std::next(child_begin(), PreInitsOffset) = PreInits;
    471   }
    472   void setIsLastIterVariable(Expr *IL) {
    473     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    474             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    475             isOpenMPDistributeDirective(getDirectiveKind())) &&
    476            "expected worksharing loop directive");
    477     *std::next(child_begin(), IsLastIterVariableOffset) = IL;
    478   }
    479   void setLowerBoundVariable(Expr *LB) {
    480     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    481             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    482             isOpenMPDistributeDirective(getDirectiveKind())) &&
    483            "expected worksharing loop directive");
    484     *std::next(child_begin(), LowerBoundVariableOffset) = LB;
    485   }
    486   void setUpperBoundVariable(Expr *UB) {
    487     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    488             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    489             isOpenMPDistributeDirective(getDirectiveKind())) &&
    490            "expected worksharing loop directive");
    491     *std::next(child_begin(), UpperBoundVariableOffset) = UB;
    492   }
    493   void setStrideVariable(Expr *ST) {
    494     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    495             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    496             isOpenMPDistributeDirective(getDirectiveKind())) &&
    497            "expected worksharing loop directive");
    498     *std::next(child_begin(), StrideVariableOffset) = ST;
    499   }
    500   void setEnsureUpperBound(Expr *EUB) {
    501     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    502             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    503             isOpenMPDistributeDirective(getDirectiveKind())) &&
    504            "expected worksharing loop directive");
    505     *std::next(child_begin(), EnsureUpperBoundOffset) = EUB;
    506   }
    507   void setNextLowerBound(Expr *NLB) {
    508     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    509             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    510             isOpenMPDistributeDirective(getDirectiveKind())) &&
    511            "expected worksharing loop directive");
    512     *std::next(child_begin(), NextLowerBoundOffset) = NLB;
    513   }
    514   void setNextUpperBound(Expr *NUB) {
    515     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    516             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    517             isOpenMPDistributeDirective(getDirectiveKind())) &&
    518            "expected worksharing loop directive");
    519     *std::next(child_begin(), NextUpperBoundOffset) = NUB;
    520   }
    521   void setNumIterations(Expr *NI) {
    522     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    523             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    524             isOpenMPDistributeDirective(getDirectiveKind())) &&
    525            "expected worksharing loop directive");
    526     *std::next(child_begin(), NumIterationsOffset) = NI;
    527   }
    528   void setPrevLowerBoundVariable(Expr *PrevLB) {
    529     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    530            "expected loop bound sharing directive");
    531     *std::next(child_begin(), PrevLowerBoundVariableOffset) = PrevLB;
    532   }
    533   void setPrevUpperBoundVariable(Expr *PrevUB) {
    534     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    535            "expected loop bound sharing directive");
    536     *std::next(child_begin(), PrevUpperBoundVariableOffset) = PrevUB;
    537   }
    538   void setDistInc(Expr *DistInc) {
    539     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    540            "expected loop bound sharing directive");
    541     *std::next(child_begin(), DistIncOffset) = DistInc;
    542   }
    543   void setPrevEnsureUpperBound(Expr *PrevEUB) {
    544     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    545            "expected loop bound sharing directive");
    546     *std::next(child_begin(), PrevEnsureUpperBoundOffset) = PrevEUB;
    547   }
    548   void setCombinedLowerBoundVariable(Expr *CombLB) {
    549     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    550            "expected loop bound sharing directive");
    551     *std::next(child_begin(), CombinedLowerBoundVariableOffset) = CombLB;
    552   }
    553   void setCombinedUpperBoundVariable(Expr *CombUB) {
    554     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    555            "expected loop bound sharing directive");
    556     *std::next(child_begin(), CombinedUpperBoundVariableOffset) = CombUB;
    557   }
    558   void setCombinedEnsureUpperBound(Expr *CombEUB) {
    559     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    560            "expected loop bound sharing directive");
    561     *std::next(child_begin(), CombinedEnsureUpperBoundOffset) = CombEUB;
    562   }
    563   void setCombinedInit(Expr *CombInit) {
    564     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    565            "expected loop bound sharing directive");
    566     *std::next(child_begin(), CombinedInitOffset) = CombInit;
    567   }
    568   void setCombinedCond(Expr *CombCond) {
    569     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    570            "expected loop bound sharing directive");
    571     *std::next(child_begin(), CombinedConditionOffset) = CombCond;
    572   }
    573   void setCombinedNextLowerBound(Expr *CombNLB) {
    574     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    575            "expected loop bound sharing directive");
    576     *std::next(child_begin(), CombinedNextLowerBoundOffset) = CombNLB;
    577   }
    578   void setCombinedNextUpperBound(Expr *CombNUB) {
    579     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    580            "expected loop bound sharing directive");
    581     *std::next(child_begin(), CombinedNextUpperBoundOffset) = CombNUB;
    582   }
    583   void setCounters(ArrayRef<Expr *> A);
    584   void setPrivateCounters(ArrayRef<Expr *> A);
    585   void setInits(ArrayRef<Expr *> A);
    586   void setUpdates(ArrayRef<Expr *> A);
    587   void setFinals(ArrayRef<Expr *> A);
    588 
    589 public:
    590   /// The expressions built to support OpenMP loops in combined/composite
    591   /// pragmas (e.g. pragma omp distribute parallel for)
    592   struct DistCombinedHelperExprs {
    593     /// DistributeLowerBound - used when composing 'omp distribute' with
    594     /// 'omp for' in a same construct.
    595     Expr *LB;
    596     /// DistributeUpperBound - used when composing 'omp distribute' with
    597     /// 'omp for' in a same construct.
    598     Expr *UB;
    599     /// DistributeEnsureUpperBound - used when composing 'omp distribute'
    600     ///  with 'omp for' in a same construct, EUB depends on DistUB
    601     Expr *EUB;
    602     /// Distribute loop iteration variable init used when composing 'omp
    603     /// distribute'
    604     ///  with 'omp for' in a same construct
    605     Expr *Init;
    606     /// Distribute Loop condition used when composing 'omp distribute'
    607     ///  with 'omp for' in a same construct
    608     Expr *Cond;
    609     /// Update of LowerBound for statically sheduled omp loops for
    610     /// outer loop in combined constructs (e.g. 'distribute parallel for')
    611     Expr *NLB;
    612     /// Update of UpperBound for statically sheduled omp loops for
    613     /// outer loop in combined constructs (e.g. 'distribute parallel for')
    614     Expr *NUB;
    615   };
    616 
    617   /// \brief The expressions built for the OpenMP loop CodeGen for the
    618   /// whole collapsed loop nest.
    619   struct HelperExprs {
    620     /// \brief Loop iteration variable.
    621     Expr *IterationVarRef;
    622     /// \brief Loop last iteration number.
    623     Expr *LastIteration;
    624     /// \brief Loop number of iterations.
    625     Expr *NumIterations;
    626     /// \brief Calculation of last iteration.
    627     Expr *CalcLastIteration;
    628     /// \brief Loop pre-condition.
    629     Expr *PreCond;
    630     /// \brief Loop condition.
    631     Expr *Cond;
    632     /// \brief Loop iteration variable init.
    633     Expr *Init;
    634     /// \brief Loop increment.
    635     Expr *Inc;
    636     /// \brief IsLastIteration - local flag variable passed to runtime.
    637     Expr *IL;
    638     /// \brief LowerBound - local variable passed to runtime.
    639     Expr *LB;
    640     /// \brief UpperBound - local variable passed to runtime.
    641     Expr *UB;
    642     /// \brief Stride - local variable passed to runtime.
    643     Expr *ST;
    644     /// \brief EnsureUpperBound -- expression UB = min(UB, NumIterations).
    645     Expr *EUB;
    646     /// \brief Update of LowerBound for statically sheduled 'omp for' loops.
    647     Expr *NLB;
    648     /// \brief Update of UpperBound for statically sheduled 'omp for' loops.
    649     Expr *NUB;
    650     /// \brief PreviousLowerBound - local variable passed to runtime in the
    651     /// enclosing schedule or null if that does not apply.
    652     Expr *PrevLB;
    653     /// \brief PreviousUpperBound - local variable passed to runtime in the
    654     /// enclosing schedule or null if that does not apply.
    655     Expr *PrevUB;
    656     /// \brief DistInc - increment expression for distribute loop when found
    657     /// combined with a further loop level (e.g. in 'distribute parallel for')
    658     /// expression IV = IV + ST
    659     Expr *DistInc;
    660     /// \brief PrevEUB - expression similar to EUB but to be used when loop
    661     /// scheduling uses PrevLB and PrevUB (e.g.  in 'distribute parallel for'
    662     /// when ensuring that the UB is either the calculated UB by the runtime or
    663     /// the end of the assigned distribute chunk)
    664     /// expression UB = min (UB, PrevUB)
    665     Expr *PrevEUB;
    666     /// \brief Counters Loop counters.
    667     SmallVector<Expr *, 4> Counters;
    668     /// \brief PrivateCounters Loop counters.
    669     SmallVector<Expr *, 4> PrivateCounters;
    670     /// \brief Expressions for loop counters inits for CodeGen.
    671     SmallVector<Expr *, 4> Inits;
    672     /// \brief Expressions for loop counters update for CodeGen.
    673     SmallVector<Expr *, 4> Updates;
    674     /// \brief Final loop counter values for GodeGen.
    675     SmallVector<Expr *, 4> Finals;
    676     /// Init statement for all captured expressions.
    677     Stmt *PreInits;
    678 
    679     /// Expressions used when combining OpenMP loop pragmas
    680     DistCombinedHelperExprs DistCombinedFields;
    681 
    682     /// \brief Check if all the expressions are built (does not check the
    683     /// worksharing ones).
    684     bool builtAll() {
    685       return IterationVarRef != nullptr && LastIteration != nullptr &&
    686              NumIterations != nullptr && PreCond != nullptr &&
    687              Cond != nullptr && Init != nullptr && Inc != nullptr;
    688     }
    689 
    690     /// \brief Initialize all the fields to null.
    691     /// \param Size Number of elements in the counters/finals/updates arrays.
    692     void clear(unsigned Size) {
    693       IterationVarRef = nullptr;
    694       LastIteration = nullptr;
    695       CalcLastIteration = nullptr;
    696       PreCond = nullptr;
    697       Cond = nullptr;
    698       Init = nullptr;
    699       Inc = nullptr;
    700       IL = nullptr;
    701       LB = nullptr;
    702       UB = nullptr;
    703       ST = nullptr;
    704       EUB = nullptr;
    705       NLB = nullptr;
    706       NUB = nullptr;
    707       NumIterations = nullptr;
    708       PrevLB = nullptr;
    709       PrevUB = nullptr;
    710       DistInc = nullptr;
    711       PrevEUB = nullptr;
    712       Counters.resize(Size);
    713       PrivateCounters.resize(Size);
    714       Inits.resize(Size);
    715       Updates.resize(Size);
    716       Finals.resize(Size);
    717       for (unsigned i = 0; i < Size; ++i) {
    718         Counters[i] = nullptr;
    719         PrivateCounters[i] = nullptr;
    720         Inits[i] = nullptr;
    721         Updates[i] = nullptr;
    722         Finals[i] = nullptr;
    723       }
    724       PreInits = nullptr;
    725       DistCombinedFields.LB = nullptr;
    726       DistCombinedFields.UB = nullptr;
    727       DistCombinedFields.EUB = nullptr;
    728       DistCombinedFields.Init = nullptr;
    729       DistCombinedFields.Cond = nullptr;
    730       DistCombinedFields.NLB = nullptr;
    731       DistCombinedFields.NUB = nullptr;
    732     }
    733   };
    734 
    735   /// \brief Get number of collapsed loops.
    736   unsigned getCollapsedNumber() const { return CollapsedNum; }
    737 
    738   Expr *getIterationVariable() const {
    739     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    740         *std::next(child_begin(), IterationVariableOffset)));
    741   }
    742   Expr *getLastIteration() const {
    743     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    744         *std::next(child_begin(), LastIterationOffset)));
    745   }
    746   Expr *getCalcLastIteration() const {
    747     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    748         *std::next(child_begin(), CalcLastIterationOffset)));
    749   }
    750   Expr *getPreCond() const {
    751     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    752         *std::next(child_begin(), PreConditionOffset)));
    753   }
    754   Expr *getCond() const {
    755     return const_cast<Expr *>(
    756         reinterpret_cast<const Expr *>(*std::next(child_begin(), CondOffset)));
    757   }
    758   Expr *getInit() const {
    759     return const_cast<Expr *>(
    760         reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset)));
    761   }
    762   Expr *getInc() const {
    763     return const_cast<Expr *>(
    764         reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset)));
    765   }
    766   const Stmt *getPreInits() const {
    767     return *std::next(child_begin(), PreInitsOffset);
    768   }
    769   Stmt *getPreInits() { return *std::next(child_begin(), PreInitsOffset); }
    770   Expr *getIsLastIterVariable() const {
    771     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    772             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    773             isOpenMPDistributeDirective(getDirectiveKind())) &&
    774            "expected worksharing loop directive");
    775     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    776         *std::next(child_begin(), IsLastIterVariableOffset)));
    777   }
    778   Expr *getLowerBoundVariable() const {
    779     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    780             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    781             isOpenMPDistributeDirective(getDirectiveKind())) &&
    782            "expected worksharing loop directive");
    783     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    784         *std::next(child_begin(), LowerBoundVariableOffset)));
    785   }
    786   Expr *getUpperBoundVariable() const {
    787     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    788             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    789             isOpenMPDistributeDirective(getDirectiveKind())) &&
    790            "expected worksharing loop directive");
    791     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    792         *std::next(child_begin(), UpperBoundVariableOffset)));
    793   }
    794   Expr *getStrideVariable() const {
    795     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    796             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    797             isOpenMPDistributeDirective(getDirectiveKind())) &&
    798            "expected worksharing loop directive");
    799     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    800         *std::next(child_begin(), StrideVariableOffset)));
    801   }
    802   Expr *getEnsureUpperBound() const {
    803     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    804             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    805             isOpenMPDistributeDirective(getDirectiveKind())) &&
    806            "expected worksharing loop directive");
    807     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    808         *std::next(child_begin(), EnsureUpperBoundOffset)));
    809   }
    810   Expr *getNextLowerBound() const {
    811     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    812             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    813             isOpenMPDistributeDirective(getDirectiveKind())) &&
    814            "expected worksharing loop directive");
    815     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    816         *std::next(child_begin(), NextLowerBoundOffset)));
    817   }
    818   Expr *getNextUpperBound() const {
    819     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    820             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    821             isOpenMPDistributeDirective(getDirectiveKind())) &&
    822            "expected worksharing loop directive");
    823     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    824         *std::next(child_begin(), NextUpperBoundOffset)));
    825   }
    826   Expr *getNumIterations() const {
    827     assert((isOpenMPWorksharingDirective(getDirectiveKind()) ||
    828             isOpenMPTaskLoopDirective(getDirectiveKind()) ||
    829             isOpenMPDistributeDirective(getDirectiveKind())) &&
    830            "expected worksharing loop directive");
    831     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    832         *std::next(child_begin(), NumIterationsOffset)));
    833   }
    834   Expr *getPrevLowerBoundVariable() const {
    835     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    836            "expected loop bound sharing directive");
    837     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    838         *std::next(child_begin(), PrevLowerBoundVariableOffset)));
    839   }
    840   Expr *getPrevUpperBoundVariable() const {
    841     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    842            "expected loop bound sharing directive");
    843     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    844         *std::next(child_begin(), PrevUpperBoundVariableOffset)));
    845   }
    846   Expr *getDistInc() const {
    847     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    848            "expected loop bound sharing directive");
    849     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    850         *std::next(child_begin(), DistIncOffset)));
    851   }
    852   Expr *getPrevEnsureUpperBound() const {
    853     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    854            "expected loop bound sharing directive");
    855     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    856         *std::next(child_begin(), PrevEnsureUpperBoundOffset)));
    857   }
    858   Expr *getCombinedLowerBoundVariable() const {
    859     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    860            "expected loop bound sharing directive");
    861     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    862         *std::next(child_begin(), CombinedLowerBoundVariableOffset)));
    863   }
    864   Expr *getCombinedUpperBoundVariable() const {
    865     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    866            "expected loop bound sharing directive");
    867     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    868         *std::next(child_begin(), CombinedUpperBoundVariableOffset)));
    869   }
    870   Expr *getCombinedEnsureUpperBound() const {
    871     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    872            "expected loop bound sharing directive");
    873     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    874         *std::next(child_begin(), CombinedEnsureUpperBoundOffset)));
    875   }
    876   Expr *getCombinedInit() const {
    877     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    878            "expected loop bound sharing directive");
    879     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    880         *std::next(child_begin(), CombinedInitOffset)));
    881   }
    882   Expr *getCombinedCond() const {
    883     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    884            "expected loop bound sharing directive");
    885     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    886         *std::next(child_begin(), CombinedConditionOffset)));
    887   }
    888   Expr *getCombinedNextLowerBound() const {
    889     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    890            "expected loop bound sharing directive");
    891     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    892         *std::next(child_begin(), CombinedNextLowerBoundOffset)));
    893   }
    894   Expr *getCombinedNextUpperBound() const {
    895     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) &&
    896            "expected loop bound sharing directive");
    897     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    898         *std::next(child_begin(), CombinedNextUpperBoundOffset)));
    899   }
    900   const Stmt *getBody() const {
    901     // This relies on the loop form is already checked by Sema.
    902     Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
    903     Body = cast<ForStmt>(Body)->getBody();
    904     for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
    905       Body = Body->IgnoreContainers();
    906       Body = cast<ForStmt>(Body)->getBody();
    907     }
    908     return Body;
    909   }
    910 
    911   ArrayRef<Expr *> counters() { return getCounters(); }
    912 
    913   ArrayRef<Expr *> counters() const {
    914     return const_cast<OMPLoopDirective *>(this)->getCounters();
    915   }
    916 
    917   ArrayRef<Expr *> private_counters() { return getPrivateCounters(); }
    918 
    919   ArrayRef<Expr *> private_counters() const {
    920     return const_cast<OMPLoopDirective *>(this)->getPrivateCounters();
    921   }
    922 
    923   ArrayRef<Expr *> inits() { return getInits(); }
    924 
    925   ArrayRef<Expr *> inits() const {
    926     return const_cast<OMPLoopDirective *>(this)->getInits();
    927   }
    928 
    929   ArrayRef<Expr *> updates() { return getUpdates(); }
    930 
    931   ArrayRef<Expr *> updates() const {
    932     return const_cast<OMPLoopDirective *>(this)->getUpdates();
    933   }
    934 
    935   ArrayRef<Expr *> finals() { return getFinals(); }
    936 
    937   ArrayRef<Expr *> finals() const {
    938     return const_cast<OMPLoopDirective *>(this)->getFinals();
    939   }
    940 
    941   static bool classof(const Stmt *T) {
    942     return T->getStmtClass() == OMPSimdDirectiveClass ||
    943            T->getStmtClass() == OMPForDirectiveClass ||
    944            T->getStmtClass() == OMPForSimdDirectiveClass ||
    945            T->getStmtClass() == OMPParallelForDirectiveClass ||
    946            T->getStmtClass() == OMPParallelForSimdDirectiveClass ||
    947            T->getStmtClass() == OMPTaskLoopDirectiveClass ||
    948            T->getStmtClass() == OMPTaskLoopSimdDirectiveClass ||
    949            T->getStmtClass() == OMPDistributeDirectiveClass ||
    950            T->getStmtClass() == OMPTargetParallelForDirectiveClass ||
    951            T->getStmtClass() == OMPDistributeParallelForDirectiveClass ||
    952            T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass ||
    953            T->getStmtClass() == OMPDistributeSimdDirectiveClass ||
    954            T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass ||
    955            T->getStmtClass() == OMPTargetSimdDirectiveClass ||
    956            T->getStmtClass() == OMPTeamsDistributeDirectiveClass ||
    957            T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass ||
    958            T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass ||
    959            T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass;
    960   }
    961 };
    962 
    963 /// \brief This represents '#pragma omp simd' directive.
    964 ///
    965 /// \code
    966 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
    967 /// \endcode
    968 /// In this example directive '#pragma omp simd' has clauses 'private'
    969 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
    970 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
    971 ///
    972 class OMPSimdDirective : public OMPLoopDirective {
    973   friend class ASTStmtReader;
    974   /// \brief Build directive with the given start and end location.
    975   ///
    976   /// \param StartLoc Starting location of the directive kind.
    977   /// \param EndLoc Ending location of the directive.
    978   /// \param CollapsedNum Number of collapsed nested loops.
    979   /// \param NumClauses Number of clauses.
    980   ///
    981   OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    982                    unsigned CollapsedNum, unsigned NumClauses)
    983       : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
    984                          EndLoc, CollapsedNum, NumClauses) {}
    985 
    986   /// \brief Build an empty directive.
    987   ///
    988   /// \param CollapsedNum Number of collapsed nested loops.
    989   /// \param NumClauses Number of clauses.
    990   ///
    991   explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
    992       : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd,
    993                          SourceLocation(), SourceLocation(), CollapsedNum,
    994                          NumClauses) {}
    995 
    996 public:
    997   /// \brief Creates directive with a list of \a Clauses.
    998   ///
    999   /// \param C AST context.
   1000   /// \param StartLoc Starting location of the directive kind.
   1001   /// \param EndLoc Ending Location of the directive.
   1002   /// \param CollapsedNum Number of collapsed loops.
   1003   /// \param Clauses List of clauses.
   1004   /// \param AssociatedStmt Statement, associated with the directive.
   1005   /// \param Exprs Helper expressions for CodeGen.
   1006   ///
   1007   static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
   1008                                   SourceLocation EndLoc, unsigned CollapsedNum,
   1009                                   ArrayRef<OMPClause *> Clauses,
   1010                                   Stmt *AssociatedStmt,
   1011                                   const HelperExprs &Exprs);
   1012 
   1013   /// \brief Creates an empty directive with the place
   1014   /// for \a NumClauses clauses.
   1015   ///
   1016   /// \param C AST context.
   1017   /// \param CollapsedNum Number of collapsed nested loops.
   1018   /// \param NumClauses Number of clauses.
   1019   ///
   1020   static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
   1021                                        unsigned CollapsedNum, EmptyShell);
   1022 
   1023   static bool classof(const Stmt *T) {
   1024     return T->getStmtClass() == OMPSimdDirectiveClass;
   1025   }
   1026 };
   1027 
   1028 /// \brief This represents '#pragma omp for' directive.
   1029 ///
   1030 /// \code
   1031 /// #pragma omp for private(a,b) reduction(+:c,d)
   1032 /// \endcode
   1033 /// In this example directive '#pragma omp for' has clauses 'private' with the
   1034 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
   1035 /// and 'd'.
   1036 ///
   1037 class OMPForDirective : public OMPLoopDirective {
   1038   friend class ASTStmtReader;
   1039 
   1040   /// \brief true if current directive has inner cancel directive.
   1041   bool HasCancel;
   1042 
   1043   /// \brief Build directive with the given start and end location.
   1044   ///
   1045   /// \param StartLoc Starting location of the directive kind.
   1046   /// \param EndLoc Ending location of the directive.
   1047   /// \param CollapsedNum Number of collapsed nested loops.
   1048   /// \param NumClauses Number of clauses.
   1049   ///
   1050   OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1051                   unsigned CollapsedNum, unsigned NumClauses)
   1052       : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc,
   1053                          CollapsedNum, NumClauses),
   1054         HasCancel(false) {}
   1055 
   1056   /// \brief Build an empty directive.
   1057   ///
   1058   /// \param CollapsedNum Number of collapsed nested loops.
   1059   /// \param NumClauses Number of clauses.
   1060   ///
   1061   explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
   1062       : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(),
   1063                          SourceLocation(), CollapsedNum, NumClauses),
   1064         HasCancel(false) {}
   1065 
   1066   /// \brief Set cancel state.
   1067   void setHasCancel(bool Has) { HasCancel = Has; }
   1068 
   1069 public:
   1070   /// \brief Creates directive with a list of \a Clauses.
   1071   ///
   1072   /// \param C AST context.
   1073   /// \param StartLoc Starting location of the directive kind.
   1074   /// \param EndLoc Ending Location of the directive.
   1075   /// \param CollapsedNum Number of collapsed loops.
   1076   /// \param Clauses List of clauses.
   1077   /// \param AssociatedStmt Statement, associated with the directive.
   1078   /// \param Exprs Helper expressions for CodeGen.
   1079   /// \param HasCancel true if current directive has inner cancel directive.
   1080   ///
   1081   static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
   1082                                  SourceLocation EndLoc, unsigned CollapsedNum,
   1083                                  ArrayRef<OMPClause *> Clauses,
   1084                                  Stmt *AssociatedStmt, const HelperExprs &Exprs,
   1085                                  bool HasCancel);
   1086 
   1087   /// \brief Creates an empty directive with the place
   1088   /// for \a NumClauses clauses.
   1089   ///
   1090   /// \param C AST context.
   1091   /// \param CollapsedNum Number of collapsed nested loops.
   1092   /// \param NumClauses Number of clauses.
   1093   ///
   1094   static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
   1095                                       unsigned CollapsedNum, EmptyShell);
   1096 
   1097   /// \brief Return true if current directive has inner cancel directive.
   1098   bool hasCancel() const { return HasCancel; }
   1099 
   1100   static bool classof(const Stmt *T) {
   1101     return T->getStmtClass() == OMPForDirectiveClass;
   1102   }
   1103 };
   1104 
   1105 /// \brief This represents '#pragma omp for simd' directive.
   1106 ///
   1107 /// \code
   1108 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
   1109 /// \endcode
   1110 /// In this example directive '#pragma omp for simd' has clauses 'private'
   1111 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
   1112 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
   1113 ///
   1114 class OMPForSimdDirective : public OMPLoopDirective {
   1115   friend class ASTStmtReader;
   1116   /// \brief Build directive with the given start and end location.
   1117   ///
   1118   /// \param StartLoc Starting location of the directive kind.
   1119   /// \param EndLoc Ending location of the directive.
   1120   /// \param CollapsedNum Number of collapsed nested loops.
   1121   /// \param NumClauses Number of clauses.
   1122   ///
   1123   OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1124                       unsigned CollapsedNum, unsigned NumClauses)
   1125       : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
   1126                          StartLoc, EndLoc, CollapsedNum, NumClauses) {}
   1127 
   1128   /// \brief Build an empty directive.
   1129   ///
   1130   /// \param CollapsedNum Number of collapsed nested loops.
   1131   /// \param NumClauses Number of clauses.
   1132   ///
   1133   explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
   1134       : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
   1135                          SourceLocation(), SourceLocation(), CollapsedNum,
   1136                          NumClauses) {}
   1137 
   1138 public:
   1139   /// \brief Creates directive with a list of \a Clauses.
   1140   ///
   1141   /// \param C AST context.
   1142   /// \param StartLoc Starting location of the directive kind.
   1143   /// \param EndLoc Ending Location of the directive.
   1144   /// \param CollapsedNum Number of collapsed loops.
   1145   /// \param Clauses List of clauses.
   1146   /// \param AssociatedStmt Statement, associated with the directive.
   1147   /// \param Exprs Helper expressions for CodeGen.
   1148   ///
   1149   static OMPForSimdDirective *
   1150   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1151          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   1152          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   1153 
   1154   /// \brief Creates an empty directive with the place
   1155   /// for \a NumClauses clauses.
   1156   ///
   1157   /// \param C AST context.
   1158   /// \param CollapsedNum Number of collapsed nested loops.
   1159   /// \param NumClauses Number of clauses.
   1160   ///
   1161   static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
   1162                                           unsigned NumClauses,
   1163                                           unsigned CollapsedNum, EmptyShell);
   1164 
   1165   static bool classof(const Stmt *T) {
   1166     return T->getStmtClass() == OMPForSimdDirectiveClass;
   1167   }
   1168 };
   1169 
   1170 /// \brief This represents '#pragma omp sections' directive.
   1171 ///
   1172 /// \code
   1173 /// #pragma omp sections private(a,b) reduction(+:c,d)
   1174 /// \endcode
   1175 /// In this example directive '#pragma omp sections' has clauses 'private' with
   1176 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
   1177 /// 'c' and 'd'.
   1178 ///
   1179 class OMPSectionsDirective : public OMPExecutableDirective {
   1180   friend class ASTStmtReader;
   1181 
   1182   /// \brief true if current directive has inner cancel directive.
   1183   bool HasCancel;
   1184 
   1185   /// \brief Build directive with the given start and end location.
   1186   ///
   1187   /// \param StartLoc Starting location of the directive kind.
   1188   /// \param EndLoc Ending location of the directive.
   1189   /// \param NumClauses Number of clauses.
   1190   ///
   1191   OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1192                        unsigned NumClauses)
   1193       : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
   1194                                StartLoc, EndLoc, NumClauses, 1),
   1195         HasCancel(false) {}
   1196 
   1197   /// \brief Build an empty directive.
   1198   ///
   1199   /// \param NumClauses Number of clauses.
   1200   ///
   1201   explicit OMPSectionsDirective(unsigned NumClauses)
   1202       : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
   1203                                SourceLocation(), SourceLocation(), NumClauses,
   1204                                1),
   1205         HasCancel(false) {}
   1206 
   1207   /// \brief Set cancel state.
   1208   void setHasCancel(bool Has) { HasCancel = Has; }
   1209 
   1210 public:
   1211   /// \brief Creates directive with a list of \a Clauses.
   1212   ///
   1213   /// \param C AST context.
   1214   /// \param StartLoc Starting location of the directive kind.
   1215   /// \param EndLoc Ending Location of the directive.
   1216   /// \param Clauses List of clauses.
   1217   /// \param AssociatedStmt Statement, associated with the directive.
   1218   /// \param HasCancel true if current directive has inner directive.
   1219   ///
   1220   static OMPSectionsDirective *
   1221   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1222          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
   1223 
   1224   /// \brief Creates an empty directive with the place for \a NumClauses
   1225   /// clauses.
   1226   ///
   1227   /// \param C AST context.
   1228   /// \param NumClauses Number of clauses.
   1229   ///
   1230   static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
   1231                                            unsigned NumClauses, EmptyShell);
   1232 
   1233   /// \brief Return true if current directive has inner cancel directive.
   1234   bool hasCancel() const { return HasCancel; }
   1235 
   1236   static bool classof(const Stmt *T) {
   1237     return T->getStmtClass() == OMPSectionsDirectiveClass;
   1238   }
   1239 };
   1240 
   1241 /// \brief This represents '#pragma omp section' directive.
   1242 ///
   1243 /// \code
   1244 /// #pragma omp section
   1245 /// \endcode
   1246 ///
   1247 class OMPSectionDirective : public OMPExecutableDirective {
   1248   friend class ASTStmtReader;
   1249 
   1250   /// \brief true if current directive has inner cancel directive.
   1251   bool HasCancel;
   1252 
   1253   /// \brief Build directive with the given start and end location.
   1254   ///
   1255   /// \param StartLoc Starting location of the directive kind.
   1256   /// \param EndLoc Ending location of the directive.
   1257   ///
   1258   OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1259       : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
   1260                                StartLoc, EndLoc, 0, 1),
   1261         HasCancel(false) {}
   1262 
   1263   /// \brief Build an empty directive.
   1264   ///
   1265   explicit OMPSectionDirective()
   1266       : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
   1267                                SourceLocation(), SourceLocation(), 0, 1),
   1268         HasCancel(false) {}
   1269 
   1270 public:
   1271   /// \brief Creates directive.
   1272   ///
   1273   /// \param C AST context.
   1274   /// \param StartLoc Starting location of the directive kind.
   1275   /// \param EndLoc Ending Location of the directive.
   1276   /// \param AssociatedStmt Statement, associated with the directive.
   1277   /// \param HasCancel true if current directive has inner directive.
   1278   ///
   1279   static OMPSectionDirective *Create(const ASTContext &C,
   1280                                      SourceLocation StartLoc,
   1281                                      SourceLocation EndLoc,
   1282                                      Stmt *AssociatedStmt, bool HasCancel);
   1283 
   1284   /// \brief Creates an empty directive.
   1285   ///
   1286   /// \param C AST context.
   1287   ///
   1288   static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1289 
   1290   /// \brief Set cancel state.
   1291   void setHasCancel(bool Has) { HasCancel = Has; }
   1292 
   1293   /// \brief Return true if current directive has inner cancel directive.
   1294   bool hasCancel() const { return HasCancel; }
   1295 
   1296   static bool classof(const Stmt *T) {
   1297     return T->getStmtClass() == OMPSectionDirectiveClass;
   1298   }
   1299 };
   1300 
   1301 /// \brief This represents '#pragma omp single' directive.
   1302 ///
   1303 /// \code
   1304 /// #pragma omp single private(a,b) copyprivate(c,d)
   1305 /// \endcode
   1306 /// In this example directive '#pragma omp single' has clauses 'private' with
   1307 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
   1308 ///
   1309 class OMPSingleDirective : public OMPExecutableDirective {
   1310   friend class ASTStmtReader;
   1311   /// \brief Build directive with the given start and end location.
   1312   ///
   1313   /// \param StartLoc Starting location of the directive kind.
   1314   /// \param EndLoc Ending location of the directive.
   1315   /// \param NumClauses Number of clauses.
   1316   ///
   1317   OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1318                      unsigned NumClauses)
   1319       : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
   1320                                StartLoc, EndLoc, NumClauses, 1) {}
   1321 
   1322   /// \brief Build an empty directive.
   1323   ///
   1324   /// \param NumClauses Number of clauses.
   1325   ///
   1326   explicit OMPSingleDirective(unsigned NumClauses)
   1327       : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
   1328                                SourceLocation(), SourceLocation(), NumClauses,
   1329                                1) {}
   1330 
   1331 public:
   1332   /// \brief Creates directive with a list of \a Clauses.
   1333   ///
   1334   /// \param C AST context.
   1335   /// \param StartLoc Starting location of the directive kind.
   1336   /// \param EndLoc Ending Location of the directive.
   1337   /// \param Clauses List of clauses.
   1338   /// \param AssociatedStmt Statement, associated with the directive.
   1339   ///
   1340   static OMPSingleDirective *
   1341   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1342          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   1343 
   1344   /// \brief Creates an empty directive with the place for \a NumClauses
   1345   /// clauses.
   1346   ///
   1347   /// \param C AST context.
   1348   /// \param NumClauses Number of clauses.
   1349   ///
   1350   static OMPSingleDirective *CreateEmpty(const ASTContext &C,
   1351                                          unsigned NumClauses, EmptyShell);
   1352 
   1353   static bool classof(const Stmt *T) {
   1354     return T->getStmtClass() == OMPSingleDirectiveClass;
   1355   }
   1356 };
   1357 
   1358 /// \brief This represents '#pragma omp master' directive.
   1359 ///
   1360 /// \code
   1361 /// #pragma omp master
   1362 /// \endcode
   1363 ///
   1364 class OMPMasterDirective : public OMPExecutableDirective {
   1365   friend class ASTStmtReader;
   1366   /// \brief Build directive with the given start and end location.
   1367   ///
   1368   /// \param StartLoc Starting location of the directive kind.
   1369   /// \param EndLoc Ending location of the directive.
   1370   ///
   1371   OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1372       : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
   1373                                StartLoc, EndLoc, 0, 1) {}
   1374 
   1375   /// \brief Build an empty directive.
   1376   ///
   1377   explicit OMPMasterDirective()
   1378       : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
   1379                                SourceLocation(), SourceLocation(), 0, 1) {}
   1380 
   1381 public:
   1382   /// \brief Creates directive.
   1383   ///
   1384   /// \param C AST context.
   1385   /// \param StartLoc Starting location of the directive kind.
   1386   /// \param EndLoc Ending Location of the directive.
   1387   /// \param AssociatedStmt Statement, associated with the directive.
   1388   ///
   1389   static OMPMasterDirective *Create(const ASTContext &C,
   1390                                     SourceLocation StartLoc,
   1391                                     SourceLocation EndLoc,
   1392                                     Stmt *AssociatedStmt);
   1393 
   1394   /// \brief Creates an empty directive.
   1395   ///
   1396   /// \param C AST context.
   1397   ///
   1398   static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1399 
   1400   static bool classof(const Stmt *T) {
   1401     return T->getStmtClass() == OMPMasterDirectiveClass;
   1402   }
   1403 };
   1404 
   1405 /// \brief This represents '#pragma omp critical' directive.
   1406 ///
   1407 /// \code
   1408 /// #pragma omp critical
   1409 /// \endcode
   1410 ///
   1411 class OMPCriticalDirective : public OMPExecutableDirective {
   1412   friend class ASTStmtReader;
   1413   /// \brief Name of the directive.
   1414   DeclarationNameInfo DirName;
   1415   /// \brief Build directive with the given start and end location.
   1416   ///
   1417   /// \param Name Name of the directive.
   1418   /// \param StartLoc Starting location of the directive kind.
   1419   /// \param EndLoc Ending location of the directive.
   1420   /// \param NumClauses Number of clauses.
   1421   ///
   1422   OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
   1423                        SourceLocation EndLoc, unsigned NumClauses)
   1424       : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
   1425                                StartLoc, EndLoc, NumClauses, 1),
   1426         DirName(Name) {}
   1427 
   1428   /// \brief Build an empty directive.
   1429   ///
   1430   /// \param NumClauses Number of clauses.
   1431   ///
   1432   explicit OMPCriticalDirective(unsigned NumClauses)
   1433       : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
   1434                                SourceLocation(), SourceLocation(), NumClauses,
   1435                                1),
   1436         DirName() {}
   1437 
   1438   /// \brief Set name of the directive.
   1439   ///
   1440   /// \param Name Name of the directive.
   1441   ///
   1442   void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
   1443 
   1444 public:
   1445   /// \brief Creates directive.
   1446   ///
   1447   /// \param C AST context.
   1448   /// \param Name Name of the directive.
   1449   /// \param StartLoc Starting location of the directive kind.
   1450   /// \param EndLoc Ending Location of the directive.
   1451   /// \param Clauses List of clauses.
   1452   /// \param AssociatedStmt Statement, associated with the directive.
   1453   ///
   1454   static OMPCriticalDirective *
   1455   Create(const ASTContext &C, const DeclarationNameInfo &Name,
   1456          SourceLocation StartLoc, SourceLocation EndLoc,
   1457          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   1458 
   1459   /// \brief Creates an empty directive.
   1460   ///
   1461   /// \param C AST context.
   1462   /// \param NumClauses Number of clauses.
   1463   ///
   1464   static OMPCriticalDirective *CreateEmpty(const ASTContext &C,
   1465                                            unsigned NumClauses, EmptyShell);
   1466 
   1467   /// \brief Return name of the directive.
   1468   ///
   1469   DeclarationNameInfo getDirectiveName() const { return DirName; }
   1470 
   1471   static bool classof(const Stmt *T) {
   1472     return T->getStmtClass() == OMPCriticalDirectiveClass;
   1473   }
   1474 };
   1475 
   1476 /// \brief This represents '#pragma omp parallel for' directive.
   1477 ///
   1478 /// \code
   1479 /// #pragma omp parallel for private(a,b) reduction(+:c,d)
   1480 /// \endcode
   1481 /// In this example directive '#pragma omp parallel for' has clauses 'private'
   1482 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
   1483 /// variables 'c' and 'd'.
   1484 ///
   1485 class OMPParallelForDirective : public OMPLoopDirective {
   1486   friend class ASTStmtReader;
   1487 
   1488   /// \brief true if current region has inner cancel directive.
   1489   bool HasCancel;
   1490 
   1491   /// \brief Build directive with the given start and end location.
   1492   ///
   1493   /// \param StartLoc Starting location of the directive kind.
   1494   /// \param EndLoc Ending location of the directive.
   1495   /// \param CollapsedNum Number of collapsed nested loops.
   1496   /// \param NumClauses Number of clauses.
   1497   ///
   1498   OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1499                           unsigned CollapsedNum, unsigned NumClauses)
   1500       : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
   1501                          StartLoc, EndLoc, CollapsedNum, NumClauses),
   1502         HasCancel(false) {}
   1503 
   1504   /// \brief Build an empty directive.
   1505   ///
   1506   /// \param CollapsedNum Number of collapsed nested loops.
   1507   /// \param NumClauses Number of clauses.
   1508   ///
   1509   explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
   1510       : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
   1511                          SourceLocation(), SourceLocation(), CollapsedNum,
   1512                          NumClauses),
   1513         HasCancel(false) {}
   1514 
   1515   /// \brief Set cancel state.
   1516   void setHasCancel(bool Has) { HasCancel = Has; }
   1517 
   1518 public:
   1519   /// \brief Creates directive with a list of \a Clauses.
   1520   ///
   1521   /// \param C AST context.
   1522   /// \param StartLoc Starting location of the directive kind.
   1523   /// \param EndLoc Ending Location of the directive.
   1524   /// \param CollapsedNum Number of collapsed loops.
   1525   /// \param Clauses List of clauses.
   1526   /// \param AssociatedStmt Statement, associated with the directive.
   1527   /// \param Exprs Helper expressions for CodeGen.
   1528   /// \param HasCancel true if current directive has inner cancel directive.
   1529   ///
   1530   static OMPParallelForDirective *
   1531   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1532          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   1533          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
   1534 
   1535   /// \brief Creates an empty directive with the place
   1536   /// for \a NumClauses clauses.
   1537   ///
   1538   /// \param C AST context.
   1539   /// \param CollapsedNum Number of collapsed nested loops.
   1540   /// \param NumClauses Number of clauses.
   1541   ///
   1542   static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
   1543                                               unsigned NumClauses,
   1544                                               unsigned CollapsedNum,
   1545                                               EmptyShell);
   1546 
   1547   /// \brief Return true if current directive has inner cancel directive.
   1548   bool hasCancel() const { return HasCancel; }
   1549 
   1550   static bool classof(const Stmt *T) {
   1551     return T->getStmtClass() == OMPParallelForDirectiveClass;
   1552   }
   1553 };
   1554 
   1555 /// \brief This represents '#pragma omp parallel for simd' directive.
   1556 ///
   1557 /// \code
   1558 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
   1559 /// \endcode
   1560 /// In this example directive '#pragma omp parallel for simd' has clauses
   1561 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
   1562 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and
   1563 /// 'd'.
   1564 ///
   1565 class OMPParallelForSimdDirective : public OMPLoopDirective {
   1566   friend class ASTStmtReader;
   1567   /// \brief Build directive with the given start and end location.
   1568   ///
   1569   /// \param StartLoc Starting location of the directive kind.
   1570   /// \param EndLoc Ending location of the directive.
   1571   /// \param CollapsedNum Number of collapsed nested loops.
   1572   /// \param NumClauses Number of clauses.
   1573   ///
   1574   OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1575                               unsigned CollapsedNum, unsigned NumClauses)
   1576       : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
   1577                          OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum,
   1578                          NumClauses) {}
   1579 
   1580   /// \brief Build an empty directive.
   1581   ///
   1582   /// \param CollapsedNum Number of collapsed nested loops.
   1583   /// \param NumClauses Number of clauses.
   1584   ///
   1585   explicit OMPParallelForSimdDirective(unsigned CollapsedNum,
   1586                                        unsigned NumClauses)
   1587       : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
   1588                          OMPD_parallel_for_simd, SourceLocation(),
   1589                          SourceLocation(), CollapsedNum, NumClauses) {}
   1590 
   1591 public:
   1592   /// \brief Creates directive with a list of \a Clauses.
   1593   ///
   1594   /// \param C AST context.
   1595   /// \param StartLoc Starting location of the directive kind.
   1596   /// \param EndLoc Ending Location of the directive.
   1597   /// \param CollapsedNum Number of collapsed loops.
   1598   /// \param Clauses List of clauses.
   1599   /// \param AssociatedStmt Statement, associated with the directive.
   1600   /// \param Exprs Helper expressions for CodeGen.
   1601   ///
   1602   static OMPParallelForSimdDirective *
   1603   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1604          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   1605          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   1606 
   1607   /// \brief Creates an empty directive with the place
   1608   /// for \a NumClauses clauses.
   1609   ///
   1610   /// \param C AST context.
   1611   /// \param CollapsedNum Number of collapsed nested loops.
   1612   /// \param NumClauses Number of clauses.
   1613   ///
   1614   static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
   1615                                                   unsigned NumClauses,
   1616                                                   unsigned CollapsedNum,
   1617                                                   EmptyShell);
   1618 
   1619   static bool classof(const Stmt *T) {
   1620     return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
   1621   }
   1622 };
   1623 
   1624 /// \brief This represents '#pragma omp parallel sections' directive.
   1625 ///
   1626 /// \code
   1627 /// #pragma omp parallel sections private(a,b) reduction(+:c,d)
   1628 /// \endcode
   1629 /// In this example directive '#pragma omp parallel sections' has clauses
   1630 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
   1631 /// and variables 'c' and 'd'.
   1632 ///
   1633 class OMPParallelSectionsDirective : public OMPExecutableDirective {
   1634   friend class ASTStmtReader;
   1635 
   1636   /// \brief true if current directive has inner cancel directive.
   1637   bool HasCancel;
   1638 
   1639   /// \brief Build directive with the given start and end location.
   1640   ///
   1641   /// \param StartLoc Starting location of the directive kind.
   1642   /// \param EndLoc Ending location of the directive.
   1643   /// \param NumClauses Number of clauses.
   1644   ///
   1645   OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1646                                unsigned NumClauses)
   1647       : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
   1648                                OMPD_parallel_sections, StartLoc, EndLoc,
   1649                                NumClauses, 1),
   1650         HasCancel(false) {}
   1651 
   1652   /// \brief Build an empty directive.
   1653   ///
   1654   /// \param NumClauses Number of clauses.
   1655   ///
   1656   explicit OMPParallelSectionsDirective(unsigned NumClauses)
   1657       : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
   1658                                OMPD_parallel_sections, SourceLocation(),
   1659                                SourceLocation(), NumClauses, 1),
   1660         HasCancel(false) {}
   1661 
   1662   /// \brief Set cancel state.
   1663   void setHasCancel(bool Has) { HasCancel = Has; }
   1664 
   1665 public:
   1666   /// \brief Creates directive with a list of \a Clauses.
   1667   ///
   1668   /// \param C AST context.
   1669   /// \param StartLoc Starting location of the directive kind.
   1670   /// \param EndLoc Ending Location of the directive.
   1671   /// \param Clauses List of clauses.
   1672   /// \param AssociatedStmt Statement, associated with the directive.
   1673   /// \param HasCancel true if current directive has inner cancel directive.
   1674   ///
   1675   static OMPParallelSectionsDirective *
   1676   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1677          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel);
   1678 
   1679   /// \brief Creates an empty directive with the place for \a NumClauses
   1680   /// clauses.
   1681   ///
   1682   /// \param C AST context.
   1683   /// \param NumClauses Number of clauses.
   1684   ///
   1685   static OMPParallelSectionsDirective *
   1686   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
   1687 
   1688   /// \brief Return true if current directive has inner cancel directive.
   1689   bool hasCancel() const { return HasCancel; }
   1690 
   1691   static bool classof(const Stmt *T) {
   1692     return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
   1693   }
   1694 };
   1695 
   1696 /// \brief This represents '#pragma omp task' directive.
   1697 ///
   1698 /// \code
   1699 /// #pragma omp task private(a,b) final(d)
   1700 /// \endcode
   1701 /// In this example directive '#pragma omp task' has clauses 'private' with the
   1702 /// variables 'a' and 'b' and 'final' with condition 'd'.
   1703 ///
   1704 class OMPTaskDirective : public OMPExecutableDirective {
   1705   friend class ASTStmtReader;
   1706   /// \brief true if this directive has inner cancel directive.
   1707   bool HasCancel;
   1708 
   1709   /// \brief Build directive with the given start and end location.
   1710   ///
   1711   /// \param StartLoc Starting location of the directive kind.
   1712   /// \param EndLoc Ending location of the directive.
   1713   /// \param NumClauses Number of clauses.
   1714   ///
   1715   OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1716                    unsigned NumClauses)
   1717       : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
   1718                                EndLoc, NumClauses, 1),
   1719         HasCancel(false) {}
   1720 
   1721   /// \brief Build an empty directive.
   1722   ///
   1723   /// \param NumClauses Number of clauses.
   1724   ///
   1725   explicit OMPTaskDirective(unsigned NumClauses)
   1726       : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
   1727                                SourceLocation(), SourceLocation(), NumClauses,
   1728                                1),
   1729         HasCancel(false) {}
   1730 
   1731   /// \brief Set cancel state.
   1732   void setHasCancel(bool Has) { HasCancel = Has; }
   1733 
   1734 public:
   1735   /// \brief Creates directive with a list of \a Clauses.
   1736   ///
   1737   /// \param C AST context.
   1738   /// \param StartLoc Starting location of the directive kind.
   1739   /// \param EndLoc Ending Location of the directive.
   1740   /// \param Clauses List of clauses.
   1741   /// \param AssociatedStmt Statement, associated with the directive.
   1742   /// \param HasCancel true, if current directive has inner cancel directive.
   1743   ///
   1744   static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
   1745                                   SourceLocation EndLoc,
   1746                                   ArrayRef<OMPClause *> Clauses,
   1747                                   Stmt *AssociatedStmt, bool HasCancel);
   1748 
   1749   /// \brief Creates an empty directive with the place for \a NumClauses
   1750   /// clauses.
   1751   ///
   1752   /// \param C AST context.
   1753   /// \param NumClauses Number of clauses.
   1754   ///
   1755   static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
   1756                                        EmptyShell);
   1757 
   1758   /// \brief Return true if current directive has inner cancel directive.
   1759   bool hasCancel() const { return HasCancel; }
   1760 
   1761   static bool classof(const Stmt *T) {
   1762     return T->getStmtClass() == OMPTaskDirectiveClass;
   1763   }
   1764 };
   1765 
   1766 /// \brief This represents '#pragma omp taskyield' directive.
   1767 ///
   1768 /// \code
   1769 /// #pragma omp taskyield
   1770 /// \endcode
   1771 ///
   1772 class OMPTaskyieldDirective : public OMPExecutableDirective {
   1773   friend class ASTStmtReader;
   1774   /// \brief Build directive with the given start and end location.
   1775   ///
   1776   /// \param StartLoc Starting location of the directive kind.
   1777   /// \param EndLoc Ending location of the directive.
   1778   ///
   1779   OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1780       : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
   1781                                StartLoc, EndLoc, 0, 0) {}
   1782 
   1783   /// \brief Build an empty directive.
   1784   ///
   1785   explicit OMPTaskyieldDirective()
   1786       : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
   1787                                SourceLocation(), SourceLocation(), 0, 0) {}
   1788 
   1789 public:
   1790   /// \brief Creates directive.
   1791   ///
   1792   /// \param C AST context.
   1793   /// \param StartLoc Starting location of the directive kind.
   1794   /// \param EndLoc Ending Location of the directive.
   1795   ///
   1796   static OMPTaskyieldDirective *
   1797   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
   1798 
   1799   /// \brief Creates an empty directive.
   1800   ///
   1801   /// \param C AST context.
   1802   ///
   1803   static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1804 
   1805   static bool classof(const Stmt *T) {
   1806     return T->getStmtClass() == OMPTaskyieldDirectiveClass;
   1807   }
   1808 };
   1809 
   1810 /// \brief This represents '#pragma omp barrier' directive.
   1811 ///
   1812 /// \code
   1813 /// #pragma omp barrier
   1814 /// \endcode
   1815 ///
   1816 class OMPBarrierDirective : public OMPExecutableDirective {
   1817   friend class ASTStmtReader;
   1818   /// \brief Build directive with the given start and end location.
   1819   ///
   1820   /// \param StartLoc Starting location of the directive kind.
   1821   /// \param EndLoc Ending location of the directive.
   1822   ///
   1823   OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1824       : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
   1825                                StartLoc, EndLoc, 0, 0) {}
   1826 
   1827   /// \brief Build an empty directive.
   1828   ///
   1829   explicit OMPBarrierDirective()
   1830       : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
   1831                                SourceLocation(), SourceLocation(), 0, 0) {}
   1832 
   1833 public:
   1834   /// \brief Creates directive.
   1835   ///
   1836   /// \param C AST context.
   1837   /// \param StartLoc Starting location of the directive kind.
   1838   /// \param EndLoc Ending Location of the directive.
   1839   ///
   1840   static OMPBarrierDirective *
   1841   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
   1842 
   1843   /// \brief Creates an empty directive.
   1844   ///
   1845   /// \param C AST context.
   1846   ///
   1847   static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1848 
   1849   static bool classof(const Stmt *T) {
   1850     return T->getStmtClass() == OMPBarrierDirectiveClass;
   1851   }
   1852 };
   1853 
   1854 /// \brief This represents '#pragma omp taskwait' directive.
   1855 ///
   1856 /// \code
   1857 /// #pragma omp taskwait
   1858 /// \endcode
   1859 ///
   1860 class OMPTaskwaitDirective : public OMPExecutableDirective {
   1861   friend class ASTStmtReader;
   1862   /// \brief Build directive with the given start and end location.
   1863   ///
   1864   /// \param StartLoc Starting location of the directive kind.
   1865   /// \param EndLoc Ending location of the directive.
   1866   ///
   1867   OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1868       : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
   1869                                StartLoc, EndLoc, 0, 0) {}
   1870 
   1871   /// \brief Build an empty directive.
   1872   ///
   1873   explicit OMPTaskwaitDirective()
   1874       : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
   1875                                SourceLocation(), SourceLocation(), 0, 0) {}
   1876 
   1877 public:
   1878   /// \brief Creates directive.
   1879   ///
   1880   /// \param C AST context.
   1881   /// \param StartLoc Starting location of the directive kind.
   1882   /// \param EndLoc Ending Location of the directive.
   1883   ///
   1884   static OMPTaskwaitDirective *
   1885   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
   1886 
   1887   /// \brief Creates an empty directive.
   1888   ///
   1889   /// \param C AST context.
   1890   ///
   1891   static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1892 
   1893   static bool classof(const Stmt *T) {
   1894     return T->getStmtClass() == OMPTaskwaitDirectiveClass;
   1895   }
   1896 };
   1897 
   1898 /// \brief This represents '#pragma omp taskgroup' directive.
   1899 ///
   1900 /// \code
   1901 /// #pragma omp taskgroup
   1902 /// \endcode
   1903 ///
   1904 class OMPTaskgroupDirective : public OMPExecutableDirective {
   1905   friend class ASTStmtReader;
   1906   /// \brief Build directive with the given start and end location.
   1907   ///
   1908   /// \param StartLoc Starting location of the directive kind.
   1909   /// \param EndLoc Ending location of the directive.
   1910   ///
   1911   OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1912       : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
   1913                                StartLoc, EndLoc, 0, 1) {}
   1914 
   1915   /// \brief Build an empty directive.
   1916   ///
   1917   explicit OMPTaskgroupDirective()
   1918       : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
   1919                                SourceLocation(), SourceLocation(), 0, 1) {}
   1920 
   1921 public:
   1922   /// \brief Creates directive.
   1923   ///
   1924   /// \param C AST context.
   1925   /// \param StartLoc Starting location of the directive kind.
   1926   /// \param EndLoc Ending Location of the directive.
   1927   /// \param AssociatedStmt Statement, associated with the directive.
   1928   ///
   1929   static OMPTaskgroupDirective *Create(const ASTContext &C,
   1930                                        SourceLocation StartLoc,
   1931                                        SourceLocation EndLoc,
   1932                                        Stmt *AssociatedStmt);
   1933 
   1934   /// \brief Creates an empty directive.
   1935   ///
   1936   /// \param C AST context.
   1937   ///
   1938   static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1939 
   1940   static bool classof(const Stmt *T) {
   1941     return T->getStmtClass() == OMPTaskgroupDirectiveClass;
   1942   }
   1943 };
   1944 
   1945 /// \brief This represents '#pragma omp flush' directive.
   1946 ///
   1947 /// \code
   1948 /// #pragma omp flush(a,b)
   1949 /// \endcode
   1950 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
   1951 /// and 'b'.
   1952 /// 'omp flush' directive does not have clauses but have an optional list of
   1953 /// variables to flush. This list of variables is stored within some fake clause
   1954 /// FlushClause.
   1955 class OMPFlushDirective : public OMPExecutableDirective {
   1956   friend class ASTStmtReader;
   1957   /// \brief Build directive with the given start and end location.
   1958   ///
   1959   /// \param StartLoc Starting location of the directive kind.
   1960   /// \param EndLoc Ending location of the directive.
   1961   /// \param NumClauses Number of clauses.
   1962   ///
   1963   OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1964                     unsigned NumClauses)
   1965       : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
   1966                                StartLoc, EndLoc, NumClauses, 0) {}
   1967 
   1968   /// \brief Build an empty directive.
   1969   ///
   1970   /// \param NumClauses Number of clauses.
   1971   ///
   1972   explicit OMPFlushDirective(unsigned NumClauses)
   1973       : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
   1974                                SourceLocation(), SourceLocation(), NumClauses,
   1975                                0) {}
   1976 
   1977 public:
   1978   /// \brief Creates directive with a list of \a Clauses.
   1979   ///
   1980   /// \param C AST context.
   1981   /// \param StartLoc Starting location of the directive kind.
   1982   /// \param EndLoc Ending Location of the directive.
   1983   /// \param Clauses List of clauses (only single OMPFlushClause clause is
   1984   /// allowed).
   1985   ///
   1986   static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
   1987                                    SourceLocation EndLoc,
   1988                                    ArrayRef<OMPClause *> Clauses);
   1989 
   1990   /// \brief Creates an empty directive with the place for \a NumClauses
   1991   /// clauses.
   1992   ///
   1993   /// \param C AST context.
   1994   /// \param NumClauses Number of clauses.
   1995   ///
   1996   static OMPFlushDirective *CreateEmpty(const ASTContext &C,
   1997                                         unsigned NumClauses, EmptyShell);
   1998 
   1999   static bool classof(const Stmt *T) {
   2000     return T->getStmtClass() == OMPFlushDirectiveClass;
   2001   }
   2002 };
   2003 
   2004 /// \brief This represents '#pragma omp ordered' directive.
   2005 ///
   2006 /// \code
   2007 /// #pragma omp ordered
   2008 /// \endcode
   2009 ///
   2010 class OMPOrderedDirective : public OMPExecutableDirective {
   2011   friend class ASTStmtReader;
   2012   /// \brief Build directive with the given start and end location.
   2013   ///
   2014   /// \param StartLoc Starting location of the directive kind.
   2015   /// \param EndLoc Ending location of the directive.
   2016   /// \param NumClauses Number of clauses.
   2017   ///
   2018   OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2019                       unsigned NumClauses)
   2020       : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
   2021                                StartLoc, EndLoc, NumClauses, 1) {}
   2022 
   2023   /// \brief Build an empty directive.
   2024   ///
   2025   /// \param NumClauses Number of clauses.
   2026   ///
   2027   explicit OMPOrderedDirective(unsigned NumClauses)
   2028       : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
   2029                                SourceLocation(), SourceLocation(), NumClauses,
   2030                                1) {}
   2031 
   2032 public:
   2033   /// \brief Creates directive.
   2034   ///
   2035   /// \param C AST context.
   2036   /// \param StartLoc Starting location of the directive kind.
   2037   /// \param EndLoc Ending Location of the directive.
   2038   /// \param Clauses List of clauses.
   2039   /// \param AssociatedStmt Statement, associated with the directive.
   2040   ///
   2041   static OMPOrderedDirective *
   2042   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2043          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   2044 
   2045   /// \brief Creates an empty directive.
   2046   ///
   2047   /// \param C AST context.
   2048   /// \param NumClauses Number of clauses.
   2049   ///
   2050   static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
   2051                                           unsigned NumClauses, EmptyShell);
   2052 
   2053   static bool classof(const Stmt *T) {
   2054     return T->getStmtClass() == OMPOrderedDirectiveClass;
   2055   }
   2056 };
   2057 
   2058 /// \brief This represents '#pragma omp atomic' directive.
   2059 ///
   2060 /// \code
   2061 /// #pragma omp atomic capture
   2062 /// \endcode
   2063 /// In this example directive '#pragma omp atomic' has clause 'capture'.
   2064 ///
   2065 class OMPAtomicDirective : public OMPExecutableDirective {
   2066   friend class ASTStmtReader;
   2067   /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
   2068   /// have atomic expressions of forms
   2069   /// \code
   2070   /// x = x binop expr;
   2071   /// x = expr binop x;
   2072   /// \endcode
   2073   /// This field is true for the first form of the expression and false for the
   2074   /// second. Required for correct codegen of non-associative operations (like
   2075   /// << or >>).
   2076   bool IsXLHSInRHSPart;
   2077   /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
   2078   /// have atomic expressions of forms
   2079   /// \code
   2080   /// v = x; <update x>;
   2081   /// <update x>; v = x;
   2082   /// \endcode
   2083   /// This field is true for the first(postfix) form of the expression and false
   2084   /// otherwise.
   2085   bool IsPostfixUpdate;
   2086 
   2087   /// \brief Build directive with the given start and end location.
   2088   ///
   2089   /// \param StartLoc Starting location of the directive kind.
   2090   /// \param EndLoc Ending location of the directive.
   2091   /// \param NumClauses Number of clauses.
   2092   ///
   2093   OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2094                      unsigned NumClauses)
   2095       : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
   2096                                StartLoc, EndLoc, NumClauses, 5),
   2097         IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
   2098 
   2099   /// \brief Build an empty directive.
   2100   ///
   2101   /// \param NumClauses Number of clauses.
   2102   ///
   2103   explicit OMPAtomicDirective(unsigned NumClauses)
   2104       : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
   2105                                SourceLocation(), SourceLocation(), NumClauses,
   2106                                5),
   2107         IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
   2108 
   2109   /// \brief Set 'x' part of the associated expression/statement.
   2110   void setX(Expr *X) { *std::next(child_begin()) = X; }
   2111   /// \brief Set helper expression of the form
   2112   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
   2113   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
   2114   void setUpdateExpr(Expr *UE) { *std::next(child_begin(), 2) = UE; }
   2115   /// \brief Set 'v' part of the associated expression/statement.
   2116   void setV(Expr *V) { *std::next(child_begin(), 3) = V; }
   2117   /// \brief Set 'expr' part of the associated expression/statement.
   2118   void setExpr(Expr *E) { *std::next(child_begin(), 4) = E; }
   2119 
   2120 public:
   2121   /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
   2122   /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
   2123   /// detailed description of 'x', 'v' and 'expr').
   2124   ///
   2125   /// \param C AST context.
   2126   /// \param StartLoc Starting location of the directive kind.
   2127   /// \param EndLoc Ending Location of the directive.
   2128   /// \param Clauses List of clauses.
   2129   /// \param AssociatedStmt Statement, associated with the directive.
   2130   /// \param X 'x' part of the associated expression/statement.
   2131   /// \param V 'v' part of the associated expression/statement.
   2132   /// \param E 'expr' part of the associated expression/statement.
   2133   /// \param UE Helper expression of the form
   2134   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
   2135   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
   2136   /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the
   2137   /// second.
   2138   /// \param IsPostfixUpdate true if original value of 'x' must be stored in
   2139   /// 'v', not an updated one.
   2140   static OMPAtomicDirective *
   2141   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2142          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
   2143          Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate);
   2144 
   2145   /// \brief Creates an empty directive with the place for \a NumClauses
   2146   /// clauses.
   2147   ///
   2148   /// \param C AST context.
   2149   /// \param NumClauses Number of clauses.
   2150   ///
   2151   static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
   2152                                          unsigned NumClauses, EmptyShell);
   2153 
   2154   /// \brief Get 'x' part of the associated expression/statement.
   2155   Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); }
   2156   const Expr *getX() const {
   2157     return cast_or_null<Expr>(*std::next(child_begin()));
   2158   }
   2159   /// \brief Get helper expression of the form
   2160   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
   2161   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
   2162   Expr *getUpdateExpr() {
   2163     return cast_or_null<Expr>(*std::next(child_begin(), 2));
   2164   }
   2165   const Expr *getUpdateExpr() const {
   2166     return cast_or_null<Expr>(*std::next(child_begin(), 2));
   2167   }
   2168   /// \brief Return true if helper update expression has form
   2169   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
   2170   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
   2171   bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
   2172   /// \brief Return true if 'v' expression must be updated to original value of
   2173   /// 'x', false if 'v' must be updated to the new value of 'x'.
   2174   bool isPostfixUpdate() const { return IsPostfixUpdate; }
   2175   /// \brief Get 'v' part of the associated expression/statement.
   2176   Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); }
   2177   const Expr *getV() const {
   2178     return cast_or_null<Expr>(*std::next(child_begin(), 3));
   2179   }
   2180   /// \brief Get 'expr' part of the associated expression/statement.
   2181   Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 4)); }
   2182   const Expr *getExpr() const {
   2183     return cast_or_null<Expr>(*std::next(child_begin(), 4));
   2184   }
   2185 
   2186   static bool classof(const Stmt *T) {
   2187     return T->getStmtClass() == OMPAtomicDirectiveClass;
   2188   }
   2189 };
   2190 
   2191 /// \brief This represents '#pragma omp target' directive.
   2192 ///
   2193 /// \code
   2194 /// #pragma omp target if(a)
   2195 /// \endcode
   2196 /// In this example directive '#pragma omp target' has clause 'if' with
   2197 /// condition 'a'.
   2198 ///
   2199 class OMPTargetDirective : public OMPExecutableDirective {
   2200   friend class ASTStmtReader;
   2201   /// \brief Build directive with the given start and end location.
   2202   ///
   2203   /// \param StartLoc Starting location of the directive kind.
   2204   /// \param EndLoc Ending location of the directive.
   2205   /// \param NumClauses Number of clauses.
   2206   ///
   2207   OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2208                      unsigned NumClauses)
   2209       : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
   2210                                StartLoc, EndLoc, NumClauses, 1) {}
   2211 
   2212   /// \brief Build an empty directive.
   2213   ///
   2214   /// \param NumClauses Number of clauses.
   2215   ///
   2216   explicit OMPTargetDirective(unsigned NumClauses)
   2217       : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
   2218                                SourceLocation(), SourceLocation(), NumClauses,
   2219                                1) {}
   2220 
   2221 public:
   2222   /// \brief Creates directive with a list of \a Clauses.
   2223   ///
   2224   /// \param C AST context.
   2225   /// \param StartLoc Starting location of the directive kind.
   2226   /// \param EndLoc Ending Location of the directive.
   2227   /// \param Clauses List of clauses.
   2228   /// \param AssociatedStmt Statement, associated with the directive.
   2229   ///
   2230   static OMPTargetDirective *
   2231   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2232          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   2233 
   2234   /// \brief Creates an empty directive with the place for \a NumClauses
   2235   /// clauses.
   2236   ///
   2237   /// \param C AST context.
   2238   /// \param NumClauses Number of clauses.
   2239   ///
   2240   static OMPTargetDirective *CreateEmpty(const ASTContext &C,
   2241                                          unsigned NumClauses, EmptyShell);
   2242 
   2243   static bool classof(const Stmt *T) {
   2244     return T->getStmtClass() == OMPTargetDirectiveClass;
   2245   }
   2246 };
   2247 
   2248 /// \brief This represents '#pragma omp target data' directive.
   2249 ///
   2250 /// \code
   2251 /// #pragma omp target data device(0) if(a) map(b[:])
   2252 /// \endcode
   2253 /// In this example directive '#pragma omp target data' has clauses 'device'
   2254 /// with the value '0', 'if' with condition 'a' and 'map' with array
   2255 /// section 'b[:]'.
   2256 ///
   2257 class OMPTargetDataDirective : public OMPExecutableDirective {
   2258   friend class ASTStmtReader;
   2259   /// \brief Build directive with the given start and end location.
   2260   ///
   2261   /// \param StartLoc Starting location of the directive kind.
   2262   /// \param EndLoc Ending Location of the directive.
   2263   /// \param NumClauses The number of clauses.
   2264   ///
   2265   OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2266                          unsigned NumClauses)
   2267       : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
   2268                                OMPD_target_data, StartLoc, EndLoc, NumClauses,
   2269                                1) {}
   2270 
   2271   /// \brief Build an empty directive.
   2272   ///
   2273   /// \param NumClauses Number of clauses.
   2274   ///
   2275   explicit OMPTargetDataDirective(unsigned NumClauses)
   2276       : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
   2277                                OMPD_target_data, SourceLocation(),
   2278                                SourceLocation(), NumClauses, 1) {}
   2279 
   2280 public:
   2281   /// \brief Creates directive with a list of \a Clauses.
   2282   ///
   2283   /// \param C AST context.
   2284   /// \param StartLoc Starting location of the directive kind.
   2285   /// \param EndLoc Ending Location of the directive.
   2286   /// \param Clauses List of clauses.
   2287   /// \param AssociatedStmt Statement, associated with the directive.
   2288   ///
   2289   static OMPTargetDataDirective *
   2290   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2291          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   2292 
   2293   /// \brief Creates an empty directive with the place for \a N clauses.
   2294   ///
   2295   /// \param C AST context.
   2296   /// \param N The number of clauses.
   2297   ///
   2298   static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
   2299                                              EmptyShell);
   2300 
   2301   static bool classof(const Stmt *T) {
   2302     return T->getStmtClass() == OMPTargetDataDirectiveClass;
   2303   }
   2304 };
   2305 
   2306 /// \brief This represents '#pragma omp target enter data' directive.
   2307 ///
   2308 /// \code
   2309 /// #pragma omp target enter data device(0) if(a) map(b[:])
   2310 /// \endcode
   2311 /// In this example directive '#pragma omp target enter data' has clauses
   2312 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
   2313 /// section 'b[:]'.
   2314 ///
   2315 class OMPTargetEnterDataDirective : public OMPExecutableDirective {
   2316   friend class ASTStmtReader;
   2317   /// \brief Build directive with the given start and end location.
   2318   ///
   2319   /// \param StartLoc Starting location of the directive kind.
   2320   /// \param EndLoc Ending Location of the directive.
   2321   /// \param NumClauses The number of clauses.
   2322   ///
   2323   OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2324                               unsigned NumClauses)
   2325       : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
   2326                                OMPD_target_enter_data, StartLoc, EndLoc,
   2327                                NumClauses, /*NumChildren=*/0) {}
   2328 
   2329   /// \brief Build an empty directive.
   2330   ///
   2331   /// \param NumClauses Number of clauses.
   2332   ///
   2333   explicit OMPTargetEnterDataDirective(unsigned NumClauses)
   2334       : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
   2335                                OMPD_target_enter_data, SourceLocation(),
   2336                                SourceLocation(), NumClauses,
   2337                                /*NumChildren=*/0) {}
   2338 
   2339 public:
   2340   /// \brief Creates directive with a list of \a Clauses.
   2341   ///
   2342   /// \param C AST context.
   2343   /// \param StartLoc Starting location of the directive kind.
   2344   /// \param EndLoc Ending Location of the directive.
   2345   /// \param Clauses List of clauses.
   2346   ///
   2347   static OMPTargetEnterDataDirective *Create(const ASTContext &C,
   2348                                              SourceLocation StartLoc,
   2349                                              SourceLocation EndLoc,
   2350                                              ArrayRef<OMPClause *> Clauses);
   2351 
   2352   /// \brief Creates an empty directive with the place for \a N clauses.
   2353   ///
   2354   /// \param C AST context.
   2355   /// \param N The number of clauses.
   2356   ///
   2357   static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C,
   2358                                                   unsigned N, EmptyShell);
   2359 
   2360   static bool classof(const Stmt *T) {
   2361     return T->getStmtClass() == OMPTargetEnterDataDirectiveClass;
   2362   }
   2363 };
   2364 
   2365 /// \brief This represents '#pragma omp target exit data' directive.
   2366 ///
   2367 /// \code
   2368 /// #pragma omp target exit data device(0) if(a) map(b[:])
   2369 /// \endcode
   2370 /// In this example directive '#pragma omp target exit data' has clauses
   2371 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
   2372 /// section 'b[:]'.
   2373 ///
   2374 class OMPTargetExitDataDirective : public OMPExecutableDirective {
   2375   friend class ASTStmtReader;
   2376   /// \brief Build directive with the given start and end location.
   2377   ///
   2378   /// \param StartLoc Starting location of the directive kind.
   2379   /// \param EndLoc Ending Location of the directive.
   2380   /// \param NumClauses The number of clauses.
   2381   ///
   2382   OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2383                              unsigned NumClauses)
   2384       : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
   2385                                OMPD_target_exit_data, StartLoc, EndLoc,
   2386                                NumClauses, /*NumChildren=*/0) {}
   2387 
   2388   /// \brief Build an empty directive.
   2389   ///
   2390   /// \param NumClauses Number of clauses.
   2391   ///
   2392   explicit OMPTargetExitDataDirective(unsigned NumClauses)
   2393       : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
   2394                                OMPD_target_exit_data, SourceLocation(),
   2395                                SourceLocation(), NumClauses,
   2396                                /*NumChildren=*/0) {}
   2397 
   2398 public:
   2399   /// \brief Creates directive with a list of \a Clauses.
   2400   ///
   2401   /// \param C AST context.
   2402   /// \param StartLoc Starting location of the directive kind.
   2403   /// \param EndLoc Ending Location of the directive.
   2404   /// \param Clauses List of clauses.
   2405   ///
   2406   static OMPTargetExitDataDirective *Create(const ASTContext &C,
   2407                                             SourceLocation StartLoc,
   2408                                             SourceLocation EndLoc,
   2409                                             ArrayRef<OMPClause *> Clauses);
   2410 
   2411   /// \brief Creates an empty directive with the place for \a N clauses.
   2412   ///
   2413   /// \param C AST context.
   2414   /// \param N The number of clauses.
   2415   ///
   2416   static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
   2417                                                  unsigned N, EmptyShell);
   2418 
   2419   static bool classof(const Stmt *T) {
   2420     return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
   2421   }
   2422 };
   2423 
   2424 /// \brief This represents '#pragma omp target parallel' directive.
   2425 ///
   2426 /// \code
   2427 /// #pragma omp target parallel if(a)
   2428 /// \endcode
   2429 /// In this example directive '#pragma omp target parallel' has clause 'if' with
   2430 /// condition 'a'.
   2431 ///
   2432 class OMPTargetParallelDirective : public OMPExecutableDirective {
   2433   friend class ASTStmtReader;
   2434   /// \brief Build directive with the given start and end location.
   2435   ///
   2436   /// \param StartLoc Starting location of the directive kind.
   2437   /// \param EndLoc Ending location of the directive.
   2438   /// \param NumClauses Number of clauses.
   2439   ///
   2440   OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2441                              unsigned NumClauses)
   2442       : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass,
   2443                                OMPD_target_parallel, StartLoc, EndLoc,
   2444                                NumClauses, /*NumChildren=*/1) {}
   2445 
   2446   /// \brief Build an empty directive.
   2447   ///
   2448   /// \param NumClauses Number of clauses.
   2449   ///
   2450   explicit OMPTargetParallelDirective(unsigned NumClauses)
   2451       : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass,
   2452                                OMPD_target_parallel, SourceLocation(),
   2453                                SourceLocation(), NumClauses,
   2454                                /*NumChildren=*/1) {}
   2455 
   2456 public:
   2457   /// \brief Creates directive with a list of \a Clauses.
   2458   ///
   2459   /// \param C AST context.
   2460   /// \param StartLoc Starting location of the directive kind.
   2461   /// \param EndLoc Ending Location of the directive.
   2462   /// \param Clauses List of clauses.
   2463   /// \param AssociatedStmt Statement, associated with the directive.
   2464   ///
   2465   static OMPTargetParallelDirective *
   2466   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2467          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   2468 
   2469   /// \brief Creates an empty directive with the place for \a NumClauses
   2470   /// clauses.
   2471   ///
   2472   /// \param C AST context.
   2473   /// \param NumClauses Number of clauses.
   2474   ///
   2475   static OMPTargetParallelDirective *
   2476   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
   2477 
   2478   static bool classof(const Stmt *T) {
   2479     return T->getStmtClass() == OMPTargetParallelDirectiveClass;
   2480   }
   2481 };
   2482 
   2483 /// \brief This represents '#pragma omp target parallel for' directive.
   2484 ///
   2485 /// \code
   2486 /// #pragma omp target parallel for private(a,b) reduction(+:c,d)
   2487 /// \endcode
   2488 /// In this example directive '#pragma omp target parallel for' has clauses
   2489 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
   2490 /// and variables 'c' and 'd'.
   2491 ///
   2492 class OMPTargetParallelForDirective : public OMPLoopDirective {
   2493   friend class ASTStmtReader;
   2494 
   2495   /// \brief true if current region has inner cancel directive.
   2496   bool HasCancel;
   2497 
   2498   /// \brief Build directive with the given start and end location.
   2499   ///
   2500   /// \param StartLoc Starting location of the directive kind.
   2501   /// \param EndLoc Ending location of the directive.
   2502   /// \param CollapsedNum Number of collapsed nested loops.
   2503   /// \param NumClauses Number of clauses.
   2504   ///
   2505   OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2506                                 unsigned CollapsedNum, unsigned NumClauses)
   2507       : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass,
   2508                          OMPD_target_parallel_for, StartLoc, EndLoc,
   2509                          CollapsedNum, NumClauses),
   2510         HasCancel(false) {}
   2511 
   2512   /// \brief Build an empty directive.
   2513   ///
   2514   /// \param CollapsedNum Number of collapsed nested loops.
   2515   /// \param NumClauses Number of clauses.
   2516   ///
   2517   explicit OMPTargetParallelForDirective(unsigned CollapsedNum,
   2518                                          unsigned NumClauses)
   2519       : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass,
   2520                          OMPD_target_parallel_for, SourceLocation(),
   2521                          SourceLocation(), CollapsedNum, NumClauses),
   2522         HasCancel(false) {}
   2523 
   2524   /// \brief Set cancel state.
   2525   void setHasCancel(bool Has) { HasCancel = Has; }
   2526 
   2527 public:
   2528   /// \brief Creates directive with a list of \a Clauses.
   2529   ///
   2530   /// \param C AST context.
   2531   /// \param StartLoc Starting location of the directive kind.
   2532   /// \param EndLoc Ending Location of the directive.
   2533   /// \param CollapsedNum Number of collapsed loops.
   2534   /// \param Clauses List of clauses.
   2535   /// \param AssociatedStmt Statement, associated with the directive.
   2536   /// \param Exprs Helper expressions for CodeGen.
   2537   /// \param HasCancel true if current directive has inner cancel directive.
   2538   ///
   2539   static OMPTargetParallelForDirective *
   2540   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2541          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   2542          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
   2543 
   2544   /// \brief Creates an empty directive with the place
   2545   /// for \a NumClauses clauses.
   2546   ///
   2547   /// \param C AST context.
   2548   /// \param CollapsedNum Number of collapsed nested loops.
   2549   /// \param NumClauses Number of clauses.
   2550   ///
   2551   static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C,
   2552                                                     unsigned NumClauses,
   2553                                                     unsigned CollapsedNum,
   2554                                                     EmptyShell);
   2555 
   2556   /// \brief Return true if current directive has inner cancel directive.
   2557   bool hasCancel() const { return HasCancel; }
   2558 
   2559   static bool classof(const Stmt *T) {
   2560     return T->getStmtClass() == OMPTargetParallelForDirectiveClass;
   2561   }
   2562 };
   2563 
   2564 /// \brief This represents '#pragma omp teams' directive.
   2565 ///
   2566 /// \code
   2567 /// #pragma omp teams if(a)
   2568 /// \endcode
   2569 /// In this example directive '#pragma omp teams' has clause 'if' with
   2570 /// condition 'a'.
   2571 ///
   2572 class OMPTeamsDirective : public OMPExecutableDirective {
   2573   friend class ASTStmtReader;
   2574   /// \brief Build directive with the given start and end location.
   2575   ///
   2576   /// \param StartLoc Starting location of the directive kind.
   2577   /// \param EndLoc Ending location of the directive.
   2578   /// \param NumClauses Number of clauses.
   2579   ///
   2580   OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2581                     unsigned NumClauses)
   2582       : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
   2583                                StartLoc, EndLoc, NumClauses, 1) {}
   2584 
   2585   /// \brief Build an empty directive.
   2586   ///
   2587   /// \param NumClauses Number of clauses.
   2588   ///
   2589   explicit OMPTeamsDirective(unsigned NumClauses)
   2590       : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
   2591                                SourceLocation(), SourceLocation(), NumClauses,
   2592                                1) {}
   2593 
   2594 public:
   2595   /// \brief Creates directive with a list of \a Clauses.
   2596   ///
   2597   /// \param C AST context.
   2598   /// \param StartLoc Starting location of the directive kind.
   2599   /// \param EndLoc Ending Location of the directive.
   2600   /// \param Clauses List of clauses.
   2601   /// \param AssociatedStmt Statement, associated with the directive.
   2602   ///
   2603   static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
   2604                                    SourceLocation EndLoc,
   2605                                    ArrayRef<OMPClause *> Clauses,
   2606                                    Stmt *AssociatedStmt);
   2607 
   2608   /// \brief Creates an empty directive with the place for \a NumClauses
   2609   /// clauses.
   2610   ///
   2611   /// \param C AST context.
   2612   /// \param NumClauses Number of clauses.
   2613   ///
   2614   static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
   2615                                         unsigned NumClauses, EmptyShell);
   2616 
   2617   static bool classof(const Stmt *T) {
   2618     return T->getStmtClass() == OMPTeamsDirectiveClass;
   2619   }
   2620 };
   2621 
   2622 /// \brief This represents '#pragma omp cancellation point' directive.
   2623 ///
   2624 /// \code
   2625 /// #pragma omp cancellation point for
   2626 /// \endcode
   2627 ///
   2628 /// In this example a cancellation point is created for innermost 'for' region.
   2629 class OMPCancellationPointDirective : public OMPExecutableDirective {
   2630   friend class ASTStmtReader;
   2631   OpenMPDirectiveKind CancelRegion;
   2632   /// \brief Build directive with the given start and end location.
   2633   ///
   2634   /// \param StartLoc Starting location of the directive kind.
   2635   /// \param EndLoc Ending location of the directive.
   2636   ///
   2637   OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   2638       : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
   2639                                OMPD_cancellation_point, StartLoc, EndLoc, 0, 0),
   2640         CancelRegion(OMPD_unknown) {}
   2641 
   2642   /// \brief Build an empty directive.
   2643   ///
   2644   explicit OMPCancellationPointDirective()
   2645       : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
   2646                                OMPD_cancellation_point, SourceLocation(),
   2647                                SourceLocation(), 0, 0),
   2648         CancelRegion(OMPD_unknown) {}
   2649 
   2650   /// \brief Set cancel region for current cancellation point.
   2651   /// \param CR Cancellation region.
   2652   void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
   2653 
   2654 public:
   2655   /// \brief Creates directive.
   2656   ///
   2657   /// \param C AST context.
   2658   /// \param StartLoc Starting location of the directive kind.
   2659   /// \param EndLoc Ending Location of the directive.
   2660   ///
   2661   static OMPCancellationPointDirective *
   2662   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2663          OpenMPDirectiveKind CancelRegion);
   2664 
   2665   /// \brief Creates an empty directive.
   2666   ///
   2667   /// \param C AST context.
   2668   ///
   2669   static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
   2670                                                     EmptyShell);
   2671 
   2672   /// \brief Get cancellation region for the current cancellation point.
   2673   OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
   2674 
   2675   static bool classof(const Stmt *T) {
   2676     return T->getStmtClass() == OMPCancellationPointDirectiveClass;
   2677   }
   2678 };
   2679 
   2680 /// \brief This represents '#pragma omp cancel' directive.
   2681 ///
   2682 /// \code
   2683 /// #pragma omp cancel for
   2684 /// \endcode
   2685 ///
   2686 /// In this example a cancel is created for innermost 'for' region.
   2687 class OMPCancelDirective : public OMPExecutableDirective {
   2688   friend class ASTStmtReader;
   2689   OpenMPDirectiveKind CancelRegion;
   2690   /// \brief Build directive with the given start and end location.
   2691   ///
   2692   /// \param StartLoc Starting location of the directive kind.
   2693   /// \param EndLoc Ending location of the directive.
   2694   /// \param NumClauses Number of clauses.
   2695   ///
   2696   OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2697                      unsigned NumClauses)
   2698       : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
   2699                                StartLoc, EndLoc, NumClauses, 0),
   2700         CancelRegion(OMPD_unknown) {}
   2701 
   2702   /// \brief Build an empty directive.
   2703   ///
   2704   /// \param NumClauses Number of clauses.
   2705   explicit OMPCancelDirective(unsigned NumClauses)
   2706       : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
   2707                                SourceLocation(), SourceLocation(), NumClauses,
   2708                                0),
   2709         CancelRegion(OMPD_unknown) {}
   2710 
   2711   /// \brief Set cancel region for current cancellation point.
   2712   /// \param CR Cancellation region.
   2713   void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
   2714 
   2715 public:
   2716   /// \brief Creates directive.
   2717   ///
   2718   /// \param C AST context.
   2719   /// \param StartLoc Starting location of the directive kind.
   2720   /// \param EndLoc Ending Location of the directive.
   2721   /// \param Clauses List of clauses.
   2722   ///
   2723   static OMPCancelDirective *
   2724   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2725          ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
   2726 
   2727   /// \brief Creates an empty directive.
   2728   ///
   2729   /// \param C AST context.
   2730   /// \param NumClauses Number of clauses.
   2731   ///
   2732   static OMPCancelDirective *CreateEmpty(const ASTContext &C,
   2733                                          unsigned NumClauses, EmptyShell);
   2734 
   2735   /// \brief Get cancellation region for the current cancellation point.
   2736   OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
   2737 
   2738   static bool classof(const Stmt *T) {
   2739     return T->getStmtClass() == OMPCancelDirectiveClass;
   2740   }
   2741 };
   2742 
   2743 /// \brief This represents '#pragma omp taskloop' directive.
   2744 ///
   2745 /// \code
   2746 /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
   2747 /// \endcode
   2748 /// In this example directive '#pragma omp taskloop' has clauses 'private'
   2749 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
   2750 /// 'num_tasks' with expression 'num'.
   2751 ///
   2752 class OMPTaskLoopDirective : public OMPLoopDirective {
   2753   friend class ASTStmtReader;
   2754   /// \brief Build directive with the given start and end location.
   2755   ///
   2756   /// \param StartLoc Starting location of the directive kind.
   2757   /// \param EndLoc Ending location of the directive.
   2758   /// \param CollapsedNum Number of collapsed nested loops.
   2759   /// \param NumClauses Number of clauses.
   2760   ///
   2761   OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2762                        unsigned CollapsedNum, unsigned NumClauses)
   2763       : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
   2764                          StartLoc, EndLoc, CollapsedNum, NumClauses) {}
   2765 
   2766   /// \brief Build an empty directive.
   2767   ///
   2768   /// \param CollapsedNum Number of collapsed nested loops.
   2769   /// \param NumClauses Number of clauses.
   2770   ///
   2771   explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses)
   2772       : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
   2773                          SourceLocation(), SourceLocation(), CollapsedNum,
   2774                          NumClauses) {}
   2775 
   2776 public:
   2777   /// \brief Creates directive with a list of \a Clauses.
   2778   ///
   2779   /// \param C AST context.
   2780   /// \param StartLoc Starting location of the directive kind.
   2781   /// \param EndLoc Ending Location of the directive.
   2782   /// \param CollapsedNum Number of collapsed loops.
   2783   /// \param Clauses List of clauses.
   2784   /// \param AssociatedStmt Statement, associated with the directive.
   2785   /// \param Exprs Helper expressions for CodeGen.
   2786   ///
   2787   static OMPTaskLoopDirective *
   2788   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2789          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   2790          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   2791 
   2792   /// \brief Creates an empty directive with the place
   2793   /// for \a NumClauses clauses.
   2794   ///
   2795   /// \param C AST context.
   2796   /// \param CollapsedNum Number of collapsed nested loops.
   2797   /// \param NumClauses Number of clauses.
   2798   ///
   2799   static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
   2800                                            unsigned NumClauses,
   2801                                            unsigned CollapsedNum, EmptyShell);
   2802 
   2803   static bool classof(const Stmt *T) {
   2804     return T->getStmtClass() == OMPTaskLoopDirectiveClass;
   2805   }
   2806 };
   2807 
   2808 /// \brief This represents '#pragma omp taskloop simd' directive.
   2809 ///
   2810 /// \code
   2811 /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
   2812 /// \endcode
   2813 /// In this example directive '#pragma omp taskloop simd' has clauses 'private'
   2814 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
   2815 /// 'num_tasks' with expression 'num'.
   2816 ///
   2817 class OMPTaskLoopSimdDirective : public OMPLoopDirective {
   2818   friend class ASTStmtReader;
   2819   /// \brief Build directive with the given start and end location.
   2820   ///
   2821   /// \param StartLoc Starting location of the directive kind.
   2822   /// \param EndLoc Ending location of the directive.
   2823   /// \param CollapsedNum Number of collapsed nested loops.
   2824   /// \param NumClauses Number of clauses.
   2825   ///
   2826   OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2827                            unsigned CollapsedNum, unsigned NumClauses)
   2828       : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
   2829                          OMPD_taskloop_simd, StartLoc, EndLoc, CollapsedNum,
   2830                          NumClauses) {}
   2831 
   2832   /// \brief Build an empty directive.
   2833   ///
   2834   /// \param CollapsedNum Number of collapsed nested loops.
   2835   /// \param NumClauses Number of clauses.
   2836   ///
   2837   explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
   2838       : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
   2839                          OMPD_taskloop_simd, SourceLocation(), SourceLocation(),
   2840                          CollapsedNum, NumClauses) {}
   2841 
   2842 public:
   2843   /// \brief Creates directive with a list of \a Clauses.
   2844   ///
   2845   /// \param C AST context.
   2846   /// \param StartLoc Starting location of the directive kind.
   2847   /// \param EndLoc Ending Location of the directive.
   2848   /// \param CollapsedNum Number of collapsed loops.
   2849   /// \param Clauses List of clauses.
   2850   /// \param AssociatedStmt Statement, associated with the directive.
   2851   /// \param Exprs Helper expressions for CodeGen.
   2852   ///
   2853   static OMPTaskLoopSimdDirective *
   2854   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2855          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   2856          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   2857 
   2858   /// \brief Creates an empty directive with the place
   2859   /// for \a NumClauses clauses.
   2860   ///
   2861   /// \param C AST context.
   2862   /// \param CollapsedNum Number of collapsed nested loops.
   2863   /// \param NumClauses Number of clauses.
   2864   ///
   2865   static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
   2866                                                unsigned NumClauses,
   2867                                                unsigned CollapsedNum,
   2868                                                EmptyShell);
   2869 
   2870   static bool classof(const Stmt *T) {
   2871     return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
   2872   }
   2873 };
   2874 
   2875 /// \brief This represents '#pragma omp distribute' directive.
   2876 ///
   2877 /// \code
   2878 /// #pragma omp distribute private(a,b)
   2879 /// \endcode
   2880 /// In this example directive '#pragma omp distribute' has clauses 'private'
   2881 /// with the variables 'a' and 'b'
   2882 ///
   2883 class OMPDistributeDirective : public OMPLoopDirective {
   2884   friend class ASTStmtReader;
   2885 
   2886   /// \brief Build directive with the given start and end location.
   2887   ///
   2888   /// \param StartLoc Starting location of the directive kind.
   2889   /// \param EndLoc Ending location of the directive.
   2890   /// \param CollapsedNum Number of collapsed nested loops.
   2891   /// \param NumClauses Number of clauses.
   2892   ///
   2893   OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2894                          unsigned CollapsedNum, unsigned NumClauses)
   2895       : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
   2896                          StartLoc, EndLoc, CollapsedNum, NumClauses)
   2897         {}
   2898 
   2899   /// \brief Build an empty directive.
   2900   ///
   2901   /// \param CollapsedNum Number of collapsed nested loops.
   2902   /// \param NumClauses Number of clauses.
   2903   ///
   2904   explicit OMPDistributeDirective(unsigned CollapsedNum, unsigned NumClauses)
   2905       : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
   2906                          SourceLocation(), SourceLocation(), CollapsedNum,
   2907                          NumClauses)
   2908         {}
   2909 
   2910 public:
   2911   /// \brief Creates directive with a list of \a Clauses.
   2912   ///
   2913   /// \param C AST context.
   2914   /// \param StartLoc Starting location of the directive kind.
   2915   /// \param EndLoc Ending Location of the directive.
   2916   /// \param CollapsedNum Number of collapsed loops.
   2917   /// \param Clauses List of clauses.
   2918   /// \param AssociatedStmt Statement, associated with the directive.
   2919   /// \param Exprs Helper expressions for CodeGen.
   2920   ///
   2921   static OMPDistributeDirective *
   2922   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2923          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   2924          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   2925 
   2926   /// \brief Creates an empty directive with the place
   2927   /// for \a NumClauses clauses.
   2928   ///
   2929   /// \param C AST context.
   2930   /// \param CollapsedNum Number of collapsed nested loops.
   2931   /// \param NumClauses Number of clauses.
   2932   ///
   2933   static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
   2934                                              unsigned NumClauses,
   2935                                              unsigned CollapsedNum, EmptyShell);
   2936 
   2937   static bool classof(const Stmt *T) {
   2938     return T->getStmtClass() == OMPDistributeDirectiveClass;
   2939   }
   2940 };
   2941 
   2942 /// \brief This represents '#pragma omp target update' directive.
   2943 ///
   2944 /// \code
   2945 /// #pragma omp target update to(a) from(b) device(1)
   2946 /// \endcode
   2947 /// In this example directive '#pragma omp target update' has clause 'to' with
   2948 /// argument 'a', clause 'from' with argument 'b' and clause 'device' with
   2949 /// argument '1'.
   2950 ///
   2951 class OMPTargetUpdateDirective : public OMPExecutableDirective {
   2952   friend class ASTStmtReader;
   2953   /// \brief Build directive with the given start and end location.
   2954   ///
   2955   /// \param StartLoc Starting location of the directive kind.
   2956   /// \param EndLoc Ending Location of the directive.
   2957   /// \param NumClauses The number of clauses.
   2958   ///
   2959   OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2960                            unsigned NumClauses)
   2961       : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
   2962                                OMPD_target_update, StartLoc, EndLoc, NumClauses,
   2963                                0) {}
   2964 
   2965   /// \brief Build an empty directive.
   2966   ///
   2967   /// \param NumClauses Number of clauses.
   2968   ///
   2969   explicit OMPTargetUpdateDirective(unsigned NumClauses)
   2970       : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
   2971                                OMPD_target_update, SourceLocation(),
   2972                                SourceLocation(), NumClauses, 0) {}
   2973 
   2974 public:
   2975   /// \brief Creates directive with a list of \a Clauses.
   2976   ///
   2977   /// \param C AST context.
   2978   /// \param StartLoc Starting location of the directive kind.
   2979   /// \param EndLoc Ending Location of the directive.
   2980   /// \param Clauses List of clauses.
   2981   ///
   2982   static OMPTargetUpdateDirective *Create(const ASTContext &C,
   2983                                           SourceLocation StartLoc,
   2984                                           SourceLocation EndLoc,
   2985                                           ArrayRef<OMPClause *> Clauses);
   2986 
   2987   /// \brief Creates an empty directive with the place for \a NumClauses
   2988   /// clauses.
   2989   ///
   2990   /// \param C AST context.
   2991   /// \param NumClauses The number of clauses.
   2992   ///
   2993   static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C,
   2994                                                unsigned NumClauses, EmptyShell);
   2995 
   2996   static bool classof(const Stmt *T) {
   2997     return T->getStmtClass() == OMPTargetUpdateDirectiveClass;
   2998   }
   2999 };
   3000 
   3001 /// \brief This represents '#pragma omp distribute parallel for' composite
   3002 ///  directive.
   3003 ///
   3004 /// \code
   3005 /// #pragma omp distribute parallel for private(a,b)
   3006 /// \endcode
   3007 /// In this example directive '#pragma omp distribute parallel for' has clause
   3008 /// 'private' with the variables 'a' and 'b'
   3009 ///
   3010 class OMPDistributeParallelForDirective : public OMPLoopDirective {
   3011   friend class ASTStmtReader;
   3012 
   3013   /// \brief Build directive with the given start and end location.
   3014   ///
   3015   /// \param StartLoc Starting location of the directive kind.
   3016   /// \param EndLoc Ending location of the directive.
   3017   /// \param CollapsedNum Number of collapsed nested loops.
   3018   /// \param NumClauses Number of clauses.
   3019   ///
   3020   OMPDistributeParallelForDirective(SourceLocation StartLoc,
   3021                                     SourceLocation EndLoc,
   3022                                     unsigned CollapsedNum, unsigned NumClauses)
   3023       : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass,
   3024                          OMPD_distribute_parallel_for, StartLoc, EndLoc,
   3025                          CollapsedNum, NumClauses) {}
   3026 
   3027   /// \brief Build an empty directive.
   3028   ///
   3029   /// \param CollapsedNum Number of collapsed nested loops.
   3030   /// \param NumClauses Number of clauses.
   3031   ///
   3032   explicit OMPDistributeParallelForDirective(unsigned CollapsedNum,
   3033                                              unsigned NumClauses)
   3034       : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass,
   3035                          OMPD_distribute_parallel_for, SourceLocation(),
   3036                          SourceLocation(), CollapsedNum, NumClauses) {}
   3037 
   3038 public:
   3039   /// \brief Creates directive with a list of \a Clauses.
   3040   ///
   3041   /// \param C AST context.
   3042   /// \param StartLoc Starting location of the directive kind.
   3043   /// \param EndLoc Ending Location of the directive.
   3044   /// \param CollapsedNum Number of collapsed loops.
   3045   /// \param Clauses List of clauses.
   3046   /// \param AssociatedStmt Statement, associated with the directive.
   3047   /// \param Exprs Helper expressions for CodeGen.
   3048   ///
   3049   static OMPDistributeParallelForDirective *
   3050   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3051          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3052          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3053 
   3054   /// \brief Creates an empty directive with the place
   3055   /// for \a NumClauses clauses.
   3056   ///
   3057   /// \param C AST context.
   3058   /// \param CollapsedNum Number of collapsed nested loops.
   3059   /// \param NumClauses Number of clauses.
   3060   ///
   3061   static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C,
   3062                                                         unsigned NumClauses,
   3063                                                         unsigned CollapsedNum,
   3064                                                         EmptyShell);
   3065 
   3066   static bool classof(const Stmt *T) {
   3067     return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
   3068   }
   3069 };
   3070 
   3071 /// This represents '#pragma omp distribute parallel for simd' composite
   3072 /// directive.
   3073 ///
   3074 /// \code
   3075 /// #pragma omp distribute parallel for simd private(x)
   3076 /// \endcode
   3077 /// In this example directive '#pragma omp distribute parallel for simd' has
   3078 /// clause 'private' with the variables 'x'
   3079 ///
   3080 class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective {
   3081   friend class ASTStmtReader;
   3082 
   3083   /// Build directive with the given start and end location.
   3084   ///
   3085   /// \param StartLoc Starting location of the directive kind.
   3086   /// \param EndLoc Ending location of the directive.
   3087   /// \param CollapsedNum Number of collapsed nested loops.
   3088   /// \param NumClauses Number of clauses.
   3089   ///
   3090   OMPDistributeParallelForSimdDirective(SourceLocation StartLoc,
   3091                                         SourceLocation EndLoc,
   3092                                         unsigned CollapsedNum,
   3093                                         unsigned NumClauses)
   3094       : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass,
   3095                          OMPD_distribute_parallel_for_simd, StartLoc,
   3096                          EndLoc, CollapsedNum, NumClauses) {}
   3097 
   3098   /// Build an empty directive.
   3099   ///
   3100   /// \param CollapsedNum Number of collapsed nested loops.
   3101   /// \param NumClauses Number of clauses.
   3102   ///
   3103   explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum,
   3104                                                  unsigned NumClauses)
   3105       : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass,
   3106                          OMPD_distribute_parallel_for_simd,
   3107                          SourceLocation(), SourceLocation(), CollapsedNum,
   3108                          NumClauses) {}
   3109 
   3110 public:
   3111   /// Creates directive with a list of \a Clauses.
   3112   ///
   3113   /// \param C AST context.
   3114   /// \param StartLoc Starting location of the directive kind.
   3115   /// \param EndLoc Ending Location of the directive.
   3116   /// \param CollapsedNum Number of collapsed loops.
   3117   /// \param Clauses List of clauses.
   3118   /// \param AssociatedStmt Statement, associated with the directive.
   3119   /// \param Exprs Helper expressions for CodeGen.
   3120   ///
   3121   static OMPDistributeParallelForSimdDirective *Create(
   3122       const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3123       unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3124       Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3125 
   3126   /// Creates an empty directive with the place for \a NumClauses clauses.
   3127   ///
   3128   /// \param C AST context.
   3129   /// \param CollapsedNum Number of collapsed nested loops.
   3130   /// \param NumClauses Number of clauses.
   3131   ///
   3132   static OMPDistributeParallelForSimdDirective *CreateEmpty(
   3133       const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
   3134       EmptyShell);
   3135 
   3136   static bool classof(const Stmt *T) {
   3137     return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass;
   3138   }
   3139 };
   3140 
   3141 /// This represents '#pragma omp distribute simd' composite directive.
   3142 ///
   3143 /// \code
   3144 /// #pragma omp distribute simd private(x)
   3145 /// \endcode
   3146 /// In this example directive '#pragma omp distribute simd' has clause
   3147 /// 'private' with the variables 'x'
   3148 ///
   3149 class OMPDistributeSimdDirective final : public OMPLoopDirective {
   3150   friend class ASTStmtReader;
   3151 
   3152   /// Build directive with the given start and end location.
   3153   ///
   3154   /// \param StartLoc Starting location of the directive kind.
   3155   /// \param EndLoc Ending location of the directive.
   3156   /// \param CollapsedNum Number of collapsed nested loops.
   3157   /// \param NumClauses Number of clauses.
   3158   ///
   3159   OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   3160                              unsigned CollapsedNum, unsigned NumClauses)
   3161       : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass,
   3162                          OMPD_distribute_simd, StartLoc, EndLoc, CollapsedNum,
   3163                          NumClauses) {}
   3164 
   3165   /// Build an empty directive.
   3166   ///
   3167   /// \param CollapsedNum Number of collapsed nested loops.
   3168   /// \param NumClauses Number of clauses.
   3169   ///
   3170   explicit OMPDistributeSimdDirective(unsigned CollapsedNum,
   3171                                       unsigned NumClauses)
   3172       : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass,
   3173                          OMPD_distribute_simd, SourceLocation(),
   3174                          SourceLocation(), CollapsedNum, NumClauses) {}
   3175 
   3176 public:
   3177   /// Creates directive with a list of \a Clauses.
   3178   ///
   3179   /// \param C AST context.
   3180   /// \param StartLoc Starting location of the directive kind.
   3181   /// \param EndLoc Ending Location of the directive.
   3182   /// \param CollapsedNum Number of collapsed loops.
   3183   /// \param Clauses List of clauses.
   3184   /// \param AssociatedStmt Statement, associated with the directive.
   3185   /// \param Exprs Helper expressions for CodeGen.
   3186   ///
   3187   static OMPDistributeSimdDirective *
   3188   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3189          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3190          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3191 
   3192   /// Creates an empty directive with the place for \a NumClauses clauses.
   3193   ///
   3194   /// \param C AST context.
   3195   /// \param CollapsedNum Number of collapsed nested loops.
   3196   /// \param NumClauses Number of clauses.
   3197   ///
   3198   static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C,
   3199                                                  unsigned NumClauses,
   3200                                                  unsigned CollapsedNum,
   3201                                                  EmptyShell);
   3202 
   3203   static bool classof(const Stmt *T) {
   3204     return T->getStmtClass() == OMPDistributeSimdDirectiveClass;
   3205   }
   3206 };
   3207 
   3208 /// This represents '#pragma omp target parallel for simd' directive.
   3209 ///
   3210 /// \code
   3211 /// #pragma omp target parallel for simd private(a) map(b) safelen(c)
   3212 /// \endcode
   3213 /// In this example directive '#pragma omp target parallel for simd' has clauses
   3214 /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen'
   3215 /// with the variable 'c'.
   3216 ///
   3217 class OMPTargetParallelForSimdDirective final : public OMPLoopDirective {
   3218   friend class ASTStmtReader;
   3219 
   3220   /// Build directive with the given start and end location.
   3221   ///
   3222   /// \param StartLoc Starting location of the directive kind.
   3223   /// \param EndLoc Ending location of the directive.
   3224   /// \param CollapsedNum Number of collapsed nested loops.
   3225   /// \param NumClauses Number of clauses.
   3226   ///
   3227   OMPTargetParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   3228                                 unsigned CollapsedNum, unsigned NumClauses)
   3229       : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass,
   3230                          OMPD_target_parallel_for_simd, StartLoc, EndLoc,
   3231                          CollapsedNum, NumClauses) {}
   3232 
   3233   /// Build an empty directive.
   3234   ///
   3235   /// \param CollapsedNum Number of collapsed nested loops.
   3236   /// \param NumClauses Number of clauses.
   3237   ///
   3238   explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum,
   3239                                              unsigned NumClauses)
   3240       : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass,
   3241                          OMPD_target_parallel_for_simd, SourceLocation(),
   3242                          SourceLocation(), CollapsedNum, NumClauses) {}
   3243 
   3244 public:
   3245   /// Creates directive with a list of \a Clauses.
   3246   ///
   3247   /// \param C AST context.
   3248   /// \param StartLoc Starting location of the directive kind.
   3249   /// \param EndLoc Ending Location of the directive.
   3250   /// \param CollapsedNum Number of collapsed loops.
   3251   /// \param Clauses List of clauses.
   3252   /// \param AssociatedStmt Statement, associated with the directive.
   3253   /// \param Exprs Helper expressions for CodeGen.
   3254   ///
   3255   static OMPTargetParallelForSimdDirective *
   3256   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3257          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3258          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3259 
   3260   /// Creates an empty directive with the place for \a NumClauses clauses.
   3261   ///
   3262   /// \param C AST context.
   3263   /// \param CollapsedNum Number of collapsed nested loops.
   3264   /// \param NumClauses Number of clauses.
   3265   ///
   3266   static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C,
   3267                                                         unsigned NumClauses,
   3268                                                         unsigned CollapsedNum,
   3269                                                         EmptyShell);
   3270 
   3271   static bool classof(const Stmt *T) {
   3272     return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
   3273   }
   3274 };
   3275 
   3276 /// This represents '#pragma omp target simd' directive.
   3277 ///
   3278 /// \code
   3279 /// #pragma omp target simd private(a) map(b) safelen(c)
   3280 /// \endcode
   3281 /// In this example directive '#pragma omp target simd' has clauses 'private'
   3282 /// with the variable 'a', 'map' with the variable 'b' and 'safelen' with
   3283 /// the variable 'c'.
   3284 ///
   3285 class OMPTargetSimdDirective final : public OMPLoopDirective {
   3286   friend class ASTStmtReader;
   3287 
   3288   /// Build directive with the given start and end location.
   3289   ///
   3290   /// \param StartLoc Starting location of the directive kind.
   3291   /// \param EndLoc Ending location of the directive.
   3292   /// \param CollapsedNum Number of collapsed nested loops.
   3293   /// \param NumClauses Number of clauses.
   3294   ///
   3295   OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   3296                          unsigned CollapsedNum, unsigned NumClauses)
   3297       : OMPLoopDirective(this, OMPTargetSimdDirectiveClass,
   3298                          OMPD_target_simd, StartLoc, EndLoc, CollapsedNum,
   3299                          NumClauses) {}
   3300 
   3301   /// Build an empty directive.
   3302   ///
   3303   /// \param CollapsedNum Number of collapsed nested loops.
   3304   /// \param NumClauses Number of clauses.
   3305   ///
   3306   explicit OMPTargetSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
   3307       : OMPLoopDirective(this, OMPTargetSimdDirectiveClass, OMPD_target_simd,
   3308                          SourceLocation(),SourceLocation(), CollapsedNum,
   3309                          NumClauses) {}
   3310 
   3311 public:
   3312   /// Creates directive with a list of \a Clauses.
   3313   ///
   3314   /// \param C AST context.
   3315   /// \param StartLoc Starting location of the directive kind.
   3316   /// \param EndLoc Ending Location of the directive.
   3317   /// \param CollapsedNum Number of collapsed loops.
   3318   /// \param Clauses List of clauses.
   3319   /// \param AssociatedStmt Statement, associated with the directive.
   3320   /// \param Exprs Helper expressions for CodeGen.
   3321   ///
   3322   static OMPTargetSimdDirective *
   3323   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3324          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3325          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3326 
   3327   /// Creates an empty directive with the place for \a NumClauses clauses.
   3328   ///
   3329   /// \param C AST context.
   3330   /// \param CollapsedNum Number of collapsed nested loops.
   3331   /// \param NumClauses Number of clauses.
   3332   ///
   3333   static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C,
   3334                                              unsigned NumClauses,
   3335                                              unsigned CollapsedNum,
   3336                                              EmptyShell);
   3337 
   3338   static bool classof(const Stmt *T) {
   3339     return T->getStmtClass() == OMPTargetSimdDirectiveClass;
   3340   }
   3341 };
   3342 
   3343 /// This represents '#pragma omp teams distribute' directive.
   3344 ///
   3345 /// \code
   3346 /// #pragma omp teams distribute private(a,b)
   3347 /// \endcode
   3348 /// In this example directive '#pragma omp teams distribute' has clauses
   3349 /// 'private' with the variables 'a' and 'b'
   3350 ///
   3351 class OMPTeamsDistributeDirective final : public OMPLoopDirective {
   3352   friend class ASTStmtReader;
   3353 
   3354   /// Build directive with the given start and end location.
   3355   ///
   3356   /// \param StartLoc Starting location of the directive kind.
   3357   /// \param EndLoc Ending location of the directive.
   3358   /// \param CollapsedNum Number of collapsed nested loops.
   3359   /// \param NumClauses Number of clauses.
   3360   ///
   3361   OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   3362                               unsigned CollapsedNum, unsigned NumClauses)
   3363       : OMPLoopDirective(this, OMPTeamsDistributeDirectiveClass,
   3364                          OMPD_teams_distribute, StartLoc, EndLoc,
   3365                          CollapsedNum, NumClauses) {}
   3366 
   3367   /// Build an empty directive.
   3368   ///
   3369   /// \param CollapsedNum Number of collapsed nested loops.
   3370   /// \param NumClauses Number of clauses.
   3371   ///
   3372   explicit OMPTeamsDistributeDirective(unsigned CollapsedNum,
   3373                                        unsigned NumClauses)
   3374       : OMPLoopDirective(this, OMPTeamsDistributeDirectiveClass,
   3375                          OMPD_teams_distribute, SourceLocation(),
   3376                          SourceLocation(), CollapsedNum, NumClauses) {}
   3377 
   3378 public:
   3379   /// Creates directive with a list of \a Clauses.
   3380   ///
   3381   /// \param C AST context.
   3382   /// \param StartLoc Starting location of the directive kind.
   3383   /// \param EndLoc Ending Location of the directive.
   3384   /// \param CollapsedNum Number of collapsed loops.
   3385   /// \param Clauses List of clauses.
   3386   /// \param AssociatedStmt Statement, associated with the directive.
   3387   /// \param Exprs Helper expressions for CodeGen.
   3388   ///
   3389   static OMPTeamsDistributeDirective *
   3390   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3391          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3392          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3393 
   3394   /// Creates an empty directive with the place for \a NumClauses clauses.
   3395   ///
   3396   /// \param C AST context.
   3397   /// \param CollapsedNum Number of collapsed nested loops.
   3398   /// \param NumClauses Number of clauses.
   3399   ///
   3400   static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C,
   3401                                                   unsigned NumClauses,
   3402                                                   unsigned CollapsedNum,
   3403                                                   EmptyShell);
   3404 
   3405   static bool classof(const Stmt *T) {
   3406     return T->getStmtClass() == OMPTeamsDistributeDirectiveClass;
   3407   }
   3408 };
   3409 
   3410 /// This represents '#pragma omp teams distribute simd'
   3411 /// combined directive.
   3412 ///
   3413 /// \code
   3414 /// #pragma omp teams distribute simd private(a,b)
   3415 /// \endcode
   3416 /// In this example directive '#pragma omp teams distribute simd'
   3417 /// has clause 'private' with the variables 'a' and 'b'
   3418 ///
   3419 class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective {
   3420   friend class ASTStmtReader;
   3421 
   3422   /// Build directive with the given start and end location.
   3423   ///
   3424   /// \param StartLoc Starting location of the directive kind.
   3425   /// \param EndLoc Ending location of the directive.
   3426   /// \param CollapsedNum Number of collapsed nested loops.
   3427   /// \param NumClauses Number of clauses.
   3428   ///
   3429   OMPTeamsDistributeSimdDirective(SourceLocation StartLoc,
   3430                                   SourceLocation EndLoc, unsigned CollapsedNum,
   3431                                   unsigned NumClauses)
   3432       : OMPLoopDirective(this, OMPTeamsDistributeSimdDirectiveClass,
   3433                          OMPD_teams_distribute_simd, StartLoc, EndLoc,
   3434                          CollapsedNum, NumClauses) {}
   3435 
   3436   /// Build an empty directive.
   3437   ///
   3438   /// \param CollapsedNum Number of collapsed nested loops.
   3439   /// \param NumClauses Number of clauses.
   3440   ///
   3441   explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum,
   3442                                            unsigned NumClauses)
   3443       : OMPLoopDirective(this, OMPTeamsDistributeSimdDirectiveClass,
   3444                          OMPD_teams_distribute_simd, SourceLocation(),
   3445                          SourceLocation(), CollapsedNum, NumClauses) {}
   3446 
   3447 public:
   3448   /// Creates directive with a list of \a Clauses.
   3449   ///
   3450   /// \param C AST context.
   3451   /// \param StartLoc Starting location of the directive kind.
   3452   /// \param EndLoc Ending Location of the directive.
   3453   /// \param CollapsedNum Number of collapsed loops.
   3454   /// \param Clauses List of clauses.
   3455   /// \param AssociatedStmt Statement, associated with the directive.
   3456   /// \param Exprs Helper expressions for CodeGen.
   3457   ///
   3458   static OMPTeamsDistributeSimdDirective *
   3459   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3460          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3461          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3462 
   3463   /// Creates an empty directive with the place
   3464   /// for \a NumClauses clauses.
   3465   ///
   3466   /// \param C AST context.
   3467   /// \param CollapsedNum Number of collapsed nested loops.
   3468   /// \param NumClauses Number of clauses.
   3469   ///
   3470   static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C,
   3471                                                       unsigned NumClauses,
   3472                                                       unsigned CollapsedNum,
   3473                                                       EmptyShell);
   3474 
   3475   static bool classof(const Stmt *T) {
   3476     return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass;
   3477   }
   3478 };
   3479 
   3480 /// This represents '#pragma omp teams distribute parallel for simd' composite
   3481 /// directive.
   3482 ///
   3483 /// \code
   3484 /// #pragma omp teams distribute parallel for simd private(x)
   3485 /// \endcode
   3486 /// In this example directive '#pragma omp teams distribute parallel for simd'
   3487 /// has clause 'private' with the variables 'x'
   3488 ///
   3489 class OMPTeamsDistributeParallelForSimdDirective final
   3490     : public OMPLoopDirective {
   3491   friend class ASTStmtReader;
   3492 
   3493   /// Build directive with the given start and end location.
   3494   ///
   3495   /// \param StartLoc Starting location of the directive kind.
   3496   /// \param EndLoc Ending location of the directive.
   3497   /// \param CollapsedNum Number of collapsed nested loops.
   3498   /// \param NumClauses Number of clauses.
   3499   ///
   3500   OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
   3501                                              SourceLocation EndLoc,
   3502                                              unsigned CollapsedNum,
   3503                                              unsigned NumClauses)
   3504       : OMPLoopDirective(this, OMPTeamsDistributeParallelForSimdDirectiveClass,
   3505                          OMPD_teams_distribute_parallel_for_simd, StartLoc,
   3506                          EndLoc, CollapsedNum, NumClauses) {}
   3507 
   3508   /// Build an empty directive.
   3509   ///
   3510   /// \param CollapsedNum Number of collapsed nested loops.
   3511   /// \param NumClauses Number of clauses.
   3512   ///
   3513   explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum,
   3514                                                       unsigned NumClauses)
   3515       : OMPLoopDirective(this, OMPTeamsDistributeParallelForSimdDirectiveClass,
   3516                          OMPD_teams_distribute_parallel_for_simd,
   3517                          SourceLocation(), SourceLocation(), CollapsedNum,
   3518                          NumClauses) {}
   3519 
   3520 public:
   3521   /// Creates directive with a list of \a Clauses.
   3522   ///
   3523   /// \param C AST context.
   3524   /// \param StartLoc Starting location of the directive kind.
   3525   /// \param EndLoc Ending Location of the directive.
   3526   /// \param CollapsedNum Number of collapsed loops.
   3527   /// \param Clauses List of clauses.
   3528   /// \param AssociatedStmt Statement, associated with the directive.
   3529   /// \param Exprs Helper expressions for CodeGen.
   3530   ///
   3531   static OMPTeamsDistributeParallelForSimdDirective *
   3532   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3533          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3534          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3535 
   3536   /// Creates an empty directive with the place for \a NumClauses clauses.
   3537   ///
   3538   /// \param C AST context.
   3539   /// \param CollapsedNum Number of collapsed nested loops.
   3540   /// \param NumClauses Number of clauses.
   3541   ///
   3542   static OMPTeamsDistributeParallelForSimdDirective *
   3543   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
   3544               EmptyShell);
   3545 
   3546   static bool classof(const Stmt *T) {
   3547     return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass;
   3548   }
   3549 };
   3550 
   3551 /// This represents '#pragma omp teams distribute parallel for' composite
   3552 /// directive.
   3553 ///
   3554 /// \code
   3555 /// #pragma omp teams distribute parallel for private(x)
   3556 /// \endcode
   3557 /// In this example directive '#pragma omp teams distribute parallel for'
   3558 /// has clause 'private' with the variables 'x'
   3559 ///
   3560 class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
   3561   friend class ASTStmtReader;
   3562 
   3563   /// Build directive with the given start and end location.
   3564   ///
   3565   /// \param StartLoc Starting location of the directive kind.
   3566   /// \param EndLoc Ending location of the directive.
   3567   /// \param CollapsedNum Number of collapsed nested loops.
   3568   /// \param NumClauses Number of clauses.
   3569   ///
   3570   OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc,
   3571                                          SourceLocation EndLoc,
   3572                                          unsigned CollapsedNum,
   3573                                          unsigned NumClauses)
   3574       : OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass,
   3575                          OMPD_teams_distribute_parallel_for, StartLoc, EndLoc,
   3576                          CollapsedNum, NumClauses) {}
   3577 
   3578   /// Build an empty directive.
   3579   ///
   3580   /// \param CollapsedNum Number of collapsed nested loops.
   3581   /// \param NumClauses Number of clauses.
   3582   ///
   3583   explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum,
   3584                                                   unsigned NumClauses)
   3585       : OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass,
   3586                          OMPD_teams_distribute_parallel_for, SourceLocation(),
   3587                          SourceLocation(), CollapsedNum, NumClauses) {}
   3588 
   3589 public:
   3590   /// Creates directive with a list of \a Clauses.
   3591   ///
   3592   /// \param C AST context.
   3593   /// \param StartLoc Starting location of the directive kind.
   3594   /// \param EndLoc Ending Location of the directive.
   3595   /// \param CollapsedNum Number of collapsed loops.
   3596   /// \param Clauses List of clauses.
   3597   /// \param AssociatedStmt Statement, associated with the directive.
   3598   /// \param Exprs Helper expressions for CodeGen.
   3599   ///
   3600   static OMPTeamsDistributeParallelForDirective *
   3601   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3602          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3603          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3604 
   3605   /// Creates an empty directive with the place for \a NumClauses clauses.
   3606   ///
   3607   /// \param C AST context.
   3608   /// \param CollapsedNum Number of collapsed nested loops.
   3609   /// \param NumClauses Number of clauses.
   3610   ///
   3611   static OMPTeamsDistributeParallelForDirective *
   3612   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
   3613               EmptyShell);
   3614 
   3615   static bool classof(const Stmt *T) {
   3616     return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass;
   3617   }
   3618 };
   3619 
   3620 /// This represents '#pragma omp target teams' directive.
   3621 ///
   3622 /// \code
   3623 /// #pragma omp target teams if(a>0)
   3624 /// \endcode
   3625 /// In this example directive '#pragma omp target teams' has clause 'if' with
   3626 /// condition 'a>0'.
   3627 ///
   3628 class OMPTargetTeamsDirective final : public OMPExecutableDirective {
   3629   friend class ASTStmtReader;
   3630   /// Build directive with the given start and end location.
   3631   ///
   3632   /// \param StartLoc Starting location of the directive kind.
   3633   /// \param EndLoc Ending location of the directive.
   3634   /// \param NumClauses Number of clauses.
   3635   ///
   3636   OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   3637                           unsigned NumClauses)
   3638       : OMPExecutableDirective(this, OMPTargetTeamsDirectiveClass,
   3639                                OMPD_target_teams, StartLoc, EndLoc, NumClauses,
   3640                                1) {}
   3641 
   3642   /// Build an empty directive.
   3643   ///
   3644   /// \param NumClauses Number of clauses.
   3645   ///
   3646   explicit OMPTargetTeamsDirective(unsigned NumClauses)
   3647       : OMPExecutableDirective(this, OMPTargetTeamsDirectiveClass,
   3648                                OMPD_target_teams, SourceLocation(),
   3649                                SourceLocation(), NumClauses, 1) {}
   3650 
   3651 public:
   3652   /// Creates directive with a list of \a Clauses.
   3653   ///
   3654   /// \param C AST context.
   3655   /// \param StartLoc Starting location of the directive kind.
   3656   /// \param EndLoc Ending Location of the directive.
   3657   /// \param Clauses List of clauses.
   3658   /// \param AssociatedStmt Statement, associated with the directive.
   3659   ///
   3660   static OMPTargetTeamsDirective *Create(const ASTContext &C,
   3661                                          SourceLocation StartLoc,
   3662                                          SourceLocation EndLoc,
   3663                                          ArrayRef<OMPClause *> Clauses,
   3664                                          Stmt *AssociatedStmt);
   3665 
   3666   /// Creates an empty directive with the place for \a NumClauses clauses.
   3667   ///
   3668   /// \param C AST context.
   3669   /// \param NumClauses Number of clauses.
   3670   ///
   3671   static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C,
   3672                                               unsigned NumClauses, EmptyShell);
   3673 
   3674   static bool classof(const Stmt *T) {
   3675     return T->getStmtClass() == OMPTargetTeamsDirectiveClass;
   3676   }
   3677 };
   3678 
   3679 /// This represents '#pragma omp target teams distribute' combined directive.
   3680 ///
   3681 /// \code
   3682 /// #pragma omp target teams distribute private(x)
   3683 /// \endcode
   3684 /// In this example directive '#pragma omp target teams distribute' has clause
   3685 /// 'private' with the variables 'x'
   3686 ///
   3687 class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective {
   3688   friend class ASTStmtReader;
   3689 
   3690   /// Build directive with the given start and end location.
   3691   ///
   3692   /// \param StartLoc Starting location of the directive kind.
   3693   /// \param EndLoc Ending location of the directive.
   3694   /// \param CollapsedNum Number of collapsed nested loops.
   3695   /// \param NumClauses Number of clauses.
   3696   ///
   3697   OMPTargetTeamsDistributeDirective(SourceLocation StartLoc,
   3698                                     SourceLocation EndLoc,
   3699                                     unsigned CollapsedNum, unsigned NumClauses)
   3700       : OMPLoopDirective(this, OMPTargetTeamsDistributeDirectiveClass,
   3701                          OMPD_target_teams_distribute, StartLoc, EndLoc,
   3702                          CollapsedNum, NumClauses) {}
   3703 
   3704   /// Build an empty directive.
   3705   ///
   3706   /// \param CollapsedNum Number of collapsed nested loops.
   3707   /// \param NumClauses Number of clauses.
   3708   ///
   3709   explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum,
   3710                                              unsigned NumClauses)
   3711       : OMPLoopDirective(this, OMPTargetTeamsDistributeDirectiveClass,
   3712                          OMPD_target_teams_distribute, SourceLocation(),
   3713                          SourceLocation(), CollapsedNum, NumClauses) {}
   3714 
   3715 public:
   3716   /// Creates directive with a list of \a Clauses.
   3717   ///
   3718   /// \param C AST context.
   3719   /// \param StartLoc Starting location of the directive kind.
   3720   /// \param EndLoc Ending Location of the directive.
   3721   /// \param CollapsedNum Number of collapsed loops.
   3722   /// \param Clauses List of clauses.
   3723   /// \param AssociatedStmt Statement, associated with the directive.
   3724   /// \param Exprs Helper expressions for CodeGen.
   3725   ///
   3726   static OMPTargetTeamsDistributeDirective *
   3727   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3728          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3729          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3730 
   3731   /// Creates an empty directive with the place for \a NumClauses clauses.
   3732   ///
   3733   /// \param C AST context.
   3734   /// \param CollapsedNum Number of collapsed nested loops.
   3735   /// \param NumClauses Number of clauses.
   3736   ///
   3737   static OMPTargetTeamsDistributeDirective *
   3738   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
   3739               EmptyShell);
   3740 
   3741   static bool classof(const Stmt *T) {
   3742     return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass;
   3743   }
   3744 };
   3745 
   3746 /// This represents '#pragma omp target teams distribute parallel for' combined
   3747 /// directive.
   3748 ///
   3749 /// \code
   3750 /// #pragma omp target teams distribute parallel for private(x)
   3751 /// \endcode
   3752 /// In this example directive '#pragma omp target teams distribute parallel
   3753 /// for' has clause 'private' with the variables 'x'
   3754 ///
   3755 class OMPTargetTeamsDistributeParallelForDirective final
   3756     : public OMPLoopDirective {
   3757   friend class ASTStmtReader;
   3758 
   3759   /// Build directive with the given start and end location.
   3760   ///
   3761   /// \param StartLoc Starting location of the directive kind.
   3762   /// \param EndLoc Ending location of the directive.
   3763   /// \param CollapsedNum Number of collapsed nested loops.
   3764   /// \param NumClauses Number of clauses.
   3765   ///
   3766   OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc,
   3767                                                SourceLocation EndLoc,
   3768                                                unsigned CollapsedNum,
   3769                                                unsigned NumClauses)
   3770       : OMPLoopDirective(this,
   3771                          OMPTargetTeamsDistributeParallelForDirectiveClass,
   3772                          OMPD_target_teams_distribute_parallel_for, StartLoc,
   3773                          EndLoc, CollapsedNum, NumClauses) {}
   3774 
   3775   /// Build an empty directive.
   3776   ///
   3777   /// \param CollapsedNum Number of collapsed nested loops.
   3778   /// \param NumClauses Number of clauses.
   3779   ///
   3780   explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum,
   3781                                                         unsigned NumClauses)
   3782       : OMPLoopDirective(
   3783             this, OMPTargetTeamsDistributeParallelForDirectiveClass,
   3784             OMPD_target_teams_distribute_parallel_for, SourceLocation(),
   3785             SourceLocation(), CollapsedNum, NumClauses) {}
   3786 
   3787 public:
   3788   /// Creates directive with a list of \a Clauses.
   3789   ///
   3790   /// \param C AST context.
   3791   /// \param StartLoc Starting location of the directive kind.
   3792   /// \param EndLoc Ending Location of the directive.
   3793   /// \param CollapsedNum Number of collapsed loops.
   3794   /// \param Clauses List of clauses.
   3795   /// \param AssociatedStmt Statement, associated with the directive.
   3796   /// \param Exprs Helper expressions for CodeGen.
   3797   ///
   3798   static OMPTargetTeamsDistributeParallelForDirective *
   3799   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3800          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3801          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3802 
   3803   /// Creates an empty directive with the place for \a NumClauses clauses.
   3804   ///
   3805   /// \param C AST context.
   3806   /// \param CollapsedNum Number of collapsed nested loops.
   3807   /// \param NumClauses Number of clauses.
   3808   ///
   3809   static OMPTargetTeamsDistributeParallelForDirective *
   3810   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
   3811               EmptyShell);
   3812 
   3813   static bool classof(const Stmt *T) {
   3814     return T->getStmtClass() ==
   3815            OMPTargetTeamsDistributeParallelForDirectiveClass;
   3816   }
   3817 };
   3818 
   3819 /// This represents '#pragma omp target teams distribute parallel for simd'
   3820 /// combined directive.
   3821 ///
   3822 /// \code
   3823 /// #pragma omp target teams distribute parallel for simd private(x)
   3824 /// \endcode
   3825 /// In this example directive '#pragma omp target teams distribute parallel
   3826 /// for simd' has clause 'private' with the variables 'x'
   3827 ///
   3828 class OMPTargetTeamsDistributeParallelForSimdDirective final
   3829     : public OMPLoopDirective {
   3830   friend class ASTStmtReader;
   3831 
   3832   /// Build directive with the given start and end location.
   3833   ///
   3834   /// \param StartLoc Starting location of the directive kind.
   3835   /// \param EndLoc Ending location of the directive.
   3836   /// \param CollapsedNum Number of collapsed nested loops.
   3837   /// \param NumClauses Number of clauses.
   3838   ///
   3839   OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
   3840                                                    SourceLocation EndLoc,
   3841                                                    unsigned CollapsedNum,
   3842                                                    unsigned NumClauses)
   3843       : OMPLoopDirective(this,
   3844                          OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
   3845                          OMPD_target_teams_distribute_parallel_for_simd,
   3846                          StartLoc, EndLoc, CollapsedNum, NumClauses) {}
   3847 
   3848   /// Build an empty directive.
   3849   ///
   3850   /// \param CollapsedNum Number of collapsed nested loops.
   3851   /// \param NumClauses Number of clauses.
   3852   ///
   3853   explicit OMPTargetTeamsDistributeParallelForSimdDirective(
   3854       unsigned CollapsedNum, unsigned NumClauses)
   3855       : OMPLoopDirective(
   3856             this, OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
   3857             OMPD_target_teams_distribute_parallel_for_simd, SourceLocation(),
   3858             SourceLocation(), CollapsedNum, NumClauses) {}
   3859 
   3860 public:
   3861   /// Creates directive with a list of \a Clauses.
   3862   ///
   3863   /// \param C AST context.
   3864   /// \param StartLoc Starting location of the directive kind.
   3865   /// \param EndLoc Ending Location of the directive.
   3866   /// \param CollapsedNum Number of collapsed loops.
   3867   /// \param Clauses List of clauses.
   3868   /// \param AssociatedStmt Statement, associated with the directive.
   3869   /// \param Exprs Helper expressions for CodeGen.
   3870   ///
   3871   static OMPTargetTeamsDistributeParallelForSimdDirective *
   3872   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3873          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3874          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3875 
   3876   /// Creates an empty directive with the place for \a NumClauses clauses.
   3877   ///
   3878   /// \param C AST context.
   3879   /// \param CollapsedNum Number of collapsed nested loops.
   3880   /// \param NumClauses Number of clauses.
   3881   ///
   3882   static OMPTargetTeamsDistributeParallelForSimdDirective *
   3883   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
   3884               EmptyShell);
   3885 
   3886   static bool classof(const Stmt *T) {
   3887     return T->getStmtClass() ==
   3888            OMPTargetTeamsDistributeParallelForSimdDirectiveClass;
   3889   }
   3890 };
   3891 
   3892 /// This represents '#pragma omp target teams distribute simd' combined
   3893 /// directive.
   3894 ///
   3895 /// \code
   3896 /// #pragma omp target teams distribute simd private(x)
   3897 /// \endcode
   3898 /// In this example directive '#pragma omp target teams distribute simd'
   3899 /// has clause 'private' with the variables 'x'
   3900 ///
   3901 class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective {
   3902   friend class ASTStmtReader;
   3903 
   3904   /// Build directive with the given start and end location.
   3905   ///
   3906   /// \param StartLoc Starting location of the directive kind.
   3907   /// \param EndLoc Ending location of the directive.
   3908   /// \param CollapsedNum Number of collapsed nested loops.
   3909   /// \param NumClauses Number of clauses.
   3910   ///
   3911   OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc,
   3912                                         SourceLocation EndLoc,
   3913                                         unsigned CollapsedNum,
   3914                                         unsigned NumClauses)
   3915       : OMPLoopDirective(this, OMPTargetTeamsDistributeSimdDirectiveClass,
   3916                          OMPD_target_teams_distribute_simd, StartLoc, EndLoc,
   3917                          CollapsedNum, NumClauses) {}
   3918 
   3919   /// Build an empty directive.
   3920   ///
   3921   /// \param CollapsedNum Number of collapsed nested loops.
   3922   /// \param NumClauses Number of clauses.
   3923   ///
   3924   explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum,
   3925                                                  unsigned NumClauses)
   3926       : OMPLoopDirective(this, OMPTargetTeamsDistributeSimdDirectiveClass,
   3927                          OMPD_target_teams_distribute_simd, SourceLocation(),
   3928                          SourceLocation(), CollapsedNum, NumClauses) {}
   3929 
   3930 public:
   3931   /// Creates directive with a list of \a Clauses.
   3932   ///
   3933   /// \param C AST context.
   3934   /// \param StartLoc Starting location of the directive kind.
   3935   /// \param EndLoc Ending Location of the directive.
   3936   /// \param CollapsedNum Number of collapsed loops.
   3937   /// \param Clauses List of clauses.
   3938   /// \param AssociatedStmt Statement, associated with the directive.
   3939   /// \param Exprs Helper expressions for CodeGen.
   3940   ///
   3941   static OMPTargetTeamsDistributeSimdDirective *
   3942   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3943          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3944          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3945 
   3946   /// Creates an empty directive with the place for \a NumClauses clauses.
   3947   ///
   3948   /// \param C AST context.
   3949   /// \param CollapsedNum Number of collapsed nested loops.
   3950   /// \param NumClauses Number of clauses.
   3951   ///
   3952   static OMPTargetTeamsDistributeSimdDirective *
   3953   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
   3954               EmptyShell);
   3955 
   3956   static bool classof(const Stmt *T) {
   3957     return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
   3958   }
   3959 };
   3960 
   3961 } // end namespace clang
   3962 
   3963 #endif
   3964