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