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 /// 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   /// 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   /// \param NumClauses Number of clauses.
   1911   ///
   1912   OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1913                         unsigned NumClauses)
   1914       : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
   1915                                StartLoc, EndLoc, NumClauses, 2) {}
   1916 
   1917   /// Build an empty directive.
   1918   /// \param NumClauses Number of clauses.
   1919   ///
   1920   explicit OMPTaskgroupDirective(unsigned NumClauses)
   1921       : OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
   1922                                SourceLocation(), SourceLocation(), NumClauses,
   1923                                2) {}
   1924 
   1925   /// Sets the task_reduction return variable.
   1926   void setReductionRef(Expr *RR) {
   1927     *std::next(child_begin(), 1) = RR;
   1928   }
   1929 
   1930 public:
   1931   /// Creates directive.
   1932   ///
   1933   /// \param C AST context.
   1934   /// \param StartLoc Starting location of the directive kind.
   1935   /// \param EndLoc Ending Location of the directive.
   1936   /// \param Clauses List of clauses.
   1937   /// \param AssociatedStmt Statement, associated with the directive.
   1938   /// \param ReductionRef Reference to the task_reduction return variable.
   1939   ///
   1940   static OMPTaskgroupDirective *
   1941   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1942          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt,
   1943          Expr *ReductionRef);
   1944 
   1945   /// Creates an empty directive.
   1946   ///
   1947   /// \param C AST context.
   1948   /// \param NumClauses Number of clauses.
   1949   ///
   1950   static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C,
   1951                                             unsigned NumClauses, EmptyShell);
   1952 
   1953 
   1954   /// Returns reference to the task_reduction return variable.
   1955   const Expr *getReductionRef() const {
   1956     return static_cast<const Expr *>(*std::next(child_begin(), 1));
   1957   }
   1958   Expr *getReductionRef() {
   1959     return static_cast<Expr *>(*std::next(child_begin(), 1));
   1960   }
   1961 
   1962   static bool classof(const Stmt *T) {
   1963     return T->getStmtClass() == OMPTaskgroupDirectiveClass;
   1964   }
   1965 };
   1966 
   1967 /// \brief This represents '#pragma omp flush' directive.
   1968 ///
   1969 /// \code
   1970 /// #pragma omp flush(a,b)
   1971 /// \endcode
   1972 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
   1973 /// and 'b'.
   1974 /// 'omp flush' directive does not have clauses but have an optional list of
   1975 /// variables to flush. This list of variables is stored within some fake clause
   1976 /// FlushClause.
   1977 class OMPFlushDirective : public OMPExecutableDirective {
   1978   friend class ASTStmtReader;
   1979   /// \brief Build directive with the given start and end location.
   1980   ///
   1981   /// \param StartLoc Starting location of the directive kind.
   1982   /// \param EndLoc Ending location of the directive.
   1983   /// \param NumClauses Number of clauses.
   1984   ///
   1985   OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1986                     unsigned NumClauses)
   1987       : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
   1988                                StartLoc, EndLoc, NumClauses, 0) {}
   1989 
   1990   /// \brief Build an empty directive.
   1991   ///
   1992   /// \param NumClauses Number of clauses.
   1993   ///
   1994   explicit OMPFlushDirective(unsigned NumClauses)
   1995       : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
   1996                                SourceLocation(), SourceLocation(), NumClauses,
   1997                                0) {}
   1998 
   1999 public:
   2000   /// \brief Creates directive with a list of \a Clauses.
   2001   ///
   2002   /// \param C AST context.
   2003   /// \param StartLoc Starting location of the directive kind.
   2004   /// \param EndLoc Ending Location of the directive.
   2005   /// \param Clauses List of clauses (only single OMPFlushClause clause is
   2006   /// allowed).
   2007   ///
   2008   static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
   2009                                    SourceLocation EndLoc,
   2010                                    ArrayRef<OMPClause *> Clauses);
   2011 
   2012   /// \brief Creates an empty directive with the place for \a NumClauses
   2013   /// clauses.
   2014   ///
   2015   /// \param C AST context.
   2016   /// \param NumClauses Number of clauses.
   2017   ///
   2018   static OMPFlushDirective *CreateEmpty(const ASTContext &C,
   2019                                         unsigned NumClauses, EmptyShell);
   2020 
   2021   static bool classof(const Stmt *T) {
   2022     return T->getStmtClass() == OMPFlushDirectiveClass;
   2023   }
   2024 };
   2025 
   2026 /// \brief This represents '#pragma omp ordered' directive.
   2027 ///
   2028 /// \code
   2029 /// #pragma omp ordered
   2030 /// \endcode
   2031 ///
   2032 class OMPOrderedDirective : public OMPExecutableDirective {
   2033   friend class ASTStmtReader;
   2034   /// \brief Build directive with the given start and end location.
   2035   ///
   2036   /// \param StartLoc Starting location of the directive kind.
   2037   /// \param EndLoc Ending location of the directive.
   2038   /// \param NumClauses Number of clauses.
   2039   ///
   2040   OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2041                       unsigned NumClauses)
   2042       : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
   2043                                StartLoc, EndLoc, NumClauses, 1) {}
   2044 
   2045   /// \brief Build an empty directive.
   2046   ///
   2047   /// \param NumClauses Number of clauses.
   2048   ///
   2049   explicit OMPOrderedDirective(unsigned NumClauses)
   2050       : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
   2051                                SourceLocation(), SourceLocation(), NumClauses,
   2052                                1) {}
   2053 
   2054 public:
   2055   /// \brief Creates directive.
   2056   ///
   2057   /// \param C AST context.
   2058   /// \param StartLoc Starting location of the directive kind.
   2059   /// \param EndLoc Ending Location of the directive.
   2060   /// \param Clauses List of clauses.
   2061   /// \param AssociatedStmt Statement, associated with the directive.
   2062   ///
   2063   static OMPOrderedDirective *
   2064   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2065          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   2066 
   2067   /// \brief Creates an empty directive.
   2068   ///
   2069   /// \param C AST context.
   2070   /// \param NumClauses Number of clauses.
   2071   ///
   2072   static OMPOrderedDirective *CreateEmpty(const ASTContext &C,
   2073                                           unsigned NumClauses, EmptyShell);
   2074 
   2075   static bool classof(const Stmt *T) {
   2076     return T->getStmtClass() == OMPOrderedDirectiveClass;
   2077   }
   2078 };
   2079 
   2080 /// \brief This represents '#pragma omp atomic' directive.
   2081 ///
   2082 /// \code
   2083 /// #pragma omp atomic capture
   2084 /// \endcode
   2085 /// In this example directive '#pragma omp atomic' has clause 'capture'.
   2086 ///
   2087 class OMPAtomicDirective : public OMPExecutableDirective {
   2088   friend class ASTStmtReader;
   2089   /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
   2090   /// have atomic expressions of forms
   2091   /// \code
   2092   /// x = x binop expr;
   2093   /// x = expr binop x;
   2094   /// \endcode
   2095   /// This field is true for the first form of the expression and false for the
   2096   /// second. Required for correct codegen of non-associative operations (like
   2097   /// << or >>).
   2098   bool IsXLHSInRHSPart;
   2099   /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
   2100   /// have atomic expressions of forms
   2101   /// \code
   2102   /// v = x; <update x>;
   2103   /// <update x>; v = x;
   2104   /// \endcode
   2105   /// This field is true for the first(postfix) form of the expression and false
   2106   /// otherwise.
   2107   bool IsPostfixUpdate;
   2108 
   2109   /// \brief Build directive with the given start and end location.
   2110   ///
   2111   /// \param StartLoc Starting location of the directive kind.
   2112   /// \param EndLoc Ending location of the directive.
   2113   /// \param NumClauses Number of clauses.
   2114   ///
   2115   OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2116                      unsigned NumClauses)
   2117       : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
   2118                                StartLoc, EndLoc, NumClauses, 5),
   2119         IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
   2120 
   2121   /// \brief Build an empty directive.
   2122   ///
   2123   /// \param NumClauses Number of clauses.
   2124   ///
   2125   explicit OMPAtomicDirective(unsigned NumClauses)
   2126       : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
   2127                                SourceLocation(), SourceLocation(), NumClauses,
   2128                                5),
   2129         IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
   2130 
   2131   /// \brief Set 'x' part of the associated expression/statement.
   2132   void setX(Expr *X) { *std::next(child_begin()) = X; }
   2133   /// \brief Set helper expression of the form
   2134   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
   2135   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
   2136   void setUpdateExpr(Expr *UE) { *std::next(child_begin(), 2) = UE; }
   2137   /// \brief Set 'v' part of the associated expression/statement.
   2138   void setV(Expr *V) { *std::next(child_begin(), 3) = V; }
   2139   /// \brief Set 'expr' part of the associated expression/statement.
   2140   void setExpr(Expr *E) { *std::next(child_begin(), 4) = E; }
   2141 
   2142 public:
   2143   /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
   2144   /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
   2145   /// detailed description of 'x', 'v' and 'expr').
   2146   ///
   2147   /// \param C AST context.
   2148   /// \param StartLoc Starting location of the directive kind.
   2149   /// \param EndLoc Ending Location of the directive.
   2150   /// \param Clauses List of clauses.
   2151   /// \param AssociatedStmt Statement, associated with the directive.
   2152   /// \param X 'x' part of the associated expression/statement.
   2153   /// \param V 'v' part of the associated expression/statement.
   2154   /// \param E 'expr' part of the associated expression/statement.
   2155   /// \param UE Helper expression of the form
   2156   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
   2157   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
   2158   /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the
   2159   /// second.
   2160   /// \param IsPostfixUpdate true if original value of 'x' must be stored in
   2161   /// 'v', not an updated one.
   2162   static OMPAtomicDirective *
   2163   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2164          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
   2165          Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate);
   2166 
   2167   /// \brief Creates an empty directive with the place for \a NumClauses
   2168   /// clauses.
   2169   ///
   2170   /// \param C AST context.
   2171   /// \param NumClauses Number of clauses.
   2172   ///
   2173   static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
   2174                                          unsigned NumClauses, EmptyShell);
   2175 
   2176   /// \brief Get 'x' part of the associated expression/statement.
   2177   Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); }
   2178   const Expr *getX() const {
   2179     return cast_or_null<Expr>(*std::next(child_begin()));
   2180   }
   2181   /// \brief Get helper expression of the form
   2182   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
   2183   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
   2184   Expr *getUpdateExpr() {
   2185     return cast_or_null<Expr>(*std::next(child_begin(), 2));
   2186   }
   2187   const Expr *getUpdateExpr() const {
   2188     return cast_or_null<Expr>(*std::next(child_begin(), 2));
   2189   }
   2190   /// \brief Return true if helper update expression has form
   2191   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
   2192   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
   2193   bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
   2194   /// \brief Return true if 'v' expression must be updated to original value of
   2195   /// 'x', false if 'v' must be updated to the new value of 'x'.
   2196   bool isPostfixUpdate() const { return IsPostfixUpdate; }
   2197   /// \brief Get 'v' part of the associated expression/statement.
   2198   Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); }
   2199   const Expr *getV() const {
   2200     return cast_or_null<Expr>(*std::next(child_begin(), 3));
   2201   }
   2202   /// \brief Get 'expr' part of the associated expression/statement.
   2203   Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 4)); }
   2204   const Expr *getExpr() const {
   2205     return cast_or_null<Expr>(*std::next(child_begin(), 4));
   2206   }
   2207 
   2208   static bool classof(const Stmt *T) {
   2209     return T->getStmtClass() == OMPAtomicDirectiveClass;
   2210   }
   2211 };
   2212 
   2213 /// \brief This represents '#pragma omp target' directive.
   2214 ///
   2215 /// \code
   2216 /// #pragma omp target if(a)
   2217 /// \endcode
   2218 /// In this example directive '#pragma omp target' has clause 'if' with
   2219 /// condition 'a'.
   2220 ///
   2221 class OMPTargetDirective : public OMPExecutableDirective {
   2222   friend class ASTStmtReader;
   2223   /// \brief Build directive with the given start and end location.
   2224   ///
   2225   /// \param StartLoc Starting location of the directive kind.
   2226   /// \param EndLoc Ending location of the directive.
   2227   /// \param NumClauses Number of clauses.
   2228   ///
   2229   OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2230                      unsigned NumClauses)
   2231       : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
   2232                                StartLoc, EndLoc, NumClauses, 1) {}
   2233 
   2234   /// \brief Build an empty directive.
   2235   ///
   2236   /// \param NumClauses Number of clauses.
   2237   ///
   2238   explicit OMPTargetDirective(unsigned NumClauses)
   2239       : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
   2240                                SourceLocation(), SourceLocation(), NumClauses,
   2241                                1) {}
   2242 
   2243 public:
   2244   /// \brief Creates directive with a list of \a Clauses.
   2245   ///
   2246   /// \param C AST context.
   2247   /// \param StartLoc Starting location of the directive kind.
   2248   /// \param EndLoc Ending Location of the directive.
   2249   /// \param Clauses List of clauses.
   2250   /// \param AssociatedStmt Statement, associated with the directive.
   2251   ///
   2252   static OMPTargetDirective *
   2253   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2254          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   2255 
   2256   /// \brief Creates an empty directive with the place for \a NumClauses
   2257   /// clauses.
   2258   ///
   2259   /// \param C AST context.
   2260   /// \param NumClauses Number of clauses.
   2261   ///
   2262   static OMPTargetDirective *CreateEmpty(const ASTContext &C,
   2263                                          unsigned NumClauses, EmptyShell);
   2264 
   2265   static bool classof(const Stmt *T) {
   2266     return T->getStmtClass() == OMPTargetDirectiveClass;
   2267   }
   2268 };
   2269 
   2270 /// \brief This represents '#pragma omp target data' directive.
   2271 ///
   2272 /// \code
   2273 /// #pragma omp target data device(0) if(a) map(b[:])
   2274 /// \endcode
   2275 /// In this example directive '#pragma omp target data' has clauses 'device'
   2276 /// with the value '0', 'if' with condition 'a' and 'map' with array
   2277 /// section 'b[:]'.
   2278 ///
   2279 class OMPTargetDataDirective : public OMPExecutableDirective {
   2280   friend class ASTStmtReader;
   2281   /// \brief Build directive with the given start and end location.
   2282   ///
   2283   /// \param StartLoc Starting location of the directive kind.
   2284   /// \param EndLoc Ending Location of the directive.
   2285   /// \param NumClauses The number of clauses.
   2286   ///
   2287   OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2288                          unsigned NumClauses)
   2289       : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
   2290                                OMPD_target_data, StartLoc, EndLoc, NumClauses,
   2291                                1) {}
   2292 
   2293   /// \brief Build an empty directive.
   2294   ///
   2295   /// \param NumClauses Number of clauses.
   2296   ///
   2297   explicit OMPTargetDataDirective(unsigned NumClauses)
   2298       : OMPExecutableDirective(this, OMPTargetDataDirectiveClass,
   2299                                OMPD_target_data, SourceLocation(),
   2300                                SourceLocation(), NumClauses, 1) {}
   2301 
   2302 public:
   2303   /// \brief Creates directive with a list of \a Clauses.
   2304   ///
   2305   /// \param C AST context.
   2306   /// \param StartLoc Starting location of the directive kind.
   2307   /// \param EndLoc Ending Location of the directive.
   2308   /// \param Clauses List of clauses.
   2309   /// \param AssociatedStmt Statement, associated with the directive.
   2310   ///
   2311   static OMPTargetDataDirective *
   2312   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2313          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   2314 
   2315   /// \brief Creates an empty directive with the place for \a N clauses.
   2316   ///
   2317   /// \param C AST context.
   2318   /// \param N The number of clauses.
   2319   ///
   2320   static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N,
   2321                                              EmptyShell);
   2322 
   2323   static bool classof(const Stmt *T) {
   2324     return T->getStmtClass() == OMPTargetDataDirectiveClass;
   2325   }
   2326 };
   2327 
   2328 /// \brief This represents '#pragma omp target enter data' directive.
   2329 ///
   2330 /// \code
   2331 /// #pragma omp target enter data device(0) if(a) map(b[:])
   2332 /// \endcode
   2333 /// In this example directive '#pragma omp target enter data' has clauses
   2334 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
   2335 /// section 'b[:]'.
   2336 ///
   2337 class OMPTargetEnterDataDirective : public OMPExecutableDirective {
   2338   friend class ASTStmtReader;
   2339   /// \brief Build directive with the given start and end location.
   2340   ///
   2341   /// \param StartLoc Starting location of the directive kind.
   2342   /// \param EndLoc Ending Location of the directive.
   2343   /// \param NumClauses The number of clauses.
   2344   ///
   2345   OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2346                               unsigned NumClauses)
   2347       : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
   2348                                OMPD_target_enter_data, StartLoc, EndLoc,
   2349                                NumClauses, /*NumChildren=*/0) {}
   2350 
   2351   /// \brief Build an empty directive.
   2352   ///
   2353   /// \param NumClauses Number of clauses.
   2354   ///
   2355   explicit OMPTargetEnterDataDirective(unsigned NumClauses)
   2356       : OMPExecutableDirective(this, OMPTargetEnterDataDirectiveClass,
   2357                                OMPD_target_enter_data, SourceLocation(),
   2358                                SourceLocation(), NumClauses,
   2359                                /*NumChildren=*/0) {}
   2360 
   2361 public:
   2362   /// \brief Creates directive with a list of \a Clauses.
   2363   ///
   2364   /// \param C AST context.
   2365   /// \param StartLoc Starting location of the directive kind.
   2366   /// \param EndLoc Ending Location of the directive.
   2367   /// \param Clauses List of clauses.
   2368   ///
   2369   static OMPTargetEnterDataDirective *Create(const ASTContext &C,
   2370                                              SourceLocation StartLoc,
   2371                                              SourceLocation EndLoc,
   2372                                              ArrayRef<OMPClause *> Clauses);
   2373 
   2374   /// \brief Creates an empty directive with the place for \a N clauses.
   2375   ///
   2376   /// \param C AST context.
   2377   /// \param N The number of clauses.
   2378   ///
   2379   static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C,
   2380                                                   unsigned N, EmptyShell);
   2381 
   2382   static bool classof(const Stmt *T) {
   2383     return T->getStmtClass() == OMPTargetEnterDataDirectiveClass;
   2384   }
   2385 };
   2386 
   2387 /// \brief This represents '#pragma omp target exit data' directive.
   2388 ///
   2389 /// \code
   2390 /// #pragma omp target exit data device(0) if(a) map(b[:])
   2391 /// \endcode
   2392 /// In this example directive '#pragma omp target exit data' has clauses
   2393 /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array
   2394 /// section 'b[:]'.
   2395 ///
   2396 class OMPTargetExitDataDirective : public OMPExecutableDirective {
   2397   friend class ASTStmtReader;
   2398   /// \brief Build directive with the given start and end location.
   2399   ///
   2400   /// \param StartLoc Starting location of the directive kind.
   2401   /// \param EndLoc Ending Location of the directive.
   2402   /// \param NumClauses The number of clauses.
   2403   ///
   2404   OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2405                              unsigned NumClauses)
   2406       : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
   2407                                OMPD_target_exit_data, StartLoc, EndLoc,
   2408                                NumClauses, /*NumChildren=*/0) {}
   2409 
   2410   /// \brief Build an empty directive.
   2411   ///
   2412   /// \param NumClauses Number of clauses.
   2413   ///
   2414   explicit OMPTargetExitDataDirective(unsigned NumClauses)
   2415       : OMPExecutableDirective(this, OMPTargetExitDataDirectiveClass,
   2416                                OMPD_target_exit_data, SourceLocation(),
   2417                                SourceLocation(), NumClauses,
   2418                                /*NumChildren=*/0) {}
   2419 
   2420 public:
   2421   /// \brief Creates directive with a list of \a Clauses.
   2422   ///
   2423   /// \param C AST context.
   2424   /// \param StartLoc Starting location of the directive kind.
   2425   /// \param EndLoc Ending Location of the directive.
   2426   /// \param Clauses List of clauses.
   2427   ///
   2428   static OMPTargetExitDataDirective *Create(const ASTContext &C,
   2429                                             SourceLocation StartLoc,
   2430                                             SourceLocation EndLoc,
   2431                                             ArrayRef<OMPClause *> Clauses);
   2432 
   2433   /// \brief Creates an empty directive with the place for \a N clauses.
   2434   ///
   2435   /// \param C AST context.
   2436   /// \param N The number of clauses.
   2437   ///
   2438   static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C,
   2439                                                  unsigned N, EmptyShell);
   2440 
   2441   static bool classof(const Stmt *T) {
   2442     return T->getStmtClass() == OMPTargetExitDataDirectiveClass;
   2443   }
   2444 };
   2445 
   2446 /// \brief This represents '#pragma omp target parallel' directive.
   2447 ///
   2448 /// \code
   2449 /// #pragma omp target parallel if(a)
   2450 /// \endcode
   2451 /// In this example directive '#pragma omp target parallel' has clause 'if' with
   2452 /// condition 'a'.
   2453 ///
   2454 class OMPTargetParallelDirective : public OMPExecutableDirective {
   2455   friend class ASTStmtReader;
   2456   /// \brief Build directive with the given start and end location.
   2457   ///
   2458   /// \param StartLoc Starting location of the directive kind.
   2459   /// \param EndLoc Ending location of the directive.
   2460   /// \param NumClauses Number of clauses.
   2461   ///
   2462   OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2463                              unsigned NumClauses)
   2464       : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass,
   2465                                OMPD_target_parallel, StartLoc, EndLoc,
   2466                                NumClauses, /*NumChildren=*/1) {}
   2467 
   2468   /// \brief Build an empty directive.
   2469   ///
   2470   /// \param NumClauses Number of clauses.
   2471   ///
   2472   explicit OMPTargetParallelDirective(unsigned NumClauses)
   2473       : OMPExecutableDirective(this, OMPTargetParallelDirectiveClass,
   2474                                OMPD_target_parallel, SourceLocation(),
   2475                                SourceLocation(), NumClauses,
   2476                                /*NumChildren=*/1) {}
   2477 
   2478 public:
   2479   /// \brief Creates directive with a list of \a Clauses.
   2480   ///
   2481   /// \param C AST context.
   2482   /// \param StartLoc Starting location of the directive kind.
   2483   /// \param EndLoc Ending Location of the directive.
   2484   /// \param Clauses List of clauses.
   2485   /// \param AssociatedStmt Statement, associated with the directive.
   2486   ///
   2487   static OMPTargetParallelDirective *
   2488   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2489          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   2490 
   2491   /// \brief Creates an empty directive with the place for \a NumClauses
   2492   /// clauses.
   2493   ///
   2494   /// \param C AST context.
   2495   /// \param NumClauses Number of clauses.
   2496   ///
   2497   static OMPTargetParallelDirective *
   2498   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
   2499 
   2500   static bool classof(const Stmt *T) {
   2501     return T->getStmtClass() == OMPTargetParallelDirectiveClass;
   2502   }
   2503 };
   2504 
   2505 /// \brief This represents '#pragma omp target parallel for' directive.
   2506 ///
   2507 /// \code
   2508 /// #pragma omp target parallel for private(a,b) reduction(+:c,d)
   2509 /// \endcode
   2510 /// In this example directive '#pragma omp target parallel for' has clauses
   2511 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
   2512 /// and variables 'c' and 'd'.
   2513 ///
   2514 class OMPTargetParallelForDirective : public OMPLoopDirective {
   2515   friend class ASTStmtReader;
   2516 
   2517   /// \brief true if current region has inner cancel directive.
   2518   bool HasCancel;
   2519 
   2520   /// \brief Build directive with the given start and end location.
   2521   ///
   2522   /// \param StartLoc Starting location of the directive kind.
   2523   /// \param EndLoc Ending location of the directive.
   2524   /// \param CollapsedNum Number of collapsed nested loops.
   2525   /// \param NumClauses Number of clauses.
   2526   ///
   2527   OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2528                                 unsigned CollapsedNum, unsigned NumClauses)
   2529       : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass,
   2530                          OMPD_target_parallel_for, StartLoc, EndLoc,
   2531                          CollapsedNum, NumClauses),
   2532         HasCancel(false) {}
   2533 
   2534   /// \brief Build an empty directive.
   2535   ///
   2536   /// \param CollapsedNum Number of collapsed nested loops.
   2537   /// \param NumClauses Number of clauses.
   2538   ///
   2539   explicit OMPTargetParallelForDirective(unsigned CollapsedNum,
   2540                                          unsigned NumClauses)
   2541       : OMPLoopDirective(this, OMPTargetParallelForDirectiveClass,
   2542                          OMPD_target_parallel_for, SourceLocation(),
   2543                          SourceLocation(), CollapsedNum, NumClauses),
   2544         HasCancel(false) {}
   2545 
   2546   /// \brief Set cancel state.
   2547   void setHasCancel(bool Has) { HasCancel = Has; }
   2548 
   2549 public:
   2550   /// \brief Creates directive with a list of \a Clauses.
   2551   ///
   2552   /// \param C AST context.
   2553   /// \param StartLoc Starting location of the directive kind.
   2554   /// \param EndLoc Ending Location of the directive.
   2555   /// \param CollapsedNum Number of collapsed loops.
   2556   /// \param Clauses List of clauses.
   2557   /// \param AssociatedStmt Statement, associated with the directive.
   2558   /// \param Exprs Helper expressions for CodeGen.
   2559   /// \param HasCancel true if current directive has inner cancel directive.
   2560   ///
   2561   static OMPTargetParallelForDirective *
   2562   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2563          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   2564          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel);
   2565 
   2566   /// \brief Creates an empty directive with the place
   2567   /// for \a NumClauses clauses.
   2568   ///
   2569   /// \param C AST context.
   2570   /// \param CollapsedNum Number of collapsed nested loops.
   2571   /// \param NumClauses Number of clauses.
   2572   ///
   2573   static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C,
   2574                                                     unsigned NumClauses,
   2575                                                     unsigned CollapsedNum,
   2576                                                     EmptyShell);
   2577 
   2578   /// \brief Return true if current directive has inner cancel directive.
   2579   bool hasCancel() const { return HasCancel; }
   2580 
   2581   static bool classof(const Stmt *T) {
   2582     return T->getStmtClass() == OMPTargetParallelForDirectiveClass;
   2583   }
   2584 };
   2585 
   2586 /// \brief This represents '#pragma omp teams' directive.
   2587 ///
   2588 /// \code
   2589 /// #pragma omp teams if(a)
   2590 /// \endcode
   2591 /// In this example directive '#pragma omp teams' has clause 'if' with
   2592 /// condition 'a'.
   2593 ///
   2594 class OMPTeamsDirective : public OMPExecutableDirective {
   2595   friend class ASTStmtReader;
   2596   /// \brief Build directive with the given start and end location.
   2597   ///
   2598   /// \param StartLoc Starting location of the directive kind.
   2599   /// \param EndLoc Ending location of the directive.
   2600   /// \param NumClauses Number of clauses.
   2601   ///
   2602   OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2603                     unsigned NumClauses)
   2604       : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
   2605                                StartLoc, EndLoc, NumClauses, 1) {}
   2606 
   2607   /// \brief Build an empty directive.
   2608   ///
   2609   /// \param NumClauses Number of clauses.
   2610   ///
   2611   explicit OMPTeamsDirective(unsigned NumClauses)
   2612       : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
   2613                                SourceLocation(), SourceLocation(), NumClauses,
   2614                                1) {}
   2615 
   2616 public:
   2617   /// \brief Creates directive with a list of \a Clauses.
   2618   ///
   2619   /// \param C AST context.
   2620   /// \param StartLoc Starting location of the directive kind.
   2621   /// \param EndLoc Ending Location of the directive.
   2622   /// \param Clauses List of clauses.
   2623   /// \param AssociatedStmt Statement, associated with the directive.
   2624   ///
   2625   static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
   2626                                    SourceLocation EndLoc,
   2627                                    ArrayRef<OMPClause *> Clauses,
   2628                                    Stmt *AssociatedStmt);
   2629 
   2630   /// \brief Creates an empty directive with the place for \a NumClauses
   2631   /// clauses.
   2632   ///
   2633   /// \param C AST context.
   2634   /// \param NumClauses Number of clauses.
   2635   ///
   2636   static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
   2637                                         unsigned NumClauses, EmptyShell);
   2638 
   2639   static bool classof(const Stmt *T) {
   2640     return T->getStmtClass() == OMPTeamsDirectiveClass;
   2641   }
   2642 };
   2643 
   2644 /// \brief This represents '#pragma omp cancellation point' directive.
   2645 ///
   2646 /// \code
   2647 /// #pragma omp cancellation point for
   2648 /// \endcode
   2649 ///
   2650 /// In this example a cancellation point is created for innermost 'for' region.
   2651 class OMPCancellationPointDirective : public OMPExecutableDirective {
   2652   friend class ASTStmtReader;
   2653   OpenMPDirectiveKind CancelRegion;
   2654   /// \brief Build directive with the given start and end location.
   2655   ///
   2656   /// \param StartLoc Starting location of the directive kind.
   2657   /// \param EndLoc Ending location of the directive.
   2658   ///
   2659   OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   2660       : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
   2661                                OMPD_cancellation_point, StartLoc, EndLoc, 0, 0),
   2662         CancelRegion(OMPD_unknown) {}
   2663 
   2664   /// \brief Build an empty directive.
   2665   ///
   2666   explicit OMPCancellationPointDirective()
   2667       : OMPExecutableDirective(this, OMPCancellationPointDirectiveClass,
   2668                                OMPD_cancellation_point, SourceLocation(),
   2669                                SourceLocation(), 0, 0),
   2670         CancelRegion(OMPD_unknown) {}
   2671 
   2672   /// \brief Set cancel region for current cancellation point.
   2673   /// \param CR Cancellation region.
   2674   void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
   2675 
   2676 public:
   2677   /// \brief Creates directive.
   2678   ///
   2679   /// \param C AST context.
   2680   /// \param StartLoc Starting location of the directive kind.
   2681   /// \param EndLoc Ending Location of the directive.
   2682   ///
   2683   static OMPCancellationPointDirective *
   2684   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2685          OpenMPDirectiveKind CancelRegion);
   2686 
   2687   /// \brief Creates an empty directive.
   2688   ///
   2689   /// \param C AST context.
   2690   ///
   2691   static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C,
   2692                                                     EmptyShell);
   2693 
   2694   /// \brief Get cancellation region for the current cancellation point.
   2695   OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
   2696 
   2697   static bool classof(const Stmt *T) {
   2698     return T->getStmtClass() == OMPCancellationPointDirectiveClass;
   2699   }
   2700 };
   2701 
   2702 /// \brief This represents '#pragma omp cancel' directive.
   2703 ///
   2704 /// \code
   2705 /// #pragma omp cancel for
   2706 /// \endcode
   2707 ///
   2708 /// In this example a cancel is created for innermost 'for' region.
   2709 class OMPCancelDirective : public OMPExecutableDirective {
   2710   friend class ASTStmtReader;
   2711   OpenMPDirectiveKind CancelRegion;
   2712   /// \brief Build directive with the given start and end location.
   2713   ///
   2714   /// \param StartLoc Starting location of the directive kind.
   2715   /// \param EndLoc Ending location of the directive.
   2716   /// \param NumClauses Number of clauses.
   2717   ///
   2718   OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2719                      unsigned NumClauses)
   2720       : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
   2721                                StartLoc, EndLoc, NumClauses, 0),
   2722         CancelRegion(OMPD_unknown) {}
   2723 
   2724   /// \brief Build an empty directive.
   2725   ///
   2726   /// \param NumClauses Number of clauses.
   2727   explicit OMPCancelDirective(unsigned NumClauses)
   2728       : OMPExecutableDirective(this, OMPCancelDirectiveClass, OMPD_cancel,
   2729                                SourceLocation(), SourceLocation(), NumClauses,
   2730                                0),
   2731         CancelRegion(OMPD_unknown) {}
   2732 
   2733   /// \brief Set cancel region for current cancellation point.
   2734   /// \param CR Cancellation region.
   2735   void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; }
   2736 
   2737 public:
   2738   /// \brief Creates directive.
   2739   ///
   2740   /// \param C AST context.
   2741   /// \param StartLoc Starting location of the directive kind.
   2742   /// \param EndLoc Ending Location of the directive.
   2743   /// \param Clauses List of clauses.
   2744   ///
   2745   static OMPCancelDirective *
   2746   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2747          ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion);
   2748 
   2749   /// \brief Creates an empty directive.
   2750   ///
   2751   /// \param C AST context.
   2752   /// \param NumClauses Number of clauses.
   2753   ///
   2754   static OMPCancelDirective *CreateEmpty(const ASTContext &C,
   2755                                          unsigned NumClauses, EmptyShell);
   2756 
   2757   /// \brief Get cancellation region for the current cancellation point.
   2758   OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; }
   2759 
   2760   static bool classof(const Stmt *T) {
   2761     return T->getStmtClass() == OMPCancelDirectiveClass;
   2762   }
   2763 };
   2764 
   2765 /// \brief This represents '#pragma omp taskloop' directive.
   2766 ///
   2767 /// \code
   2768 /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num)
   2769 /// \endcode
   2770 /// In this example directive '#pragma omp taskloop' has clauses 'private'
   2771 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
   2772 /// 'num_tasks' with expression 'num'.
   2773 ///
   2774 class OMPTaskLoopDirective : public OMPLoopDirective {
   2775   friend class ASTStmtReader;
   2776   /// \brief Build directive with the given start and end location.
   2777   ///
   2778   /// \param StartLoc Starting location of the directive kind.
   2779   /// \param EndLoc Ending location of the directive.
   2780   /// \param CollapsedNum Number of collapsed nested loops.
   2781   /// \param NumClauses Number of clauses.
   2782   ///
   2783   OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2784                        unsigned CollapsedNum, unsigned NumClauses)
   2785       : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
   2786                          StartLoc, EndLoc, CollapsedNum, NumClauses) {}
   2787 
   2788   /// \brief Build an empty directive.
   2789   ///
   2790   /// \param CollapsedNum Number of collapsed nested loops.
   2791   /// \param NumClauses Number of clauses.
   2792   ///
   2793   explicit OMPTaskLoopDirective(unsigned CollapsedNum, unsigned NumClauses)
   2794       : OMPLoopDirective(this, OMPTaskLoopDirectiveClass, OMPD_taskloop,
   2795                          SourceLocation(), SourceLocation(), CollapsedNum,
   2796                          NumClauses) {}
   2797 
   2798 public:
   2799   /// \brief Creates directive with a list of \a Clauses.
   2800   ///
   2801   /// \param C AST context.
   2802   /// \param StartLoc Starting location of the directive kind.
   2803   /// \param EndLoc Ending Location of the directive.
   2804   /// \param CollapsedNum Number of collapsed loops.
   2805   /// \param Clauses List of clauses.
   2806   /// \param AssociatedStmt Statement, associated with the directive.
   2807   /// \param Exprs Helper expressions for CodeGen.
   2808   ///
   2809   static OMPTaskLoopDirective *
   2810   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2811          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   2812          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   2813 
   2814   /// \brief Creates an empty directive with the place
   2815   /// for \a NumClauses clauses.
   2816   ///
   2817   /// \param C AST context.
   2818   /// \param CollapsedNum Number of collapsed nested loops.
   2819   /// \param NumClauses Number of clauses.
   2820   ///
   2821   static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C,
   2822                                            unsigned NumClauses,
   2823                                            unsigned CollapsedNum, EmptyShell);
   2824 
   2825   static bool classof(const Stmt *T) {
   2826     return T->getStmtClass() == OMPTaskLoopDirectiveClass;
   2827   }
   2828 };
   2829 
   2830 /// \brief This represents '#pragma omp taskloop simd' directive.
   2831 ///
   2832 /// \code
   2833 /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num)
   2834 /// \endcode
   2835 /// In this example directive '#pragma omp taskloop simd' has clauses 'private'
   2836 /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and
   2837 /// 'num_tasks' with expression 'num'.
   2838 ///
   2839 class OMPTaskLoopSimdDirective : public OMPLoopDirective {
   2840   friend class ASTStmtReader;
   2841   /// \brief Build directive with the given start and end location.
   2842   ///
   2843   /// \param StartLoc Starting location of the directive kind.
   2844   /// \param EndLoc Ending location of the directive.
   2845   /// \param CollapsedNum Number of collapsed nested loops.
   2846   /// \param NumClauses Number of clauses.
   2847   ///
   2848   OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2849                            unsigned CollapsedNum, unsigned NumClauses)
   2850       : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
   2851                          OMPD_taskloop_simd, StartLoc, EndLoc, CollapsedNum,
   2852                          NumClauses) {}
   2853 
   2854   /// \brief Build an empty directive.
   2855   ///
   2856   /// \param CollapsedNum Number of collapsed nested loops.
   2857   /// \param NumClauses Number of clauses.
   2858   ///
   2859   explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
   2860       : OMPLoopDirective(this, OMPTaskLoopSimdDirectiveClass,
   2861                          OMPD_taskloop_simd, SourceLocation(), SourceLocation(),
   2862                          CollapsedNum, NumClauses) {}
   2863 
   2864 public:
   2865   /// \brief Creates directive with a list of \a Clauses.
   2866   ///
   2867   /// \param C AST context.
   2868   /// \param StartLoc Starting location of the directive kind.
   2869   /// \param EndLoc Ending Location of the directive.
   2870   /// \param CollapsedNum Number of collapsed loops.
   2871   /// \param Clauses List of clauses.
   2872   /// \param AssociatedStmt Statement, associated with the directive.
   2873   /// \param Exprs Helper expressions for CodeGen.
   2874   ///
   2875   static OMPTaskLoopSimdDirective *
   2876   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2877          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   2878          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   2879 
   2880   /// \brief Creates an empty directive with the place
   2881   /// for \a NumClauses clauses.
   2882   ///
   2883   /// \param C AST context.
   2884   /// \param CollapsedNum Number of collapsed nested loops.
   2885   /// \param NumClauses Number of clauses.
   2886   ///
   2887   static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C,
   2888                                                unsigned NumClauses,
   2889                                                unsigned CollapsedNum,
   2890                                                EmptyShell);
   2891 
   2892   static bool classof(const Stmt *T) {
   2893     return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass;
   2894   }
   2895 };
   2896 
   2897 /// \brief This represents '#pragma omp distribute' directive.
   2898 ///
   2899 /// \code
   2900 /// #pragma omp distribute private(a,b)
   2901 /// \endcode
   2902 /// In this example directive '#pragma omp distribute' has clauses 'private'
   2903 /// with the variables 'a' and 'b'
   2904 ///
   2905 class OMPDistributeDirective : public OMPLoopDirective {
   2906   friend class ASTStmtReader;
   2907 
   2908   /// \brief Build directive with the given start and end location.
   2909   ///
   2910   /// \param StartLoc Starting location of the directive kind.
   2911   /// \param EndLoc Ending location of the directive.
   2912   /// \param CollapsedNum Number of collapsed nested loops.
   2913   /// \param NumClauses Number of clauses.
   2914   ///
   2915   OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2916                          unsigned CollapsedNum, unsigned NumClauses)
   2917       : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
   2918                          StartLoc, EndLoc, CollapsedNum, NumClauses)
   2919         {}
   2920 
   2921   /// \brief Build an empty directive.
   2922   ///
   2923   /// \param CollapsedNum Number of collapsed nested loops.
   2924   /// \param NumClauses Number of clauses.
   2925   ///
   2926   explicit OMPDistributeDirective(unsigned CollapsedNum, unsigned NumClauses)
   2927       : OMPLoopDirective(this, OMPDistributeDirectiveClass, OMPD_distribute,
   2928                          SourceLocation(), SourceLocation(), CollapsedNum,
   2929                          NumClauses)
   2930         {}
   2931 
   2932 public:
   2933   /// \brief Creates directive with a list of \a Clauses.
   2934   ///
   2935   /// \param C AST context.
   2936   /// \param StartLoc Starting location of the directive kind.
   2937   /// \param EndLoc Ending Location of the directive.
   2938   /// \param CollapsedNum Number of collapsed loops.
   2939   /// \param Clauses List of clauses.
   2940   /// \param AssociatedStmt Statement, associated with the directive.
   2941   /// \param Exprs Helper expressions for CodeGen.
   2942   ///
   2943   static OMPDistributeDirective *
   2944   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   2945          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   2946          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   2947 
   2948   /// \brief Creates an empty directive with the place
   2949   /// for \a NumClauses clauses.
   2950   ///
   2951   /// \param C AST context.
   2952   /// \param CollapsedNum Number of collapsed nested loops.
   2953   /// \param NumClauses Number of clauses.
   2954   ///
   2955   static OMPDistributeDirective *CreateEmpty(const ASTContext &C,
   2956                                              unsigned NumClauses,
   2957                                              unsigned CollapsedNum, EmptyShell);
   2958 
   2959   static bool classof(const Stmt *T) {
   2960     return T->getStmtClass() == OMPDistributeDirectiveClass;
   2961   }
   2962 };
   2963 
   2964 /// \brief This represents '#pragma omp target update' directive.
   2965 ///
   2966 /// \code
   2967 /// #pragma omp target update to(a) from(b) device(1)
   2968 /// \endcode
   2969 /// In this example directive '#pragma omp target update' has clause 'to' with
   2970 /// argument 'a', clause 'from' with argument 'b' and clause 'device' with
   2971 /// argument '1'.
   2972 ///
   2973 class OMPTargetUpdateDirective : public OMPExecutableDirective {
   2974   friend class ASTStmtReader;
   2975   /// \brief Build directive with the given start and end location.
   2976   ///
   2977   /// \param StartLoc Starting location of the directive kind.
   2978   /// \param EndLoc Ending Location of the directive.
   2979   /// \param NumClauses The number of clauses.
   2980   ///
   2981   OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   2982                            unsigned NumClauses)
   2983       : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
   2984                                OMPD_target_update, StartLoc, EndLoc, NumClauses,
   2985                                0) {}
   2986 
   2987   /// \brief Build an empty directive.
   2988   ///
   2989   /// \param NumClauses Number of clauses.
   2990   ///
   2991   explicit OMPTargetUpdateDirective(unsigned NumClauses)
   2992       : OMPExecutableDirective(this, OMPTargetUpdateDirectiveClass,
   2993                                OMPD_target_update, SourceLocation(),
   2994                                SourceLocation(), NumClauses, 0) {}
   2995 
   2996 public:
   2997   /// \brief Creates directive with a list of \a Clauses.
   2998   ///
   2999   /// \param C AST context.
   3000   /// \param StartLoc Starting location of the directive kind.
   3001   /// \param EndLoc Ending Location of the directive.
   3002   /// \param Clauses List of clauses.
   3003   ///
   3004   static OMPTargetUpdateDirective *Create(const ASTContext &C,
   3005                                           SourceLocation StartLoc,
   3006                                           SourceLocation EndLoc,
   3007                                           ArrayRef<OMPClause *> Clauses);
   3008 
   3009   /// \brief Creates an empty directive with the place for \a NumClauses
   3010   /// clauses.
   3011   ///
   3012   /// \param C AST context.
   3013   /// \param NumClauses The number of clauses.
   3014   ///
   3015   static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C,
   3016                                                unsigned NumClauses, EmptyShell);
   3017 
   3018   static bool classof(const Stmt *T) {
   3019     return T->getStmtClass() == OMPTargetUpdateDirectiveClass;
   3020   }
   3021 };
   3022 
   3023 /// \brief This represents '#pragma omp distribute parallel for' composite
   3024 ///  directive.
   3025 ///
   3026 /// \code
   3027 /// #pragma omp distribute parallel for private(a,b)
   3028 /// \endcode
   3029 /// In this example directive '#pragma omp distribute parallel for' has clause
   3030 /// 'private' with the variables 'a' and 'b'
   3031 ///
   3032 class OMPDistributeParallelForDirective : public OMPLoopDirective {
   3033   friend class ASTStmtReader;
   3034 
   3035   /// \brief Build directive with the given start and end location.
   3036   ///
   3037   /// \param StartLoc Starting location of the directive kind.
   3038   /// \param EndLoc Ending location of the directive.
   3039   /// \param CollapsedNum Number of collapsed nested loops.
   3040   /// \param NumClauses Number of clauses.
   3041   ///
   3042   OMPDistributeParallelForDirective(SourceLocation StartLoc,
   3043                                     SourceLocation EndLoc,
   3044                                     unsigned CollapsedNum, unsigned NumClauses)
   3045       : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass,
   3046                          OMPD_distribute_parallel_for, StartLoc, EndLoc,
   3047                          CollapsedNum, NumClauses) {}
   3048 
   3049   /// \brief Build an empty directive.
   3050   ///
   3051   /// \param CollapsedNum Number of collapsed nested loops.
   3052   /// \param NumClauses Number of clauses.
   3053   ///
   3054   explicit OMPDistributeParallelForDirective(unsigned CollapsedNum,
   3055                                              unsigned NumClauses)
   3056       : OMPLoopDirective(this, OMPDistributeParallelForDirectiveClass,
   3057                          OMPD_distribute_parallel_for, SourceLocation(),
   3058                          SourceLocation(), CollapsedNum, NumClauses) {}
   3059 
   3060 public:
   3061   /// \brief Creates directive with a list of \a Clauses.
   3062   ///
   3063   /// \param C AST context.
   3064   /// \param StartLoc Starting location of the directive kind.
   3065   /// \param EndLoc Ending Location of the directive.
   3066   /// \param CollapsedNum Number of collapsed loops.
   3067   /// \param Clauses List of clauses.
   3068   /// \param AssociatedStmt Statement, associated with the directive.
   3069   /// \param Exprs Helper expressions for CodeGen.
   3070   ///
   3071   static OMPDistributeParallelForDirective *
   3072   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3073          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3074          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3075 
   3076   /// \brief Creates an empty directive with the place
   3077   /// for \a NumClauses clauses.
   3078   ///
   3079   /// \param C AST context.
   3080   /// \param CollapsedNum Number of collapsed nested loops.
   3081   /// \param NumClauses Number of clauses.
   3082   ///
   3083   static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C,
   3084                                                         unsigned NumClauses,
   3085                                                         unsigned CollapsedNum,
   3086                                                         EmptyShell);
   3087 
   3088   static bool classof(const Stmt *T) {
   3089     return T->getStmtClass() == OMPDistributeParallelForDirectiveClass;
   3090   }
   3091 };
   3092 
   3093 /// This represents '#pragma omp distribute parallel for simd' composite
   3094 /// directive.
   3095 ///
   3096 /// \code
   3097 /// #pragma omp distribute parallel for simd private(x)
   3098 /// \endcode
   3099 /// In this example directive '#pragma omp distribute parallel for simd' has
   3100 /// clause 'private' with the variables 'x'
   3101 ///
   3102 class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective {
   3103   friend class ASTStmtReader;
   3104 
   3105   /// Build directive with the given start and end location.
   3106   ///
   3107   /// \param StartLoc Starting location of the directive kind.
   3108   /// \param EndLoc Ending location of the directive.
   3109   /// \param CollapsedNum Number of collapsed nested loops.
   3110   /// \param NumClauses Number of clauses.
   3111   ///
   3112   OMPDistributeParallelForSimdDirective(SourceLocation StartLoc,
   3113                                         SourceLocation EndLoc,
   3114                                         unsigned CollapsedNum,
   3115                                         unsigned NumClauses)
   3116       : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass,
   3117                          OMPD_distribute_parallel_for_simd, StartLoc,
   3118                          EndLoc, CollapsedNum, NumClauses) {}
   3119 
   3120   /// Build an empty directive.
   3121   ///
   3122   /// \param CollapsedNum Number of collapsed nested loops.
   3123   /// \param NumClauses Number of clauses.
   3124   ///
   3125   explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum,
   3126                                                  unsigned NumClauses)
   3127       : OMPLoopDirective(this, OMPDistributeParallelForSimdDirectiveClass,
   3128                          OMPD_distribute_parallel_for_simd,
   3129                          SourceLocation(), SourceLocation(), CollapsedNum,
   3130                          NumClauses) {}
   3131 
   3132 public:
   3133   /// Creates directive with a list of \a Clauses.
   3134   ///
   3135   /// \param C AST context.
   3136   /// \param StartLoc Starting location of the directive kind.
   3137   /// \param EndLoc Ending Location of the directive.
   3138   /// \param CollapsedNum Number of collapsed loops.
   3139   /// \param Clauses List of clauses.
   3140   /// \param AssociatedStmt Statement, associated with the directive.
   3141   /// \param Exprs Helper expressions for CodeGen.
   3142   ///
   3143   static OMPDistributeParallelForSimdDirective *Create(
   3144       const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3145       unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3146       Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3147 
   3148   /// Creates an empty directive with the place for \a NumClauses clauses.
   3149   ///
   3150   /// \param C AST context.
   3151   /// \param CollapsedNum Number of collapsed nested loops.
   3152   /// \param NumClauses Number of clauses.
   3153   ///
   3154   static OMPDistributeParallelForSimdDirective *CreateEmpty(
   3155       const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
   3156       EmptyShell);
   3157 
   3158   static bool classof(const Stmt *T) {
   3159     return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass;
   3160   }
   3161 };
   3162 
   3163 /// This represents '#pragma omp distribute simd' composite directive.
   3164 ///
   3165 /// \code
   3166 /// #pragma omp distribute simd private(x)
   3167 /// \endcode
   3168 /// In this example directive '#pragma omp distribute simd' has clause
   3169 /// 'private' with the variables 'x'
   3170 ///
   3171 class OMPDistributeSimdDirective final : public OMPLoopDirective {
   3172   friend class ASTStmtReader;
   3173 
   3174   /// Build directive with the given start and end location.
   3175   ///
   3176   /// \param StartLoc Starting location of the directive kind.
   3177   /// \param EndLoc Ending location of the directive.
   3178   /// \param CollapsedNum Number of collapsed nested loops.
   3179   /// \param NumClauses Number of clauses.
   3180   ///
   3181   OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   3182                              unsigned CollapsedNum, unsigned NumClauses)
   3183       : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass,
   3184                          OMPD_distribute_simd, StartLoc, EndLoc, CollapsedNum,
   3185                          NumClauses) {}
   3186 
   3187   /// Build an empty directive.
   3188   ///
   3189   /// \param CollapsedNum Number of collapsed nested loops.
   3190   /// \param NumClauses Number of clauses.
   3191   ///
   3192   explicit OMPDistributeSimdDirective(unsigned CollapsedNum,
   3193                                       unsigned NumClauses)
   3194       : OMPLoopDirective(this, OMPDistributeSimdDirectiveClass,
   3195                          OMPD_distribute_simd, SourceLocation(),
   3196                          SourceLocation(), CollapsedNum, NumClauses) {}
   3197 
   3198 public:
   3199   /// Creates directive with a list of \a Clauses.
   3200   ///
   3201   /// \param C AST context.
   3202   /// \param StartLoc Starting location of the directive kind.
   3203   /// \param EndLoc Ending Location of the directive.
   3204   /// \param CollapsedNum Number of collapsed loops.
   3205   /// \param Clauses List of clauses.
   3206   /// \param AssociatedStmt Statement, associated with the directive.
   3207   /// \param Exprs Helper expressions for CodeGen.
   3208   ///
   3209   static OMPDistributeSimdDirective *
   3210   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3211          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3212          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3213 
   3214   /// Creates an empty directive with the place for \a NumClauses clauses.
   3215   ///
   3216   /// \param C AST context.
   3217   /// \param CollapsedNum Number of collapsed nested loops.
   3218   /// \param NumClauses Number of clauses.
   3219   ///
   3220   static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C,
   3221                                                  unsigned NumClauses,
   3222                                                  unsigned CollapsedNum,
   3223                                                  EmptyShell);
   3224 
   3225   static bool classof(const Stmt *T) {
   3226     return T->getStmtClass() == OMPDistributeSimdDirectiveClass;
   3227   }
   3228 };
   3229 
   3230 /// This represents '#pragma omp target parallel for simd' directive.
   3231 ///
   3232 /// \code
   3233 /// #pragma omp target parallel for simd private(a) map(b) safelen(c)
   3234 /// \endcode
   3235 /// In this example directive '#pragma omp target parallel for simd' has clauses
   3236 /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen'
   3237 /// with the variable 'c'.
   3238 ///
   3239 class OMPTargetParallelForSimdDirective final : public OMPLoopDirective {
   3240   friend class ASTStmtReader;
   3241 
   3242   /// Build directive with the given start and end location.
   3243   ///
   3244   /// \param StartLoc Starting location of the directive kind.
   3245   /// \param EndLoc Ending location of the directive.
   3246   /// \param CollapsedNum Number of collapsed nested loops.
   3247   /// \param NumClauses Number of clauses.
   3248   ///
   3249   OMPTargetParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   3250                                 unsigned CollapsedNum, unsigned NumClauses)
   3251       : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass,
   3252                          OMPD_target_parallel_for_simd, StartLoc, EndLoc,
   3253                          CollapsedNum, NumClauses) {}
   3254 
   3255   /// Build an empty directive.
   3256   ///
   3257   /// \param CollapsedNum Number of collapsed nested loops.
   3258   /// \param NumClauses Number of clauses.
   3259   ///
   3260   explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum,
   3261                                              unsigned NumClauses)
   3262       : OMPLoopDirective(this, OMPTargetParallelForSimdDirectiveClass,
   3263                          OMPD_target_parallel_for_simd, SourceLocation(),
   3264                          SourceLocation(), CollapsedNum, NumClauses) {}
   3265 
   3266 public:
   3267   /// Creates directive with a list of \a Clauses.
   3268   ///
   3269   /// \param C AST context.
   3270   /// \param StartLoc Starting location of the directive kind.
   3271   /// \param EndLoc Ending Location of the directive.
   3272   /// \param CollapsedNum Number of collapsed loops.
   3273   /// \param Clauses List of clauses.
   3274   /// \param AssociatedStmt Statement, associated with the directive.
   3275   /// \param Exprs Helper expressions for CodeGen.
   3276   ///
   3277   static OMPTargetParallelForSimdDirective *
   3278   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3279          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3280          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3281 
   3282   /// Creates an empty directive with the place for \a NumClauses clauses.
   3283   ///
   3284   /// \param C AST context.
   3285   /// \param CollapsedNum Number of collapsed nested loops.
   3286   /// \param NumClauses Number of clauses.
   3287   ///
   3288   static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C,
   3289                                                         unsigned NumClauses,
   3290                                                         unsigned CollapsedNum,
   3291                                                         EmptyShell);
   3292 
   3293   static bool classof(const Stmt *T) {
   3294     return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass;
   3295   }
   3296 };
   3297 
   3298 /// This represents '#pragma omp target simd' directive.
   3299 ///
   3300 /// \code
   3301 /// #pragma omp target simd private(a) map(b) safelen(c)
   3302 /// \endcode
   3303 /// In this example directive '#pragma omp target simd' has clauses 'private'
   3304 /// with the variable 'a', 'map' with the variable 'b' and 'safelen' with
   3305 /// the variable 'c'.
   3306 ///
   3307 class OMPTargetSimdDirective final : public OMPLoopDirective {
   3308   friend class ASTStmtReader;
   3309 
   3310   /// Build directive with the given start and end location.
   3311   ///
   3312   /// \param StartLoc Starting location of the directive kind.
   3313   /// \param EndLoc Ending location of the directive.
   3314   /// \param CollapsedNum Number of collapsed nested loops.
   3315   /// \param NumClauses Number of clauses.
   3316   ///
   3317   OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   3318                          unsigned CollapsedNum, unsigned NumClauses)
   3319       : OMPLoopDirective(this, OMPTargetSimdDirectiveClass,
   3320                          OMPD_target_simd, StartLoc, EndLoc, CollapsedNum,
   3321                          NumClauses) {}
   3322 
   3323   /// Build an empty directive.
   3324   ///
   3325   /// \param CollapsedNum Number of collapsed nested loops.
   3326   /// \param NumClauses Number of clauses.
   3327   ///
   3328   explicit OMPTargetSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
   3329       : OMPLoopDirective(this, OMPTargetSimdDirectiveClass, OMPD_target_simd,
   3330                          SourceLocation(),SourceLocation(), CollapsedNum,
   3331                          NumClauses) {}
   3332 
   3333 public:
   3334   /// Creates directive with a list of \a Clauses.
   3335   ///
   3336   /// \param C AST context.
   3337   /// \param StartLoc Starting location of the directive kind.
   3338   /// \param EndLoc Ending Location of the directive.
   3339   /// \param CollapsedNum Number of collapsed loops.
   3340   /// \param Clauses List of clauses.
   3341   /// \param AssociatedStmt Statement, associated with the directive.
   3342   /// \param Exprs Helper expressions for CodeGen.
   3343   ///
   3344   static OMPTargetSimdDirective *
   3345   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3346          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3347          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3348 
   3349   /// Creates an empty directive with the place for \a NumClauses clauses.
   3350   ///
   3351   /// \param C AST context.
   3352   /// \param CollapsedNum Number of collapsed nested loops.
   3353   /// \param NumClauses Number of clauses.
   3354   ///
   3355   static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C,
   3356                                              unsigned NumClauses,
   3357                                              unsigned CollapsedNum,
   3358                                              EmptyShell);
   3359 
   3360   static bool classof(const Stmt *T) {
   3361     return T->getStmtClass() == OMPTargetSimdDirectiveClass;
   3362   }
   3363 };
   3364 
   3365 /// This represents '#pragma omp teams distribute' directive.
   3366 ///
   3367 /// \code
   3368 /// #pragma omp teams distribute private(a,b)
   3369 /// \endcode
   3370 /// In this example directive '#pragma omp teams distribute' has clauses
   3371 /// 'private' with the variables 'a' and 'b'
   3372 ///
   3373 class OMPTeamsDistributeDirective final : public OMPLoopDirective {
   3374   friend class ASTStmtReader;
   3375 
   3376   /// Build directive with the given start and end location.
   3377   ///
   3378   /// \param StartLoc Starting location of the directive kind.
   3379   /// \param EndLoc Ending location of the directive.
   3380   /// \param CollapsedNum Number of collapsed nested loops.
   3381   /// \param NumClauses Number of clauses.
   3382   ///
   3383   OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   3384                               unsigned CollapsedNum, unsigned NumClauses)
   3385       : OMPLoopDirective(this, OMPTeamsDistributeDirectiveClass,
   3386                          OMPD_teams_distribute, StartLoc, EndLoc,
   3387                          CollapsedNum, NumClauses) {}
   3388 
   3389   /// Build an empty directive.
   3390   ///
   3391   /// \param CollapsedNum Number of collapsed nested loops.
   3392   /// \param NumClauses Number of clauses.
   3393   ///
   3394   explicit OMPTeamsDistributeDirective(unsigned CollapsedNum,
   3395                                        unsigned NumClauses)
   3396       : OMPLoopDirective(this, OMPTeamsDistributeDirectiveClass,
   3397                          OMPD_teams_distribute, SourceLocation(),
   3398                          SourceLocation(), CollapsedNum, NumClauses) {}
   3399 
   3400 public:
   3401   /// Creates directive with a list of \a Clauses.
   3402   ///
   3403   /// \param C AST context.
   3404   /// \param StartLoc Starting location of the directive kind.
   3405   /// \param EndLoc Ending Location of the directive.
   3406   /// \param CollapsedNum Number of collapsed loops.
   3407   /// \param Clauses List of clauses.
   3408   /// \param AssociatedStmt Statement, associated with the directive.
   3409   /// \param Exprs Helper expressions for CodeGen.
   3410   ///
   3411   static OMPTeamsDistributeDirective *
   3412   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3413          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3414          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3415 
   3416   /// Creates an empty directive with the place for \a NumClauses clauses.
   3417   ///
   3418   /// \param C AST context.
   3419   /// \param CollapsedNum Number of collapsed nested loops.
   3420   /// \param NumClauses Number of clauses.
   3421   ///
   3422   static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C,
   3423                                                   unsigned NumClauses,
   3424                                                   unsigned CollapsedNum,
   3425                                                   EmptyShell);
   3426 
   3427   static bool classof(const Stmt *T) {
   3428     return T->getStmtClass() == OMPTeamsDistributeDirectiveClass;
   3429   }
   3430 };
   3431 
   3432 /// This represents '#pragma omp teams distribute simd'
   3433 /// combined directive.
   3434 ///
   3435 /// \code
   3436 /// #pragma omp teams distribute simd private(a,b)
   3437 /// \endcode
   3438 /// In this example directive '#pragma omp teams distribute simd'
   3439 /// has clause 'private' with the variables 'a' and 'b'
   3440 ///
   3441 class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective {
   3442   friend class ASTStmtReader;
   3443 
   3444   /// Build directive with the given start and end location.
   3445   ///
   3446   /// \param StartLoc Starting location of the directive kind.
   3447   /// \param EndLoc Ending location of the directive.
   3448   /// \param CollapsedNum Number of collapsed nested loops.
   3449   /// \param NumClauses Number of clauses.
   3450   ///
   3451   OMPTeamsDistributeSimdDirective(SourceLocation StartLoc,
   3452                                   SourceLocation EndLoc, unsigned CollapsedNum,
   3453                                   unsigned NumClauses)
   3454       : OMPLoopDirective(this, OMPTeamsDistributeSimdDirectiveClass,
   3455                          OMPD_teams_distribute_simd, StartLoc, EndLoc,
   3456                          CollapsedNum, NumClauses) {}
   3457 
   3458   /// Build an empty directive.
   3459   ///
   3460   /// \param CollapsedNum Number of collapsed nested loops.
   3461   /// \param NumClauses Number of clauses.
   3462   ///
   3463   explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum,
   3464                                            unsigned NumClauses)
   3465       : OMPLoopDirective(this, OMPTeamsDistributeSimdDirectiveClass,
   3466                          OMPD_teams_distribute_simd, SourceLocation(),
   3467                          SourceLocation(), CollapsedNum, NumClauses) {}
   3468 
   3469 public:
   3470   /// Creates directive with a list of \a Clauses.
   3471   ///
   3472   /// \param C AST context.
   3473   /// \param StartLoc Starting location of the directive kind.
   3474   /// \param EndLoc Ending Location of the directive.
   3475   /// \param CollapsedNum Number of collapsed loops.
   3476   /// \param Clauses List of clauses.
   3477   /// \param AssociatedStmt Statement, associated with the directive.
   3478   /// \param Exprs Helper expressions for CodeGen.
   3479   ///
   3480   static OMPTeamsDistributeSimdDirective *
   3481   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3482          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3483          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3484 
   3485   /// Creates an empty directive with the place
   3486   /// for \a NumClauses clauses.
   3487   ///
   3488   /// \param C AST context.
   3489   /// \param CollapsedNum Number of collapsed nested loops.
   3490   /// \param NumClauses Number of clauses.
   3491   ///
   3492   static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C,
   3493                                                       unsigned NumClauses,
   3494                                                       unsigned CollapsedNum,
   3495                                                       EmptyShell);
   3496 
   3497   static bool classof(const Stmt *T) {
   3498     return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass;
   3499   }
   3500 };
   3501 
   3502 /// This represents '#pragma omp teams distribute parallel for simd' composite
   3503 /// directive.
   3504 ///
   3505 /// \code
   3506 /// #pragma omp teams distribute parallel for simd private(x)
   3507 /// \endcode
   3508 /// In this example directive '#pragma omp teams distribute parallel for simd'
   3509 /// has clause 'private' with the variables 'x'
   3510 ///
   3511 class OMPTeamsDistributeParallelForSimdDirective final
   3512     : public OMPLoopDirective {
   3513   friend class ASTStmtReader;
   3514 
   3515   /// Build directive with the given start and end location.
   3516   ///
   3517   /// \param StartLoc Starting location of the directive kind.
   3518   /// \param EndLoc Ending location of the directive.
   3519   /// \param CollapsedNum Number of collapsed nested loops.
   3520   /// \param NumClauses Number of clauses.
   3521   ///
   3522   OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
   3523                                              SourceLocation EndLoc,
   3524                                              unsigned CollapsedNum,
   3525                                              unsigned NumClauses)
   3526       : OMPLoopDirective(this, OMPTeamsDistributeParallelForSimdDirectiveClass,
   3527                          OMPD_teams_distribute_parallel_for_simd, StartLoc,
   3528                          EndLoc, CollapsedNum, NumClauses) {}
   3529 
   3530   /// Build an empty directive.
   3531   ///
   3532   /// \param CollapsedNum Number of collapsed nested loops.
   3533   /// \param NumClauses Number of clauses.
   3534   ///
   3535   explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum,
   3536                                                       unsigned NumClauses)
   3537       : OMPLoopDirective(this, OMPTeamsDistributeParallelForSimdDirectiveClass,
   3538                          OMPD_teams_distribute_parallel_for_simd,
   3539                          SourceLocation(), SourceLocation(), CollapsedNum,
   3540                          NumClauses) {}
   3541 
   3542 public:
   3543   /// Creates directive with a list of \a Clauses.
   3544   ///
   3545   /// \param C AST context.
   3546   /// \param StartLoc Starting location of the directive kind.
   3547   /// \param EndLoc Ending Location of the directive.
   3548   /// \param CollapsedNum Number of collapsed loops.
   3549   /// \param Clauses List of clauses.
   3550   /// \param AssociatedStmt Statement, associated with the directive.
   3551   /// \param Exprs Helper expressions for CodeGen.
   3552   ///
   3553   static OMPTeamsDistributeParallelForSimdDirective *
   3554   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3555          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3556          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3557 
   3558   /// Creates an empty directive with the place for \a NumClauses clauses.
   3559   ///
   3560   /// \param C AST context.
   3561   /// \param CollapsedNum Number of collapsed nested loops.
   3562   /// \param NumClauses Number of clauses.
   3563   ///
   3564   static OMPTeamsDistributeParallelForSimdDirective *
   3565   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
   3566               EmptyShell);
   3567 
   3568   static bool classof(const Stmt *T) {
   3569     return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass;
   3570   }
   3571 };
   3572 
   3573 /// This represents '#pragma omp teams distribute parallel for' composite
   3574 /// directive.
   3575 ///
   3576 /// \code
   3577 /// #pragma omp teams distribute parallel for private(x)
   3578 /// \endcode
   3579 /// In this example directive '#pragma omp teams distribute parallel for'
   3580 /// has clause 'private' with the variables 'x'
   3581 ///
   3582 class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective {
   3583   friend class ASTStmtReader;
   3584 
   3585   /// Build directive with the given start and end location.
   3586   ///
   3587   /// \param StartLoc Starting location of the directive kind.
   3588   /// \param EndLoc Ending location of the directive.
   3589   /// \param CollapsedNum Number of collapsed nested loops.
   3590   /// \param NumClauses Number of clauses.
   3591   ///
   3592   OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc,
   3593                                          SourceLocation EndLoc,
   3594                                          unsigned CollapsedNum,
   3595                                          unsigned NumClauses)
   3596       : OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass,
   3597                          OMPD_teams_distribute_parallel_for, StartLoc, EndLoc,
   3598                          CollapsedNum, NumClauses) {}
   3599 
   3600   /// Build an empty directive.
   3601   ///
   3602   /// \param CollapsedNum Number of collapsed nested loops.
   3603   /// \param NumClauses Number of clauses.
   3604   ///
   3605   explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum,
   3606                                                   unsigned NumClauses)
   3607       : OMPLoopDirective(this, OMPTeamsDistributeParallelForDirectiveClass,
   3608                          OMPD_teams_distribute_parallel_for, SourceLocation(),
   3609                          SourceLocation(), CollapsedNum, NumClauses) {}
   3610 
   3611 public:
   3612   /// Creates directive with a list of \a Clauses.
   3613   ///
   3614   /// \param C AST context.
   3615   /// \param StartLoc Starting location of the directive kind.
   3616   /// \param EndLoc Ending Location of the directive.
   3617   /// \param CollapsedNum Number of collapsed loops.
   3618   /// \param Clauses List of clauses.
   3619   /// \param AssociatedStmt Statement, associated with the directive.
   3620   /// \param Exprs Helper expressions for CodeGen.
   3621   ///
   3622   static OMPTeamsDistributeParallelForDirective *
   3623   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3624          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3625          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3626 
   3627   /// Creates an empty directive with the place for \a NumClauses clauses.
   3628   ///
   3629   /// \param C AST context.
   3630   /// \param CollapsedNum Number of collapsed nested loops.
   3631   /// \param NumClauses Number of clauses.
   3632   ///
   3633   static OMPTeamsDistributeParallelForDirective *
   3634   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
   3635               EmptyShell);
   3636 
   3637   static bool classof(const Stmt *T) {
   3638     return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass;
   3639   }
   3640 };
   3641 
   3642 /// This represents '#pragma omp target teams' directive.
   3643 ///
   3644 /// \code
   3645 /// #pragma omp target teams if(a>0)
   3646 /// \endcode
   3647 /// In this example directive '#pragma omp target teams' has clause 'if' with
   3648 /// condition 'a>0'.
   3649 ///
   3650 class OMPTargetTeamsDirective final : public OMPExecutableDirective {
   3651   friend class ASTStmtReader;
   3652   /// Build directive with the given start and end location.
   3653   ///
   3654   /// \param StartLoc Starting location of the directive kind.
   3655   /// \param EndLoc Ending location of the directive.
   3656   /// \param NumClauses Number of clauses.
   3657   ///
   3658   OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   3659                           unsigned NumClauses)
   3660       : OMPExecutableDirective(this, OMPTargetTeamsDirectiveClass,
   3661                                OMPD_target_teams, StartLoc, EndLoc, NumClauses,
   3662                                1) {}
   3663 
   3664   /// Build an empty directive.
   3665   ///
   3666   /// \param NumClauses Number of clauses.
   3667   ///
   3668   explicit OMPTargetTeamsDirective(unsigned NumClauses)
   3669       : OMPExecutableDirective(this, OMPTargetTeamsDirectiveClass,
   3670                                OMPD_target_teams, SourceLocation(),
   3671                                SourceLocation(), NumClauses, 1) {}
   3672 
   3673 public:
   3674   /// Creates directive with a list of \a Clauses.
   3675   ///
   3676   /// \param C AST context.
   3677   /// \param StartLoc Starting location of the directive kind.
   3678   /// \param EndLoc Ending Location of the directive.
   3679   /// \param Clauses List of clauses.
   3680   /// \param AssociatedStmt Statement, associated with the directive.
   3681   ///
   3682   static OMPTargetTeamsDirective *Create(const ASTContext &C,
   3683                                          SourceLocation StartLoc,
   3684                                          SourceLocation EndLoc,
   3685                                          ArrayRef<OMPClause *> Clauses,
   3686                                          Stmt *AssociatedStmt);
   3687 
   3688   /// Creates an empty directive with the place for \a NumClauses clauses.
   3689   ///
   3690   /// \param C AST context.
   3691   /// \param NumClauses Number of clauses.
   3692   ///
   3693   static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C,
   3694                                               unsigned NumClauses, EmptyShell);
   3695 
   3696   static bool classof(const Stmt *T) {
   3697     return T->getStmtClass() == OMPTargetTeamsDirectiveClass;
   3698   }
   3699 };
   3700 
   3701 /// This represents '#pragma omp target teams distribute' combined directive.
   3702 ///
   3703 /// \code
   3704 /// #pragma omp target teams distribute private(x)
   3705 /// \endcode
   3706 /// In this example directive '#pragma omp target teams distribute' has clause
   3707 /// 'private' with the variables 'x'
   3708 ///
   3709 class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective {
   3710   friend class ASTStmtReader;
   3711 
   3712   /// Build directive with the given start and end location.
   3713   ///
   3714   /// \param StartLoc Starting location of the directive kind.
   3715   /// \param EndLoc Ending location of the directive.
   3716   /// \param CollapsedNum Number of collapsed nested loops.
   3717   /// \param NumClauses Number of clauses.
   3718   ///
   3719   OMPTargetTeamsDistributeDirective(SourceLocation StartLoc,
   3720                                     SourceLocation EndLoc,
   3721                                     unsigned CollapsedNum, unsigned NumClauses)
   3722       : OMPLoopDirective(this, OMPTargetTeamsDistributeDirectiveClass,
   3723                          OMPD_target_teams_distribute, StartLoc, EndLoc,
   3724                          CollapsedNum, NumClauses) {}
   3725 
   3726   /// Build an empty directive.
   3727   ///
   3728   /// \param CollapsedNum Number of collapsed nested loops.
   3729   /// \param NumClauses Number of clauses.
   3730   ///
   3731   explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum,
   3732                                              unsigned NumClauses)
   3733       : OMPLoopDirective(this, OMPTargetTeamsDistributeDirectiveClass,
   3734                          OMPD_target_teams_distribute, SourceLocation(),
   3735                          SourceLocation(), CollapsedNum, NumClauses) {}
   3736 
   3737 public:
   3738   /// Creates directive with a list of \a Clauses.
   3739   ///
   3740   /// \param C AST context.
   3741   /// \param StartLoc Starting location of the directive kind.
   3742   /// \param EndLoc Ending Location of the directive.
   3743   /// \param CollapsedNum Number of collapsed loops.
   3744   /// \param Clauses List of clauses.
   3745   /// \param AssociatedStmt Statement, associated with the directive.
   3746   /// \param Exprs Helper expressions for CodeGen.
   3747   ///
   3748   static OMPTargetTeamsDistributeDirective *
   3749   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3750          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3751          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3752 
   3753   /// Creates an empty directive with the place for \a NumClauses clauses.
   3754   ///
   3755   /// \param C AST context.
   3756   /// \param CollapsedNum Number of collapsed nested loops.
   3757   /// \param NumClauses Number of clauses.
   3758   ///
   3759   static OMPTargetTeamsDistributeDirective *
   3760   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
   3761               EmptyShell);
   3762 
   3763   static bool classof(const Stmt *T) {
   3764     return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass;
   3765   }
   3766 };
   3767 
   3768 /// This represents '#pragma omp target teams distribute parallel for' combined
   3769 /// directive.
   3770 ///
   3771 /// \code
   3772 /// #pragma omp target teams distribute parallel for private(x)
   3773 /// \endcode
   3774 /// In this example directive '#pragma omp target teams distribute parallel
   3775 /// for' has clause 'private' with the variables 'x'
   3776 ///
   3777 class OMPTargetTeamsDistributeParallelForDirective final
   3778     : public OMPLoopDirective {
   3779   friend class ASTStmtReader;
   3780 
   3781   /// Build directive with the given start and end location.
   3782   ///
   3783   /// \param StartLoc Starting location of the directive kind.
   3784   /// \param EndLoc Ending location of the directive.
   3785   /// \param CollapsedNum Number of collapsed nested loops.
   3786   /// \param NumClauses Number of clauses.
   3787   ///
   3788   OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc,
   3789                                                SourceLocation EndLoc,
   3790                                                unsigned CollapsedNum,
   3791                                                unsigned NumClauses)
   3792       : OMPLoopDirective(this,
   3793                          OMPTargetTeamsDistributeParallelForDirectiveClass,
   3794                          OMPD_target_teams_distribute_parallel_for, StartLoc,
   3795                          EndLoc, CollapsedNum, NumClauses) {}
   3796 
   3797   /// Build an empty directive.
   3798   ///
   3799   /// \param CollapsedNum Number of collapsed nested loops.
   3800   /// \param NumClauses Number of clauses.
   3801   ///
   3802   explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum,
   3803                                                         unsigned NumClauses)
   3804       : OMPLoopDirective(
   3805             this, OMPTargetTeamsDistributeParallelForDirectiveClass,
   3806             OMPD_target_teams_distribute_parallel_for, SourceLocation(),
   3807             SourceLocation(), CollapsedNum, NumClauses) {}
   3808 
   3809 public:
   3810   /// Creates directive with a list of \a Clauses.
   3811   ///
   3812   /// \param C AST context.
   3813   /// \param StartLoc Starting location of the directive kind.
   3814   /// \param EndLoc Ending Location of the directive.
   3815   /// \param CollapsedNum Number of collapsed loops.
   3816   /// \param Clauses List of clauses.
   3817   /// \param AssociatedStmt Statement, associated with the directive.
   3818   /// \param Exprs Helper expressions for CodeGen.
   3819   ///
   3820   static OMPTargetTeamsDistributeParallelForDirective *
   3821   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3822          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3823          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3824 
   3825   /// Creates an empty directive with the place for \a NumClauses clauses.
   3826   ///
   3827   /// \param C AST context.
   3828   /// \param CollapsedNum Number of collapsed nested loops.
   3829   /// \param NumClauses Number of clauses.
   3830   ///
   3831   static OMPTargetTeamsDistributeParallelForDirective *
   3832   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
   3833               EmptyShell);
   3834 
   3835   static bool classof(const Stmt *T) {
   3836     return T->getStmtClass() ==
   3837            OMPTargetTeamsDistributeParallelForDirectiveClass;
   3838   }
   3839 };
   3840 
   3841 /// This represents '#pragma omp target teams distribute parallel for simd'
   3842 /// combined directive.
   3843 ///
   3844 /// \code
   3845 /// #pragma omp target teams distribute parallel for simd private(x)
   3846 /// \endcode
   3847 /// In this example directive '#pragma omp target teams distribute parallel
   3848 /// for simd' has clause 'private' with the variables 'x'
   3849 ///
   3850 class OMPTargetTeamsDistributeParallelForSimdDirective final
   3851     : public OMPLoopDirective {
   3852   friend class ASTStmtReader;
   3853 
   3854   /// Build directive with the given start and end location.
   3855   ///
   3856   /// \param StartLoc Starting location of the directive kind.
   3857   /// \param EndLoc Ending location of the directive.
   3858   /// \param CollapsedNum Number of collapsed nested loops.
   3859   /// \param NumClauses Number of clauses.
   3860   ///
   3861   OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc,
   3862                                                    SourceLocation EndLoc,
   3863                                                    unsigned CollapsedNum,
   3864                                                    unsigned NumClauses)
   3865       : OMPLoopDirective(this,
   3866                          OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
   3867                          OMPD_target_teams_distribute_parallel_for_simd,
   3868                          StartLoc, EndLoc, CollapsedNum, NumClauses) {}
   3869 
   3870   /// Build an empty directive.
   3871   ///
   3872   /// \param CollapsedNum Number of collapsed nested loops.
   3873   /// \param NumClauses Number of clauses.
   3874   ///
   3875   explicit OMPTargetTeamsDistributeParallelForSimdDirective(
   3876       unsigned CollapsedNum, unsigned NumClauses)
   3877       : OMPLoopDirective(
   3878             this, OMPTargetTeamsDistributeParallelForSimdDirectiveClass,
   3879             OMPD_target_teams_distribute_parallel_for_simd, SourceLocation(),
   3880             SourceLocation(), CollapsedNum, NumClauses) {}
   3881 
   3882 public:
   3883   /// Creates directive with a list of \a Clauses.
   3884   ///
   3885   /// \param C AST context.
   3886   /// \param StartLoc Starting location of the directive kind.
   3887   /// \param EndLoc Ending Location of the directive.
   3888   /// \param CollapsedNum Number of collapsed loops.
   3889   /// \param Clauses List of clauses.
   3890   /// \param AssociatedStmt Statement, associated with the directive.
   3891   /// \param Exprs Helper expressions for CodeGen.
   3892   ///
   3893   static OMPTargetTeamsDistributeParallelForSimdDirective *
   3894   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3895          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3896          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3897 
   3898   /// Creates an empty directive with the place for \a NumClauses clauses.
   3899   ///
   3900   /// \param C AST context.
   3901   /// \param CollapsedNum Number of collapsed nested loops.
   3902   /// \param NumClauses Number of clauses.
   3903   ///
   3904   static OMPTargetTeamsDistributeParallelForSimdDirective *
   3905   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
   3906               EmptyShell);
   3907 
   3908   static bool classof(const Stmt *T) {
   3909     return T->getStmtClass() ==
   3910            OMPTargetTeamsDistributeParallelForSimdDirectiveClass;
   3911   }
   3912 };
   3913 
   3914 /// This represents '#pragma omp target teams distribute simd' combined
   3915 /// directive.
   3916 ///
   3917 /// \code
   3918 /// #pragma omp target teams distribute simd private(x)
   3919 /// \endcode
   3920 /// In this example directive '#pragma omp target teams distribute simd'
   3921 /// has clause 'private' with the variables 'x'
   3922 ///
   3923 class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective {
   3924   friend class ASTStmtReader;
   3925 
   3926   /// Build directive with the given start and end location.
   3927   ///
   3928   /// \param StartLoc Starting location of the directive kind.
   3929   /// \param EndLoc Ending location of the directive.
   3930   /// \param CollapsedNum Number of collapsed nested loops.
   3931   /// \param NumClauses Number of clauses.
   3932   ///
   3933   OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc,
   3934                                         SourceLocation EndLoc,
   3935                                         unsigned CollapsedNum,
   3936                                         unsigned NumClauses)
   3937       : OMPLoopDirective(this, OMPTargetTeamsDistributeSimdDirectiveClass,
   3938                          OMPD_target_teams_distribute_simd, StartLoc, EndLoc,
   3939                          CollapsedNum, NumClauses) {}
   3940 
   3941   /// Build an empty directive.
   3942   ///
   3943   /// \param CollapsedNum Number of collapsed nested loops.
   3944   /// \param NumClauses Number of clauses.
   3945   ///
   3946   explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum,
   3947                                                  unsigned NumClauses)
   3948       : OMPLoopDirective(this, OMPTargetTeamsDistributeSimdDirectiveClass,
   3949                          OMPD_target_teams_distribute_simd, SourceLocation(),
   3950                          SourceLocation(), CollapsedNum, NumClauses) {}
   3951 
   3952 public:
   3953   /// Creates directive with a list of \a Clauses.
   3954   ///
   3955   /// \param C AST context.
   3956   /// \param StartLoc Starting location of the directive kind.
   3957   /// \param EndLoc Ending Location of the directive.
   3958   /// \param CollapsedNum Number of collapsed loops.
   3959   /// \param Clauses List of clauses.
   3960   /// \param AssociatedStmt Statement, associated with the directive.
   3961   /// \param Exprs Helper expressions for CodeGen.
   3962   ///
   3963   static OMPTargetTeamsDistributeSimdDirective *
   3964   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   3965          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   3966          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   3967 
   3968   /// Creates an empty directive with the place for \a NumClauses clauses.
   3969   ///
   3970   /// \param C AST context.
   3971   /// \param CollapsedNum Number of collapsed nested loops.
   3972   /// \param NumClauses Number of clauses.
   3973   ///
   3974   static OMPTargetTeamsDistributeSimdDirective *
   3975   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum,
   3976               EmptyShell);
   3977 
   3978   static bool classof(const Stmt *T) {
   3979     return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass;
   3980   }
   3981 };
   3982 
   3983 } // end namespace clang
   3984 
   3985 #endif
   3986