Home | History | Annotate | Download | only in AST
      1 //===- StmtOpenMP.h - Classes for OpenMP directives  ------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 /// \file
     10 /// \brief This file defines OpenMP AST classes for executable directives and
     11 /// clauses.
     12 ///
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_CLANG_AST_STMTOPENMP_H
     16 #define LLVM_CLANG_AST_STMTOPENMP_H
     17 
     18 #include "clang/AST/Expr.h"
     19 #include "clang/AST/OpenMPClause.h"
     20 #include "clang/AST/Stmt.h"
     21 #include "clang/Basic/OpenMPKinds.h"
     22 #include "clang/Basic/SourceLocation.h"
     23 
     24 namespace clang {
     25 
     26 //===----------------------------------------------------------------------===//
     27 // AST classes for directives.
     28 //===----------------------------------------------------------------------===//
     29 
     30 /// \brief This is a basic class for representing single OpenMP executable
     31 /// directive.
     32 ///
     33 class OMPExecutableDirective : public Stmt {
     34   friend class ASTStmtReader;
     35   /// \brief Kind of the directive.
     36   OpenMPDirectiveKind Kind;
     37   /// \brief Starting location of the directive (directive keyword).
     38   SourceLocation StartLoc;
     39   /// \brief Ending location of the directive.
     40   SourceLocation EndLoc;
     41   /// \brief Numbers of clauses.
     42   const unsigned NumClauses;
     43   /// \brief Number of child expressions/stmts.
     44   const unsigned NumChildren;
     45   /// \brief Offset from this to the start of clauses.
     46   /// There are NumClauses pointers to clauses, they are followed by
     47   /// NumChildren pointers to child stmts/exprs (if the directive type
     48   /// requires an associated stmt, then it has to be the first of them).
     49   const unsigned ClausesOffset;
     50 
     51   /// \brief Get the clauses storage.
     52   MutableArrayRef<OMPClause *> getClauses() {
     53     OMPClause **ClauseStorage = reinterpret_cast<OMPClause **>(
     54         reinterpret_cast<char *>(this) + ClausesOffset);
     55     return MutableArrayRef<OMPClause *>(ClauseStorage, NumClauses);
     56   }
     57 
     58 protected:
     59   /// \brief Build instance of directive of class \a K.
     60   ///
     61   /// \param SC Statement class.
     62   /// \param K Kind of OpenMP directive.
     63   /// \param StartLoc Starting location of the directive (directive keyword).
     64   /// \param EndLoc Ending location of the directive.
     65   ///
     66   template <typename T>
     67   OMPExecutableDirective(const T *, StmtClass SC, OpenMPDirectiveKind K,
     68                          SourceLocation StartLoc, SourceLocation EndLoc,
     69                          unsigned NumClauses, unsigned NumChildren)
     70       : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)),
     71         EndLoc(std::move(EndLoc)), NumClauses(NumClauses),
     72         NumChildren(NumChildren),
     73         ClausesOffset(llvm::RoundUpToAlignment(sizeof(T),
     74                                                llvm::alignOf<OMPClause *>())) {}
     75 
     76   /// \brief Sets the list of variables for this clause.
     77   ///
     78   /// \param Clauses The list of clauses for the directive.
     79   ///
     80   void setClauses(ArrayRef<OMPClause *> Clauses);
     81 
     82   /// \brief Set the associated statement for the directive.
     83   ///
     84   /// /param S Associated statement.
     85   ///
     86   void setAssociatedStmt(Stmt *S) {
     87     assert(hasAssociatedStmt() && "no associated statement.");
     88     *child_begin() = S;
     89   }
     90 
     91 public:
     92   /// \brief Iterates over a filtered subrange of clauses applied to a
     93   /// directive.
     94   ///
     95   /// This iterator visits only those declarations that meet some run-time
     96   /// criteria.
     97   template <class FilterPredicate> class filtered_clause_iterator {
     98   protected:
     99     ArrayRef<OMPClause *>::const_iterator Current;
    100     ArrayRef<OMPClause *>::const_iterator End;
    101     FilterPredicate Pred;
    102     void SkipToNextClause() {
    103       while (Current != End && !Pred(*Current))
    104         ++Current;
    105     }
    106 
    107   public:
    108     typedef const OMPClause *value_type;
    109     filtered_clause_iterator() : Current(), End() {}
    110     filtered_clause_iterator(ArrayRef<OMPClause *> Arr, FilterPredicate Pred)
    111         : Current(Arr.begin()), End(Arr.end()), Pred(Pred) {
    112       SkipToNextClause();
    113     }
    114     value_type operator*() const { return *Current; }
    115     value_type operator->() const { return *Current; }
    116     filtered_clause_iterator &operator++() {
    117       ++Current;
    118       SkipToNextClause();
    119       return *this;
    120     }
    121 
    122     filtered_clause_iterator operator++(int) {
    123       filtered_clause_iterator tmp(*this);
    124       ++(*this);
    125       return tmp;
    126     }
    127 
    128     bool operator!() { return Current == End; }
    129     operator bool() { return Current != End; }
    130     bool empty() const { return Current == End; }
    131   };
    132 
    133   /// \brief A filter to iterate over 'linear' clauses using a C++ range
    134   /// for loop.
    135   struct linear_filter : public filtered_clause_iterator<
    136                              std::function<bool(const OMPClause *)> > {
    137     linear_filter(ArrayRef<OMPClause *> Arr)
    138         : filtered_clause_iterator(Arr, [](const OMPClause *C)->bool {
    139             return C->getClauseKind() == OMPC_linear;
    140           }) {}
    141     const OMPLinearClause *operator*() const {
    142       return cast<OMPLinearClause>(*Current);
    143     }
    144     const OMPLinearClause *operator->() const {
    145       return cast<OMPLinearClause>(*Current);
    146     }
    147     friend linear_filter begin(const linear_filter &range) { return range; }
    148     friend linear_filter end(const linear_filter &range) {
    149       return linear_filter(ArrayRef<OMPClause *>(range.End, range.End));
    150     }
    151   };
    152 
    153   /// \brief Gets a single clause of the specified kind \a K associated with the
    154   /// current directive iff there is only one clause of this kind (and assertion
    155   /// is fired if there is more than one clause is associated with the
    156   /// directive). Returns nullptr if no clause of kind \a K is associated with
    157   /// the directive.
    158   const OMPClause *getSingleClause(OpenMPClauseKind K) const;
    159 
    160   /// \brief Returns starting location of directive kind.
    161   SourceLocation getLocStart() const { return StartLoc; }
    162   /// \brief Returns ending location of directive.
    163   SourceLocation getLocEnd() const { return EndLoc; }
    164 
    165   /// \brief Set starting location of directive kind.
    166   ///
    167   /// \param Loc New starting location of directive.
    168   ///
    169   void setLocStart(SourceLocation Loc) { StartLoc = Loc; }
    170   /// \brief Set ending location of directive.
    171   ///
    172   /// \param Loc New ending location of directive.
    173   ///
    174   void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }
    175 
    176   /// \brief Get number of clauses.
    177   unsigned getNumClauses() const { return NumClauses; }
    178 
    179   /// \brief Returns specified clause.
    180   ///
    181   /// \param i Number of clause.
    182   ///
    183   OMPClause *getClause(unsigned i) const { return clauses()[i]; }
    184 
    185   /// \brief Returns true if directive has associated statement.
    186   bool hasAssociatedStmt() const { return NumChildren > 0; }
    187 
    188   /// \brief Returns statement associated with the directive.
    189   Stmt *getAssociatedStmt() const {
    190     assert(hasAssociatedStmt() && "no associated statement.");
    191     return const_cast<Stmt *>(*child_begin());
    192   }
    193 
    194   OpenMPDirectiveKind getDirectiveKind() const { return Kind; }
    195 
    196   static bool classof(const Stmt *S) {
    197     return S->getStmtClass() >= firstOMPExecutableDirectiveConstant &&
    198            S->getStmtClass() <= lastOMPExecutableDirectiveConstant;
    199   }
    200 
    201   child_range children() {
    202     if (!hasAssociatedStmt())
    203       return child_range();
    204     Stmt **ChildStorage = reinterpret_cast<Stmt **>(getClauses().end());
    205     return child_range(ChildStorage, ChildStorage + NumChildren);
    206   }
    207 
    208   ArrayRef<OMPClause *> clauses() { return getClauses(); }
    209 
    210   ArrayRef<OMPClause *> clauses() const {
    211     return const_cast<OMPExecutableDirective *>(this)->getClauses();
    212   }
    213 };
    214 
    215 /// \brief This represents '#pragma omp parallel' directive.
    216 ///
    217 /// \code
    218 /// #pragma omp parallel private(a,b) reduction(+: c,d)
    219 /// \endcode
    220 /// In this example directive '#pragma omp parallel' has clauses 'private'
    221 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
    222 /// variables 'c' and 'd'.
    223 ///
    224 class OMPParallelDirective : public OMPExecutableDirective {
    225   /// \brief Build directive with the given start and end location.
    226   ///
    227   /// \param StartLoc Starting location of the directive (directive keyword).
    228   /// \param EndLoc Ending Location of the directive.
    229   ///
    230   OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    231                        unsigned NumClauses)
    232       : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
    233                                StartLoc, EndLoc, NumClauses, 1) {}
    234 
    235   /// \brief Build an empty directive.
    236   ///
    237   /// \param NumClauses Number of clauses.
    238   ///
    239   explicit OMPParallelDirective(unsigned NumClauses)
    240       : OMPExecutableDirective(this, OMPParallelDirectiveClass, OMPD_parallel,
    241                                SourceLocation(), SourceLocation(), NumClauses,
    242                                1) {}
    243 
    244 public:
    245   /// \brief Creates directive with a list of \a Clauses.
    246   ///
    247   /// \param C AST context.
    248   /// \param StartLoc Starting location of the directive kind.
    249   /// \param EndLoc Ending Location of the directive.
    250   /// \param Clauses List of clauses.
    251   /// \param AssociatedStmt Statement associated with the directive.
    252   ///
    253   static OMPParallelDirective *
    254   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
    255          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
    256 
    257   /// \brief Creates an empty directive with the place for \a N clauses.
    258   ///
    259   /// \param C AST context.
    260   /// \param NumClauses Number of clauses.
    261   ///
    262   static OMPParallelDirective *CreateEmpty(const ASTContext &C,
    263                                            unsigned NumClauses, EmptyShell);
    264 
    265   static bool classof(const Stmt *T) {
    266     return T->getStmtClass() == OMPParallelDirectiveClass;
    267   }
    268 };
    269 
    270 /// \brief This is a common base class for loop directives ('omp simd', 'omp
    271 /// for', 'omp for simd' etc.). It is responsible for the loop code generation.
    272 ///
    273 class OMPLoopDirective : public OMPExecutableDirective {
    274   friend class ASTStmtReader;
    275   /// \brief Number of collapsed loops as specified by 'collapse' clause.
    276   unsigned CollapsedNum;
    277 
    278   /// \brief Offsets to the stored exprs.
    279   /// This enumeration contains offsets to all the pointers to children
    280   /// expressions stored in OMPLoopDirective.
    281   /// The first 9 children are nesessary for all the loop directives, and
    282   /// the next 7 are specific to the worksharing ones.
    283   /// After the fixed children, three arrays of length CollapsedNum are
    284   /// allocated: loop counters, their updates and final values.
    285   ///
    286   enum {
    287     AssociatedStmtOffset = 0,
    288     IterationVariableOffset = 1,
    289     LastIterationOffset = 2,
    290     CalcLastIterationOffset = 3,
    291     PreConditionOffset = 4,
    292     CondOffset = 5,
    293     SeparatedCondOffset = 6,
    294     InitOffset = 7,
    295     IncOffset = 8,
    296     // The '...End' enumerators do not correspond to child expressions - they
    297     // specify the offset to the end (and start of the following counters/
    298     // updates/finals arrays).
    299     DefaultEnd = 9,
    300     // The following 7 exprs are used by worksharing loops only.
    301     IsLastIterVariableOffset = 9,
    302     LowerBoundVariableOffset = 10,
    303     UpperBoundVariableOffset = 11,
    304     StrideVariableOffset = 12,
    305     EnsureUpperBoundOffset = 13,
    306     NextLowerBoundOffset = 14,
    307     NextUpperBoundOffset = 15,
    308     // Offset to the end (and start of the following counters/updates/finals
    309     // arrays) for worksharing loop directives.
    310     WorksharingEnd = 16,
    311   };
    312 
    313   /// \brief Get the counters storage.
    314   MutableArrayRef<Expr *> getCounters() {
    315     Expr **Storage = reinterpret_cast<Expr **>(
    316         &(*(std::next(child_begin(), getArraysOffset(getDirectiveKind())))));
    317     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
    318   }
    319 
    320   /// \brief Get the updates storage.
    321   MutableArrayRef<Expr *> getUpdates() {
    322     Expr **Storage = reinterpret_cast<Expr **>(
    323         &*std::next(child_begin(),
    324                     getArraysOffset(getDirectiveKind()) + CollapsedNum));
    325     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
    326   }
    327 
    328   /// \brief Get the final counter updates storage.
    329   MutableArrayRef<Expr *> getFinals() {
    330     Expr **Storage = reinterpret_cast<Expr **>(
    331         &*std::next(child_begin(),
    332                     getArraysOffset(getDirectiveKind()) + 2 * CollapsedNum));
    333     return MutableArrayRef<Expr *>(Storage, CollapsedNum);
    334   }
    335 
    336 protected:
    337   /// \brief Build instance of loop directive of class \a Kind.
    338   ///
    339   /// \param SC Statement class.
    340   /// \param Kind Kind of OpenMP directive.
    341   /// \param StartLoc Starting location of the directive (directive keyword).
    342   /// \param EndLoc Ending location of the directive.
    343   /// \param CollapsedNum Number of collapsed loops from 'collapse' clause.
    344   /// \param NumClauses Number of clauses.
    345   /// \param NumSpecialChildren Number of additional directive-specific stmts.
    346   ///
    347   template <typename T>
    348   OMPLoopDirective(const T *That, StmtClass SC, OpenMPDirectiveKind Kind,
    349                    SourceLocation StartLoc, SourceLocation EndLoc,
    350                    unsigned CollapsedNum, unsigned NumClauses,
    351                    unsigned NumSpecialChildren = 0)
    352       : OMPExecutableDirective(That, SC, Kind, StartLoc, EndLoc, NumClauses,
    353                                numLoopChildren(CollapsedNum, Kind) +
    354                                    NumSpecialChildren),
    355         CollapsedNum(CollapsedNum) {}
    356 
    357   /// \brief Offset to the start of children expression arrays.
    358   static unsigned getArraysOffset(OpenMPDirectiveKind Kind) {
    359     return isOpenMPWorksharingDirective(Kind) ? WorksharingEnd
    360                                               : DefaultEnd;
    361   }
    362 
    363   /// \brief Children number.
    364   static unsigned numLoopChildren(unsigned CollapsedNum,
    365                                   OpenMPDirectiveKind Kind) {
    366     return getArraysOffset(Kind) +
    367            3 * CollapsedNum; // Counters, Updates and Finals
    368   }
    369 
    370   void setIterationVariable(Expr *IV) {
    371     *std::next(child_begin(), IterationVariableOffset) = IV;
    372   }
    373   void setLastIteration(Expr *LI) {
    374     *std::next(child_begin(), LastIterationOffset) = LI;
    375   }
    376   void setCalcLastIteration(Expr *CLI) {
    377     *std::next(child_begin(), CalcLastIterationOffset) = CLI;
    378   }
    379   void setPreCond(Expr *PC) {
    380     *std::next(child_begin(), PreConditionOffset) = PC;
    381   }
    382   void setCond(Expr *Cond, Expr *SeparatedCond) {
    383     *std::next(child_begin(), CondOffset) = Cond;
    384     *std::next(child_begin(), SeparatedCondOffset) = SeparatedCond;
    385   }
    386   void setInit(Expr *Init) { *std::next(child_begin(), InitOffset) = Init; }
    387   void setInc(Expr *Inc) { *std::next(child_begin(), IncOffset) = Inc; }
    388   void setIsLastIterVariable(Expr *IL) {
    389     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
    390            "expected worksharing loop directive");
    391     *std::next(child_begin(), IsLastIterVariableOffset) = IL;
    392   }
    393   void setLowerBoundVariable(Expr *LB) {
    394     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
    395            "expected worksharing loop directive");
    396     *std::next(child_begin(), LowerBoundVariableOffset) = LB;
    397   }
    398   void setUpperBoundVariable(Expr *UB) {
    399     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
    400            "expected worksharing loop directive");
    401     *std::next(child_begin(), UpperBoundVariableOffset) = UB;
    402   }
    403   void setStrideVariable(Expr *ST) {
    404     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
    405            "expected worksharing loop directive");
    406     *std::next(child_begin(), StrideVariableOffset) = ST;
    407   }
    408   void setEnsureUpperBound(Expr *EUB) {
    409     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
    410            "expected worksharing loop directive");
    411     *std::next(child_begin(), EnsureUpperBoundOffset) = EUB;
    412   }
    413   void setNextLowerBound(Expr *NLB) {
    414     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
    415            "expected worksharing loop directive");
    416     *std::next(child_begin(), NextLowerBoundOffset) = NLB;
    417   }
    418   void setNextUpperBound(Expr *NUB) {
    419     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
    420            "expected worksharing loop directive");
    421     *std::next(child_begin(), NextUpperBoundOffset) = NUB;
    422   }
    423   void setCounters(ArrayRef<Expr *> A);
    424   void setUpdates(ArrayRef<Expr *> A);
    425   void setFinals(ArrayRef<Expr *> A);
    426 
    427 public:
    428   /// \brief The expressions built for the OpenMP loop CodeGen for the
    429   /// whole collapsed loop nest.
    430   struct HelperExprs {
    431     /// \brief Loop iteration variable.
    432     Expr *IterationVarRef;
    433     /// \brief Loop last iteration number.
    434     Expr *LastIteration;
    435     /// \brief Loop number of iterations.
    436     Expr *NumIterations;
    437     /// \brief Calculation of last iteration.
    438     Expr *CalcLastIteration;
    439     /// \brief Loop pre-condition.
    440     Expr *PreCond;
    441     /// \brief Loop condition.
    442     Expr *Cond;
    443     /// \brief A condition with 1 iteration separated.
    444     Expr *SeparatedCond;
    445     /// \brief Loop iteration variable init.
    446     Expr *Init;
    447     /// \brief Loop increment.
    448     Expr *Inc;
    449     /// \brief IsLastIteration - local flag variable passed to runtime.
    450     Expr *IL;
    451     /// \brief LowerBound - local variable passed to runtime.
    452     Expr *LB;
    453     /// \brief UpperBound - local variable passed to runtime.
    454     Expr *UB;
    455     /// \brief Stride - local variable passed to runtime.
    456     Expr *ST;
    457     /// \brief EnsureUpperBound -- expression LB = min(LB, NumIterations).
    458     Expr *EUB;
    459     /// \brief Update of LowerBound for statically sheduled 'omp for' loops.
    460     Expr *NLB;
    461     /// \brief Update of UpperBound for statically sheduled 'omp for' loops.
    462     Expr *NUB;
    463     /// \brief Counters Loop counters.
    464     SmallVector<Expr *, 4> Counters;
    465     /// \brief Expressions for loop counters update for CodeGen.
    466     SmallVector<Expr *, 4> Updates;
    467     /// \brief Final loop counter values for GodeGen.
    468     SmallVector<Expr *, 4> Finals;
    469 
    470     /// \brief Check if all the expressions are built (does not check the
    471     /// worksharing ones).
    472     bool builtAll() {
    473       return IterationVarRef != nullptr && LastIteration != nullptr &&
    474              NumIterations != nullptr && PreCond != nullptr &&
    475              Cond != nullptr && SeparatedCond != nullptr && Init != nullptr &&
    476              Inc != nullptr;
    477     }
    478 
    479     /// \brief Initialize all the fields to null.
    480     /// \param Size Number of elements in the counters/finals/updates arrays.
    481     void clear(unsigned Size) {
    482       IterationVarRef = nullptr;
    483       LastIteration = nullptr;
    484       CalcLastIteration = nullptr;
    485       PreCond = nullptr;
    486       Cond = nullptr;
    487       SeparatedCond = nullptr;
    488       Init = nullptr;
    489       Inc = nullptr;
    490       IL = nullptr;
    491       LB = nullptr;
    492       UB = nullptr;
    493       ST = nullptr;
    494       EUB = nullptr;
    495       NLB = nullptr;
    496       NUB = nullptr;
    497       Counters.resize(Size);
    498       Updates.resize(Size);
    499       Finals.resize(Size);
    500       for (unsigned i = 0; i < Size; ++i) {
    501         Counters[i] = nullptr;
    502         Updates[i] = nullptr;
    503         Finals[i] = nullptr;
    504       }
    505     }
    506   };
    507 
    508   /// \brief Get number of collapsed loops.
    509   unsigned getCollapsedNumber() const { return CollapsedNum; }
    510 
    511   Expr *getIterationVariable() const {
    512     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    513         *std::next(child_begin(), IterationVariableOffset)));
    514   }
    515   Expr *getLastIteration() const {
    516     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    517         *std::next(child_begin(), LastIterationOffset)));
    518   }
    519   Expr *getCalcLastIteration() const {
    520     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    521         *std::next(child_begin(), CalcLastIterationOffset)));
    522   }
    523   Expr *getPreCond() const {
    524     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    525         *std::next(child_begin(), PreConditionOffset)));
    526   }
    527   Expr *getCond(bool SeparateIter) const {
    528     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    529         *std::next(child_begin(),
    530                    (SeparateIter ? SeparatedCondOffset : CondOffset))));
    531   }
    532   Expr *getInit() const {
    533     return const_cast<Expr *>(
    534         reinterpret_cast<const Expr *>(*std::next(child_begin(), InitOffset)));
    535   }
    536   Expr *getInc() const {
    537     return const_cast<Expr *>(
    538         reinterpret_cast<const Expr *>(*std::next(child_begin(), IncOffset)));
    539   }
    540   Expr *getIsLastIterVariable() const {
    541     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
    542            "expected worksharing loop directive");
    543     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    544         *std::next(child_begin(), IsLastIterVariableOffset)));
    545   }
    546   Expr *getLowerBoundVariable() const {
    547     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
    548            "expected worksharing loop directive");
    549     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    550         *std::next(child_begin(), LowerBoundVariableOffset)));
    551   }
    552   Expr *getUpperBoundVariable() const {
    553     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
    554            "expected worksharing loop directive");
    555     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    556         *std::next(child_begin(), UpperBoundVariableOffset)));
    557   }
    558   Expr *getStrideVariable() const {
    559     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
    560            "expected worksharing loop directive");
    561     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    562         *std::next(child_begin(), StrideVariableOffset)));
    563   }
    564   Expr *getEnsureUpperBound() const {
    565     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
    566            "expected worksharing loop directive");
    567     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    568         *std::next(child_begin(), EnsureUpperBoundOffset)));
    569   }
    570   Expr *getNextLowerBound() const {
    571     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
    572            "expected worksharing loop directive");
    573     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    574         *std::next(child_begin(), NextLowerBoundOffset)));
    575   }
    576   Expr *getNextUpperBound() const {
    577     assert(isOpenMPWorksharingDirective(getDirectiveKind()) &&
    578            "expected worksharing loop directive");
    579     return const_cast<Expr *>(reinterpret_cast<const Expr *>(
    580         *std::next(child_begin(), NextUpperBoundOffset)));
    581   }
    582   const Stmt *getBody() const {
    583     // This relies on the loop form is already checked by Sema.
    584     Stmt *Body = getAssociatedStmt()->IgnoreContainers(true);
    585     Body = cast<ForStmt>(Body)->getBody();
    586     for (unsigned Cnt = 1; Cnt < CollapsedNum; ++Cnt) {
    587       Body = Body->IgnoreContainers();
    588       Body = cast<ForStmt>(Body)->getBody();
    589     }
    590     return Body;
    591   }
    592 
    593   ArrayRef<Expr *> counters() { return getCounters(); }
    594 
    595   ArrayRef<Expr *> counters() const {
    596     return const_cast<OMPLoopDirective *>(this)->getCounters();
    597   }
    598 
    599   ArrayRef<Expr *> updates() { return getUpdates(); }
    600 
    601   ArrayRef<Expr *> updates() const {
    602     return const_cast<OMPLoopDirective *>(this)->getUpdates();
    603   }
    604 
    605   ArrayRef<Expr *> finals() { return getFinals(); }
    606 
    607   ArrayRef<Expr *> finals() const {
    608     return const_cast<OMPLoopDirective *>(this)->getFinals();
    609   }
    610 
    611   static bool classof(const Stmt *T) {
    612     return T->getStmtClass() == OMPSimdDirectiveClass ||
    613            T->getStmtClass() == OMPForDirectiveClass ||
    614            T->getStmtClass() == OMPForSimdDirectiveClass ||
    615            T->getStmtClass() == OMPParallelForDirectiveClass ||
    616            T->getStmtClass() == OMPParallelForSimdDirectiveClass;
    617   }
    618 };
    619 
    620 /// \brief This represents '#pragma omp simd' directive.
    621 ///
    622 /// \code
    623 /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d)
    624 /// \endcode
    625 /// In this example directive '#pragma omp simd' has clauses 'private'
    626 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
    627 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
    628 ///
    629 class OMPSimdDirective : public OMPLoopDirective {
    630   friend class ASTStmtReader;
    631   /// \brief Build directive with the given start and end location.
    632   ///
    633   /// \param StartLoc Starting location of the directive kind.
    634   /// \param EndLoc Ending location of the directive.
    635   /// \param CollapsedNum Number of collapsed nested loops.
    636   /// \param NumClauses Number of clauses.
    637   ///
    638   OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    639                    unsigned CollapsedNum, unsigned NumClauses)
    640       : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd, StartLoc,
    641                          EndLoc, CollapsedNum, NumClauses) {}
    642 
    643   /// \brief Build an empty directive.
    644   ///
    645   /// \param CollapsedNum Number of collapsed nested loops.
    646   /// \param NumClauses Number of clauses.
    647   ///
    648   explicit OMPSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
    649       : OMPLoopDirective(this, OMPSimdDirectiveClass, OMPD_simd,
    650                          SourceLocation(), SourceLocation(), CollapsedNum,
    651                          NumClauses) {}
    652 
    653 public:
    654   /// \brief Creates directive with a list of \a Clauses.
    655   ///
    656   /// \param C AST context.
    657   /// \param StartLoc Starting location of the directive kind.
    658   /// \param EndLoc Ending Location of the directive.
    659   /// \param CollapsedNum Number of collapsed loops.
    660   /// \param Clauses List of clauses.
    661   /// \param AssociatedStmt Statement, associated with the directive.
    662   /// \param Exprs Helper expressions for CodeGen.
    663   ///
    664   static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc,
    665                                   SourceLocation EndLoc, unsigned CollapsedNum,
    666                                   ArrayRef<OMPClause *> Clauses,
    667                                   Stmt *AssociatedStmt,
    668                                   const HelperExprs &Exprs);
    669 
    670   /// \brief Creates an empty directive with the place
    671   /// for \a NumClauses clauses.
    672   ///
    673   /// \param C AST context.
    674   /// \param CollapsedNum Number of collapsed nested loops.
    675   /// \param NumClauses Number of clauses.
    676   ///
    677   static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
    678                                        unsigned CollapsedNum, EmptyShell);
    679 
    680   static bool classof(const Stmt *T) {
    681     return T->getStmtClass() == OMPSimdDirectiveClass;
    682   }
    683 };
    684 
    685 /// \brief This represents '#pragma omp for' directive.
    686 ///
    687 /// \code
    688 /// #pragma omp for private(a,b) reduction(+:c,d)
    689 /// \endcode
    690 /// In this example directive '#pragma omp for' has clauses 'private' with the
    691 /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c'
    692 /// and 'd'.
    693 ///
    694 class OMPForDirective : public OMPLoopDirective {
    695   friend class ASTStmtReader;
    696   /// \brief Build directive with the given start and end location.
    697   ///
    698   /// \param StartLoc Starting location of the directive kind.
    699   /// \param EndLoc Ending location of the directive.
    700   /// \param CollapsedNum Number of collapsed nested loops.
    701   /// \param NumClauses Number of clauses.
    702   ///
    703   OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    704                   unsigned CollapsedNum, unsigned NumClauses)
    705       : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, StartLoc, EndLoc,
    706                          CollapsedNum, NumClauses) {}
    707 
    708   /// \brief Build an empty directive.
    709   ///
    710   /// \param CollapsedNum Number of collapsed nested loops.
    711   /// \param NumClauses Number of clauses.
    712   ///
    713   explicit OMPForDirective(unsigned CollapsedNum, unsigned NumClauses)
    714       : OMPLoopDirective(this, OMPForDirectiveClass, OMPD_for, SourceLocation(),
    715                          SourceLocation(), CollapsedNum, NumClauses) {}
    716 
    717 public:
    718   /// \brief Creates directive with a list of \a Clauses.
    719   ///
    720   /// \param C AST context.
    721   /// \param StartLoc Starting location of the directive kind.
    722   /// \param EndLoc Ending Location of the directive.
    723   /// \param CollapsedNum Number of collapsed loops.
    724   /// \param Clauses List of clauses.
    725   /// \param AssociatedStmt Statement, associated with the directive.
    726   /// \param Exprs Helper expressions for CodeGen.
    727   ///
    728   static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc,
    729                                  SourceLocation EndLoc, unsigned CollapsedNum,
    730                                  ArrayRef<OMPClause *> Clauses,
    731                                  Stmt *AssociatedStmt,
    732                                  const HelperExprs &Exprs);
    733 
    734   /// \brief Creates an empty directive with the place
    735   /// for \a NumClauses clauses.
    736   ///
    737   /// \param C AST context.
    738   /// \param CollapsedNum Number of collapsed nested loops.
    739   /// \param NumClauses Number of clauses.
    740   ///
    741   static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
    742                                       unsigned CollapsedNum, EmptyShell);
    743 
    744   static bool classof(const Stmt *T) {
    745     return T->getStmtClass() == OMPForDirectiveClass;
    746   }
    747 };
    748 
    749 /// \brief This represents '#pragma omp for simd' directive.
    750 ///
    751 /// \code
    752 /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d)
    753 /// \endcode
    754 /// In this example directive '#pragma omp for simd' has clauses 'private'
    755 /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and
    756 /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'.
    757 ///
    758 class OMPForSimdDirective : public OMPLoopDirective {
    759   friend class ASTStmtReader;
    760   /// \brief Build directive with the given start and end location.
    761   ///
    762   /// \param StartLoc Starting location of the directive kind.
    763   /// \param EndLoc Ending location of the directive.
    764   /// \param CollapsedNum Number of collapsed nested loops.
    765   /// \param NumClauses Number of clauses.
    766   ///
    767   OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    768                       unsigned CollapsedNum, unsigned NumClauses)
    769       : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
    770                          StartLoc, EndLoc, CollapsedNum, NumClauses) {}
    771 
    772   /// \brief Build an empty directive.
    773   ///
    774   /// \param CollapsedNum Number of collapsed nested loops.
    775   /// \param NumClauses Number of clauses.
    776   ///
    777   explicit OMPForSimdDirective(unsigned CollapsedNum, unsigned NumClauses)
    778       : OMPLoopDirective(this, OMPForSimdDirectiveClass, OMPD_for_simd,
    779                          SourceLocation(), SourceLocation(), CollapsedNum,
    780                          NumClauses) {}
    781 
    782 public:
    783   /// \brief Creates directive with a list of \a Clauses.
    784   ///
    785   /// \param C AST context.
    786   /// \param StartLoc Starting location of the directive kind.
    787   /// \param EndLoc Ending Location of the directive.
    788   /// \param CollapsedNum Number of collapsed loops.
    789   /// \param Clauses List of clauses.
    790   /// \param AssociatedStmt Statement, associated with the directive.
    791   /// \param Exprs Helper expressions for CodeGen.
    792   ///
    793   static OMPForSimdDirective *
    794   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
    795          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
    796          Stmt *AssociatedStmt, const HelperExprs &Exprs);
    797 
    798   /// \brief Creates an empty directive with the place
    799   /// for \a NumClauses clauses.
    800   ///
    801   /// \param C AST context.
    802   /// \param CollapsedNum Number of collapsed nested loops.
    803   /// \param NumClauses Number of clauses.
    804   ///
    805   static OMPForSimdDirective *CreateEmpty(const ASTContext &C,
    806                                           unsigned NumClauses,
    807                                           unsigned CollapsedNum, EmptyShell);
    808 
    809   static bool classof(const Stmt *T) {
    810     return T->getStmtClass() == OMPForSimdDirectiveClass;
    811   }
    812 };
    813 
    814 /// \brief This represents '#pragma omp sections' directive.
    815 ///
    816 /// \code
    817 /// #pragma omp sections private(a,b) reduction(+:c,d)
    818 /// \endcode
    819 /// In this example directive '#pragma omp sections' has clauses 'private' with
    820 /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables
    821 /// 'c' and 'd'.
    822 ///
    823 class OMPSectionsDirective : public OMPExecutableDirective {
    824   friend class ASTStmtReader;
    825   /// \brief Build directive with the given start and end location.
    826   ///
    827   /// \param StartLoc Starting location of the directive kind.
    828   /// \param EndLoc Ending location of the directive.
    829   /// \param NumClauses Number of clauses.
    830   ///
    831   OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    832                        unsigned NumClauses)
    833       : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
    834                                StartLoc, EndLoc, NumClauses, 1) {}
    835 
    836   /// \brief Build an empty directive.
    837   ///
    838   /// \param NumClauses Number of clauses.
    839   ///
    840   explicit OMPSectionsDirective(unsigned NumClauses)
    841       : OMPExecutableDirective(this, OMPSectionsDirectiveClass, OMPD_sections,
    842                                SourceLocation(), SourceLocation(), NumClauses,
    843                                1) {}
    844 
    845 public:
    846   /// \brief Creates directive with a list of \a Clauses.
    847   ///
    848   /// \param C AST context.
    849   /// \param StartLoc Starting location of the directive kind.
    850   /// \param EndLoc Ending Location of the directive.
    851   /// \param Clauses List of clauses.
    852   /// \param AssociatedStmt Statement, associated with the directive.
    853   ///
    854   static OMPSectionsDirective *
    855   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
    856          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
    857 
    858   /// \brief Creates an empty directive with the place for \a NumClauses
    859   /// clauses.
    860   ///
    861   /// \param C AST context.
    862   /// \param NumClauses Number of clauses.
    863   ///
    864   static OMPSectionsDirective *CreateEmpty(const ASTContext &C,
    865                                            unsigned NumClauses, EmptyShell);
    866 
    867   static bool classof(const Stmt *T) {
    868     return T->getStmtClass() == OMPSectionsDirectiveClass;
    869   }
    870 };
    871 
    872 /// \brief This represents '#pragma omp section' directive.
    873 ///
    874 /// \code
    875 /// #pragma omp section
    876 /// \endcode
    877 ///
    878 class OMPSectionDirective : public OMPExecutableDirective {
    879   friend class ASTStmtReader;
    880   /// \brief Build directive with the given start and end location.
    881   ///
    882   /// \param StartLoc Starting location of the directive kind.
    883   /// \param EndLoc Ending location of the directive.
    884   ///
    885   OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc)
    886       : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
    887                                StartLoc, EndLoc, 0, 1) {}
    888 
    889   /// \brief Build an empty directive.
    890   ///
    891   explicit OMPSectionDirective()
    892       : OMPExecutableDirective(this, OMPSectionDirectiveClass, OMPD_section,
    893                                SourceLocation(), SourceLocation(), 0, 1) {}
    894 
    895 public:
    896   /// \brief Creates directive.
    897   ///
    898   /// \param C AST context.
    899   /// \param StartLoc Starting location of the directive kind.
    900   /// \param EndLoc Ending Location of the directive.
    901   /// \param AssociatedStmt Statement, associated with the directive.
    902   ///
    903   static OMPSectionDirective *Create(const ASTContext &C,
    904                                      SourceLocation StartLoc,
    905                                      SourceLocation EndLoc,
    906                                      Stmt *AssociatedStmt);
    907 
    908   /// \brief Creates an empty directive.
    909   ///
    910   /// \param C AST context.
    911   ///
    912   static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell);
    913 
    914   static bool classof(const Stmt *T) {
    915     return T->getStmtClass() == OMPSectionDirectiveClass;
    916   }
    917 };
    918 
    919 /// \brief This represents '#pragma omp single' directive.
    920 ///
    921 /// \code
    922 /// #pragma omp single private(a,b) copyprivate(c,d)
    923 /// \endcode
    924 /// In this example directive '#pragma omp single' has clauses 'private' with
    925 /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'.
    926 ///
    927 class OMPSingleDirective : public OMPExecutableDirective {
    928   friend class ASTStmtReader;
    929   /// \brief Build directive with the given start and end location.
    930   ///
    931   /// \param StartLoc Starting location of the directive kind.
    932   /// \param EndLoc Ending location of the directive.
    933   /// \param NumClauses Number of clauses.
    934   ///
    935   OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc,
    936                      unsigned NumClauses)
    937       : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
    938                                StartLoc, EndLoc, NumClauses, 1) {}
    939 
    940   /// \brief Build an empty directive.
    941   ///
    942   /// \param NumClauses Number of clauses.
    943   ///
    944   explicit OMPSingleDirective(unsigned NumClauses)
    945       : OMPExecutableDirective(this, OMPSingleDirectiveClass, OMPD_single,
    946                                SourceLocation(), SourceLocation(), NumClauses,
    947                                1) {}
    948 
    949 public:
    950   /// \brief Creates directive with a list of \a Clauses.
    951   ///
    952   /// \param C AST context.
    953   /// \param StartLoc Starting location of the directive kind.
    954   /// \param EndLoc Ending Location of the directive.
    955   /// \param Clauses List of clauses.
    956   /// \param AssociatedStmt Statement, associated with the directive.
    957   ///
    958   static OMPSingleDirective *
    959   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
    960          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
    961 
    962   /// \brief Creates an empty directive with the place for \a NumClauses
    963   /// clauses.
    964   ///
    965   /// \param C AST context.
    966   /// \param NumClauses Number of clauses.
    967   ///
    968   static OMPSingleDirective *CreateEmpty(const ASTContext &C,
    969                                          unsigned NumClauses, EmptyShell);
    970 
    971   static bool classof(const Stmt *T) {
    972     return T->getStmtClass() == OMPSingleDirectiveClass;
    973   }
    974 };
    975 
    976 /// \brief This represents '#pragma omp master' directive.
    977 ///
    978 /// \code
    979 /// #pragma omp master
    980 /// \endcode
    981 ///
    982 class OMPMasterDirective : public OMPExecutableDirective {
    983   friend class ASTStmtReader;
    984   /// \brief Build directive with the given start and end location.
    985   ///
    986   /// \param StartLoc Starting location of the directive kind.
    987   /// \param EndLoc Ending location of the directive.
    988   ///
    989   OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc)
    990       : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
    991                                StartLoc, EndLoc, 0, 1) {}
    992 
    993   /// \brief Build an empty directive.
    994   ///
    995   explicit OMPMasterDirective()
    996       : OMPExecutableDirective(this, OMPMasterDirectiveClass, OMPD_master,
    997                                SourceLocation(), SourceLocation(), 0, 1) {}
    998 
    999 public:
   1000   /// \brief Creates directive.
   1001   ///
   1002   /// \param C AST context.
   1003   /// \param StartLoc Starting location of the directive kind.
   1004   /// \param EndLoc Ending Location of the directive.
   1005   /// \param AssociatedStmt Statement, associated with the directive.
   1006   ///
   1007   static OMPMasterDirective *Create(const ASTContext &C,
   1008                                     SourceLocation StartLoc,
   1009                                     SourceLocation EndLoc,
   1010                                     Stmt *AssociatedStmt);
   1011 
   1012   /// \brief Creates an empty directive.
   1013   ///
   1014   /// \param C AST context.
   1015   ///
   1016   static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1017 
   1018   static bool classof(const Stmt *T) {
   1019     return T->getStmtClass() == OMPMasterDirectiveClass;
   1020   }
   1021 };
   1022 
   1023 /// \brief This represents '#pragma omp critical' directive.
   1024 ///
   1025 /// \code
   1026 /// #pragma omp critical
   1027 /// \endcode
   1028 ///
   1029 class OMPCriticalDirective : public OMPExecutableDirective {
   1030   friend class ASTStmtReader;
   1031   /// \brief Name of the directive.
   1032   DeclarationNameInfo DirName;
   1033   /// \brief Build directive with the given start and end location.
   1034   ///
   1035   /// \param Name Name of the directive.
   1036   /// \param StartLoc Starting location of the directive kind.
   1037   /// \param EndLoc Ending location of the directive.
   1038   ///
   1039   OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc,
   1040                        SourceLocation EndLoc)
   1041       : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
   1042                                StartLoc, EndLoc, 0, 1),
   1043         DirName(Name) {}
   1044 
   1045   /// \brief Build an empty directive.
   1046   ///
   1047   explicit OMPCriticalDirective()
   1048       : OMPExecutableDirective(this, OMPCriticalDirectiveClass, OMPD_critical,
   1049                                SourceLocation(), SourceLocation(), 0, 1),
   1050         DirName() {}
   1051 
   1052   /// \brief Set name of the directive.
   1053   ///
   1054   /// \param Name Name of the directive.
   1055   ///
   1056   void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; }
   1057 
   1058 public:
   1059   /// \brief Creates directive.
   1060   ///
   1061   /// \param C AST context.
   1062   /// \param Name Name of the directive.
   1063   /// \param StartLoc Starting location of the directive kind.
   1064   /// \param EndLoc Ending Location of the directive.
   1065   /// \param AssociatedStmt Statement, associated with the directive.
   1066   ///
   1067   static OMPCriticalDirective *
   1068   Create(const ASTContext &C, const DeclarationNameInfo &Name,
   1069          SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt);
   1070 
   1071   /// \brief Creates an empty directive.
   1072   ///
   1073   /// \param C AST context.
   1074   ///
   1075   static OMPCriticalDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1076 
   1077   /// \brief Return name of the directive.
   1078   ///
   1079   DeclarationNameInfo getDirectiveName() const { return DirName; }
   1080 
   1081   static bool classof(const Stmt *T) {
   1082     return T->getStmtClass() == OMPCriticalDirectiveClass;
   1083   }
   1084 };
   1085 
   1086 /// \brief This represents '#pragma omp parallel for' directive.
   1087 ///
   1088 /// \code
   1089 /// #pragma omp parallel for private(a,b) reduction(+:c,d)
   1090 /// \endcode
   1091 /// In this example directive '#pragma omp parallel for' has clauses 'private'
   1092 /// with the variables 'a' and 'b' and 'reduction' with operator '+' and
   1093 /// variables 'c' and 'd'.
   1094 ///
   1095 class OMPParallelForDirective : public OMPLoopDirective {
   1096   friend class ASTStmtReader;
   1097   /// \brief Build directive with the given start and end location.
   1098   ///
   1099   /// \param StartLoc Starting location of the directive kind.
   1100   /// \param EndLoc Ending location of the directive.
   1101   /// \param CollapsedNum Number of collapsed nested loops.
   1102   /// \param NumClauses Number of clauses.
   1103   ///
   1104   OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1105                           unsigned CollapsedNum, unsigned NumClauses)
   1106       : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
   1107                          StartLoc, EndLoc, CollapsedNum, NumClauses) {}
   1108 
   1109   /// \brief Build an empty directive.
   1110   ///
   1111   /// \param CollapsedNum Number of collapsed nested loops.
   1112   /// \param NumClauses Number of clauses.
   1113   ///
   1114   explicit OMPParallelForDirective(unsigned CollapsedNum, unsigned NumClauses)
   1115       : OMPLoopDirective(this, OMPParallelForDirectiveClass, OMPD_parallel_for,
   1116                          SourceLocation(), SourceLocation(), CollapsedNum,
   1117                          NumClauses) {}
   1118 
   1119 public:
   1120   /// \brief Creates directive with a list of \a Clauses.
   1121   ///
   1122   /// \param C AST context.
   1123   /// \param StartLoc Starting location of the directive kind.
   1124   /// \param EndLoc Ending Location of the directive.
   1125   /// \param CollapsedNum Number of collapsed loops.
   1126   /// \param Clauses List of clauses.
   1127   /// \param AssociatedStmt Statement, associated with the directive.
   1128   /// \param Exprs Helper expressions for CodeGen.
   1129   ///
   1130   static OMPParallelForDirective *
   1131   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1132          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   1133          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   1134 
   1135   /// \brief Creates an empty directive with the place
   1136   /// for \a NumClauses clauses.
   1137   ///
   1138   /// \param C AST context.
   1139   /// \param CollapsedNum Number of collapsed nested loops.
   1140   /// \param NumClauses Number of clauses.
   1141   ///
   1142   static OMPParallelForDirective *CreateEmpty(const ASTContext &C,
   1143                                               unsigned NumClauses,
   1144                                               unsigned CollapsedNum,
   1145                                               EmptyShell);
   1146 
   1147   static bool classof(const Stmt *T) {
   1148     return T->getStmtClass() == OMPParallelForDirectiveClass;
   1149   }
   1150 };
   1151 
   1152 /// \brief This represents '#pragma omp parallel for simd' directive.
   1153 ///
   1154 /// \code
   1155 /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d)
   1156 /// \endcode
   1157 /// In this example directive '#pragma omp parallel for simd' has clauses
   1158 /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j'
   1159 /// and linear step 's', 'reduction' with operator '+' and variables 'c' and
   1160 /// 'd'.
   1161 ///
   1162 class OMPParallelForSimdDirective : public OMPLoopDirective {
   1163   friend class ASTStmtReader;
   1164   /// \brief Build directive with the given start and end location.
   1165   ///
   1166   /// \param StartLoc Starting location of the directive kind.
   1167   /// \param EndLoc Ending location of the directive.
   1168   /// \param CollapsedNum Number of collapsed nested loops.
   1169   /// \param NumClauses Number of clauses.
   1170   ///
   1171   OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1172                               unsigned CollapsedNum, unsigned NumClauses)
   1173       : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
   1174                          OMPD_parallel_for_simd, StartLoc, EndLoc, CollapsedNum,
   1175                          NumClauses) {}
   1176 
   1177   /// \brief Build an empty directive.
   1178   ///
   1179   /// \param CollapsedNum Number of collapsed nested loops.
   1180   /// \param NumClauses Number of clauses.
   1181   ///
   1182   explicit OMPParallelForSimdDirective(unsigned CollapsedNum,
   1183                                        unsigned NumClauses)
   1184       : OMPLoopDirective(this, OMPParallelForSimdDirectiveClass,
   1185                          OMPD_parallel_for_simd, SourceLocation(),
   1186                          SourceLocation(), CollapsedNum, NumClauses) {}
   1187 
   1188 public:
   1189   /// \brief Creates directive with a list of \a Clauses.
   1190   ///
   1191   /// \param C AST context.
   1192   /// \param StartLoc Starting location of the directive kind.
   1193   /// \param EndLoc Ending Location of the directive.
   1194   /// \param CollapsedNum Number of collapsed loops.
   1195   /// \param Clauses List of clauses.
   1196   /// \param AssociatedStmt Statement, associated with the directive.
   1197   /// \param Exprs Helper expressions for CodeGen.
   1198   ///
   1199   static OMPParallelForSimdDirective *
   1200   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1201          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses,
   1202          Stmt *AssociatedStmt, const HelperExprs &Exprs);
   1203 
   1204   /// \brief Creates an empty directive with the place
   1205   /// for \a NumClauses clauses.
   1206   ///
   1207   /// \param C AST context.
   1208   /// \param CollapsedNum Number of collapsed nested loops.
   1209   /// \param NumClauses Number of clauses.
   1210   ///
   1211   static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C,
   1212                                                   unsigned NumClauses,
   1213                                                   unsigned CollapsedNum,
   1214                                                   EmptyShell);
   1215 
   1216   static bool classof(const Stmt *T) {
   1217     return T->getStmtClass() == OMPParallelForSimdDirectiveClass;
   1218   }
   1219 };
   1220 
   1221 /// \brief This represents '#pragma omp parallel sections' directive.
   1222 ///
   1223 /// \code
   1224 /// #pragma omp parallel sections private(a,b) reduction(+:c,d)
   1225 /// \endcode
   1226 /// In this example directive '#pragma omp parallel sections' has clauses
   1227 /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+'
   1228 /// and variables 'c' and 'd'.
   1229 ///
   1230 class OMPParallelSectionsDirective : public OMPExecutableDirective {
   1231   friend class ASTStmtReader;
   1232   /// \brief Build directive with the given start and end location.
   1233   ///
   1234   /// \param StartLoc Starting location of the directive kind.
   1235   /// \param EndLoc Ending location of the directive.
   1236   /// \param NumClauses Number of clauses.
   1237   ///
   1238   OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1239                                unsigned NumClauses)
   1240       : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
   1241                                OMPD_parallel_sections, StartLoc, EndLoc,
   1242                                NumClauses, 1) {}
   1243 
   1244   /// \brief Build an empty directive.
   1245   ///
   1246   /// \param NumClauses Number of clauses.
   1247   ///
   1248   explicit OMPParallelSectionsDirective(unsigned NumClauses)
   1249       : OMPExecutableDirective(this, OMPParallelSectionsDirectiveClass,
   1250                                OMPD_parallel_sections, SourceLocation(),
   1251                                SourceLocation(), NumClauses, 1) {}
   1252 
   1253 public:
   1254   /// \brief Creates directive with a list of \a Clauses.
   1255   ///
   1256   /// \param C AST context.
   1257   /// \param StartLoc Starting location of the directive kind.
   1258   /// \param EndLoc Ending Location of the directive.
   1259   /// \param Clauses List of clauses.
   1260   /// \param AssociatedStmt Statement, associated with the directive.
   1261   ///
   1262   static OMPParallelSectionsDirective *
   1263   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1264          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   1265 
   1266   /// \brief Creates an empty directive with the place for \a NumClauses
   1267   /// clauses.
   1268   ///
   1269   /// \param C AST context.
   1270   /// \param NumClauses Number of clauses.
   1271   ///
   1272   static OMPParallelSectionsDirective *
   1273   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell);
   1274 
   1275   static bool classof(const Stmt *T) {
   1276     return T->getStmtClass() == OMPParallelSectionsDirectiveClass;
   1277   }
   1278 };
   1279 
   1280 /// \brief This represents '#pragma omp task' directive.
   1281 ///
   1282 /// \code
   1283 /// #pragma omp task private(a,b) final(d)
   1284 /// \endcode
   1285 /// In this example directive '#pragma omp task' has clauses 'private' with the
   1286 /// variables 'a' and 'b' and 'final' with condition 'd'.
   1287 ///
   1288 class OMPTaskDirective : public OMPExecutableDirective {
   1289   friend class ASTStmtReader;
   1290   /// \brief Build directive with the given start and end location.
   1291   ///
   1292   /// \param StartLoc Starting location of the directive kind.
   1293   /// \param EndLoc Ending location of the directive.
   1294   /// \param NumClauses Number of clauses.
   1295   ///
   1296   OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1297                    unsigned NumClauses)
   1298       : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task, StartLoc,
   1299                                EndLoc, NumClauses, 1) {}
   1300 
   1301   /// \brief Build an empty directive.
   1302   ///
   1303   /// \param NumClauses Number of clauses.
   1304   ///
   1305   explicit OMPTaskDirective(unsigned NumClauses)
   1306       : OMPExecutableDirective(this, OMPTaskDirectiveClass, OMPD_task,
   1307                                SourceLocation(), SourceLocation(), NumClauses,
   1308                                1) {}
   1309 
   1310 public:
   1311   /// \brief Creates directive with a list of \a Clauses.
   1312   ///
   1313   /// \param C AST context.
   1314   /// \param StartLoc Starting location of the directive kind.
   1315   /// \param EndLoc Ending Location of the directive.
   1316   /// \param Clauses List of clauses.
   1317   /// \param AssociatedStmt Statement, associated with the directive.
   1318   ///
   1319   static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc,
   1320                                   SourceLocation EndLoc,
   1321                                   ArrayRef<OMPClause *> Clauses,
   1322                                   Stmt *AssociatedStmt);
   1323 
   1324   /// \brief Creates an empty directive with the place for \a NumClauses
   1325   /// clauses.
   1326   ///
   1327   /// \param C AST context.
   1328   /// \param NumClauses Number of clauses.
   1329   ///
   1330   static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses,
   1331                                        EmptyShell);
   1332 
   1333   static bool classof(const Stmt *T) {
   1334     return T->getStmtClass() == OMPTaskDirectiveClass;
   1335   }
   1336 };
   1337 
   1338 /// \brief This represents '#pragma omp taskyield' directive.
   1339 ///
   1340 /// \code
   1341 /// #pragma omp taskyield
   1342 /// \endcode
   1343 ///
   1344 class OMPTaskyieldDirective : public OMPExecutableDirective {
   1345   friend class ASTStmtReader;
   1346   /// \brief Build directive with the given start and end location.
   1347   ///
   1348   /// \param StartLoc Starting location of the directive kind.
   1349   /// \param EndLoc Ending location of the directive.
   1350   ///
   1351   OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1352       : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
   1353                                StartLoc, EndLoc, 0, 0) {}
   1354 
   1355   /// \brief Build an empty directive.
   1356   ///
   1357   explicit OMPTaskyieldDirective()
   1358       : OMPExecutableDirective(this, OMPTaskyieldDirectiveClass, OMPD_taskyield,
   1359                                SourceLocation(), SourceLocation(), 0, 0) {}
   1360 
   1361 public:
   1362   /// \brief Creates directive.
   1363   ///
   1364   /// \param C AST context.
   1365   /// \param StartLoc Starting location of the directive kind.
   1366   /// \param EndLoc Ending Location of the directive.
   1367   ///
   1368   static OMPTaskyieldDirective *
   1369   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
   1370 
   1371   /// \brief Creates an empty directive.
   1372   ///
   1373   /// \param C AST context.
   1374   ///
   1375   static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1376 
   1377   static bool classof(const Stmt *T) {
   1378     return T->getStmtClass() == OMPTaskyieldDirectiveClass;
   1379   }
   1380 };
   1381 
   1382 /// \brief This represents '#pragma omp barrier' directive.
   1383 ///
   1384 /// \code
   1385 /// #pragma omp barrier
   1386 /// \endcode
   1387 ///
   1388 class OMPBarrierDirective : public OMPExecutableDirective {
   1389   friend class ASTStmtReader;
   1390   /// \brief Build directive with the given start and end location.
   1391   ///
   1392   /// \param StartLoc Starting location of the directive kind.
   1393   /// \param EndLoc Ending location of the directive.
   1394   ///
   1395   OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1396       : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
   1397                                StartLoc, EndLoc, 0, 0) {}
   1398 
   1399   /// \brief Build an empty directive.
   1400   ///
   1401   explicit OMPBarrierDirective()
   1402       : OMPExecutableDirective(this, OMPBarrierDirectiveClass, OMPD_barrier,
   1403                                SourceLocation(), SourceLocation(), 0, 0) {}
   1404 
   1405 public:
   1406   /// \brief Creates directive.
   1407   ///
   1408   /// \param C AST context.
   1409   /// \param StartLoc Starting location of the directive kind.
   1410   /// \param EndLoc Ending Location of the directive.
   1411   ///
   1412   static OMPBarrierDirective *
   1413   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
   1414 
   1415   /// \brief Creates an empty directive.
   1416   ///
   1417   /// \param C AST context.
   1418   ///
   1419   static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1420 
   1421   static bool classof(const Stmt *T) {
   1422     return T->getStmtClass() == OMPBarrierDirectiveClass;
   1423   }
   1424 };
   1425 
   1426 /// \brief This represents '#pragma omp taskwait' directive.
   1427 ///
   1428 /// \code
   1429 /// #pragma omp taskwait
   1430 /// \endcode
   1431 ///
   1432 class OMPTaskwaitDirective : public OMPExecutableDirective {
   1433   friend class ASTStmtReader;
   1434   /// \brief Build directive with the given start and end location.
   1435   ///
   1436   /// \param StartLoc Starting location of the directive kind.
   1437   /// \param EndLoc Ending location of the directive.
   1438   ///
   1439   OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1440       : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
   1441                                StartLoc, EndLoc, 0, 0) {}
   1442 
   1443   /// \brief Build an empty directive.
   1444   ///
   1445   explicit OMPTaskwaitDirective()
   1446       : OMPExecutableDirective(this, OMPTaskwaitDirectiveClass, OMPD_taskwait,
   1447                                SourceLocation(), SourceLocation(), 0, 0) {}
   1448 
   1449 public:
   1450   /// \brief Creates directive.
   1451   ///
   1452   /// \param C AST context.
   1453   /// \param StartLoc Starting location of the directive kind.
   1454   /// \param EndLoc Ending Location of the directive.
   1455   ///
   1456   static OMPTaskwaitDirective *
   1457   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc);
   1458 
   1459   /// \brief Creates an empty directive.
   1460   ///
   1461   /// \param C AST context.
   1462   ///
   1463   static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1464 
   1465   static bool classof(const Stmt *T) {
   1466     return T->getStmtClass() == OMPTaskwaitDirectiveClass;
   1467   }
   1468 };
   1469 
   1470 /// \brief This represents '#pragma omp flush' directive.
   1471 ///
   1472 /// \code
   1473 /// #pragma omp flush(a,b)
   1474 /// \endcode
   1475 /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a'
   1476 /// and 'b'.
   1477 /// 'omp flush' directive does not have clauses but have an optional list of
   1478 /// variables to flush. This list of variables is stored within some fake clause
   1479 /// FlushClause.
   1480 class OMPFlushDirective : public OMPExecutableDirective {
   1481   friend class ASTStmtReader;
   1482   /// \brief Build directive with the given start and end location.
   1483   ///
   1484   /// \param StartLoc Starting location of the directive kind.
   1485   /// \param EndLoc Ending location of the directive.
   1486   /// \param NumClauses Number of clauses.
   1487   ///
   1488   OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1489                     unsigned NumClauses)
   1490       : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
   1491                                StartLoc, EndLoc, NumClauses, 0) {}
   1492 
   1493   /// \brief Build an empty directive.
   1494   ///
   1495   /// \param NumClauses Number of clauses.
   1496   ///
   1497   explicit OMPFlushDirective(unsigned NumClauses)
   1498       : OMPExecutableDirective(this, OMPFlushDirectiveClass, OMPD_flush,
   1499                                SourceLocation(), SourceLocation(), NumClauses,
   1500                                0) {}
   1501 
   1502 public:
   1503   /// \brief Creates directive with a list of \a Clauses.
   1504   ///
   1505   /// \param C AST context.
   1506   /// \param StartLoc Starting location of the directive kind.
   1507   /// \param EndLoc Ending Location of the directive.
   1508   /// \param Clauses List of clauses (only single OMPFlushClause clause is
   1509   /// allowed).
   1510   ///
   1511   static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc,
   1512                                    SourceLocation EndLoc,
   1513                                    ArrayRef<OMPClause *> Clauses);
   1514 
   1515   /// \brief Creates an empty directive with the place for \a NumClauses
   1516   /// clauses.
   1517   ///
   1518   /// \param C AST context.
   1519   /// \param NumClauses Number of clauses.
   1520   ///
   1521   static OMPFlushDirective *CreateEmpty(const ASTContext &C,
   1522                                         unsigned NumClauses, EmptyShell);
   1523 
   1524   static bool classof(const Stmt *T) {
   1525     return T->getStmtClass() == OMPFlushDirectiveClass;
   1526   }
   1527 };
   1528 
   1529 /// \brief This represents '#pragma omp ordered' directive.
   1530 ///
   1531 /// \code
   1532 /// #pragma omp ordered
   1533 /// \endcode
   1534 ///
   1535 class OMPOrderedDirective : public OMPExecutableDirective {
   1536   friend class ASTStmtReader;
   1537   /// \brief Build directive with the given start and end location.
   1538   ///
   1539   /// \param StartLoc Starting location of the directive kind.
   1540   /// \param EndLoc Ending location of the directive.
   1541   ///
   1542   OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc)
   1543       : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
   1544                                StartLoc, EndLoc, 0, 1) {}
   1545 
   1546   /// \brief Build an empty directive.
   1547   ///
   1548   explicit OMPOrderedDirective()
   1549       : OMPExecutableDirective(this, OMPOrderedDirectiveClass, OMPD_ordered,
   1550                                SourceLocation(), SourceLocation(), 0, 1) {}
   1551 
   1552 public:
   1553   /// \brief Creates directive.
   1554   ///
   1555   /// \param C AST context.
   1556   /// \param StartLoc Starting location of the directive kind.
   1557   /// \param EndLoc Ending Location of the directive.
   1558   /// \param AssociatedStmt Statement, associated with the directive.
   1559   ///
   1560   static OMPOrderedDirective *Create(const ASTContext &C,
   1561                                      SourceLocation StartLoc,
   1562                                      SourceLocation EndLoc,
   1563                                      Stmt *AssociatedStmt);
   1564 
   1565   /// \brief Creates an empty directive.
   1566   ///
   1567   /// \param C AST context.
   1568   ///
   1569   static OMPOrderedDirective *CreateEmpty(const ASTContext &C, EmptyShell);
   1570 
   1571   static bool classof(const Stmt *T) {
   1572     return T->getStmtClass() == OMPOrderedDirectiveClass;
   1573   }
   1574 };
   1575 
   1576 /// \brief This represents '#pragma omp atomic' directive.
   1577 ///
   1578 /// \code
   1579 /// #pragma omp atomic capture
   1580 /// \endcode
   1581 /// In this example directive '#pragma omp atomic' has clause 'capture'.
   1582 ///
   1583 class OMPAtomicDirective : public OMPExecutableDirective {
   1584   friend class ASTStmtReader;
   1585   /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
   1586   /// have atomic expressions of forms
   1587   /// \code
   1588   /// x = x binop expr;
   1589   /// x = expr binop x;
   1590   /// \endcode
   1591   /// This field is true for the first form of the expression and false for the
   1592   /// second. Required for correct codegen of non-associative operations (like
   1593   /// << or >>).
   1594   bool IsXLHSInRHSPart;
   1595   /// \brief Used for 'atomic update' or 'atomic capture' constructs. They may
   1596   /// have atomic expressions of forms
   1597   /// \code
   1598   /// v = x; <update x>;
   1599   /// <update x>; v = x;
   1600   /// \endcode
   1601   /// This field is true for the first(postfix) form of the expression and false
   1602   /// otherwise.
   1603   bool IsPostfixUpdate;
   1604 
   1605   /// \brief Build directive with the given start and end location.
   1606   ///
   1607   /// \param StartLoc Starting location of the directive kind.
   1608   /// \param EndLoc Ending location of the directive.
   1609   /// \param NumClauses Number of clauses.
   1610   ///
   1611   OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1612                      unsigned NumClauses)
   1613       : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
   1614                                StartLoc, EndLoc, NumClauses, 5),
   1615         IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
   1616 
   1617   /// \brief Build an empty directive.
   1618   ///
   1619   /// \param NumClauses Number of clauses.
   1620   ///
   1621   explicit OMPAtomicDirective(unsigned NumClauses)
   1622       : OMPExecutableDirective(this, OMPAtomicDirectiveClass, OMPD_atomic,
   1623                                SourceLocation(), SourceLocation(), NumClauses,
   1624                                5),
   1625         IsXLHSInRHSPart(false), IsPostfixUpdate(false) {}
   1626 
   1627   /// \brief Set 'x' part of the associated expression/statement.
   1628   void setX(Expr *X) { *std::next(child_begin()) = X; }
   1629   /// \brief Set helper expression of the form
   1630   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
   1631   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
   1632   void setUpdateExpr(Expr *UE) { *std::next(child_begin(), 2) = UE; }
   1633   /// \brief Set 'v' part of the associated expression/statement.
   1634   void setV(Expr *V) { *std::next(child_begin(), 3) = V; }
   1635   /// \brief Set 'expr' part of the associated expression/statement.
   1636   void setExpr(Expr *E) { *std::next(child_begin(), 4) = E; }
   1637 
   1638 public:
   1639   /// \brief Creates directive with a list of \a Clauses and 'x', 'v' and 'expr'
   1640   /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for
   1641   /// detailed description of 'x', 'v' and 'expr').
   1642   ///
   1643   /// \param C AST context.
   1644   /// \param StartLoc Starting location of the directive kind.
   1645   /// \param EndLoc Ending Location of the directive.
   1646   /// \param Clauses List of clauses.
   1647   /// \param AssociatedStmt Statement, associated with the directive.
   1648   /// \param X 'x' part of the associated expression/statement.
   1649   /// \param V 'v' part of the associated expression/statement.
   1650   /// \param E 'expr' part of the associated expression/statement.
   1651   /// \param UE Helper expression of the form
   1652   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
   1653   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
   1654   /// \param IsXLHSInRHSPart true if \a UE has the first form and false if the
   1655   /// second.
   1656   /// \param IsPostfixUpdate true if original value of 'x' must be stored in
   1657   /// 'v', not an updated one.
   1658   static OMPAtomicDirective *
   1659   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1660          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V,
   1661          Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate);
   1662 
   1663   /// \brief Creates an empty directive with the place for \a NumClauses
   1664   /// clauses.
   1665   ///
   1666   /// \param C AST context.
   1667   /// \param NumClauses Number of clauses.
   1668   ///
   1669   static OMPAtomicDirective *CreateEmpty(const ASTContext &C,
   1670                                          unsigned NumClauses, EmptyShell);
   1671 
   1672   /// \brief Get 'x' part of the associated expression/statement.
   1673   Expr *getX() { return cast_or_null<Expr>(*std::next(child_begin())); }
   1674   const Expr *getX() const {
   1675     return cast_or_null<Expr>(*std::next(child_begin()));
   1676   }
   1677   /// \brief Get helper expression of the form
   1678   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
   1679   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
   1680   Expr *getUpdateExpr() {
   1681     return cast_or_null<Expr>(*std::next(child_begin(), 2));
   1682   }
   1683   const Expr *getUpdateExpr() const {
   1684     return cast_or_null<Expr>(*std::next(child_begin(), 2));
   1685   }
   1686   /// \brief Return true if helper update expression has form
   1687   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form
   1688   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
   1689   bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
   1690   /// \brief Return true if 'v' expression must be updated to original value of
   1691   /// 'x', false if 'v' must be updated to the new value of 'x'.
   1692   bool isPostfixUpdate() const { return IsPostfixUpdate; }
   1693   /// \brief Get 'v' part of the associated expression/statement.
   1694   Expr *getV() { return cast_or_null<Expr>(*std::next(child_begin(), 3)); }
   1695   const Expr *getV() const {
   1696     return cast_or_null<Expr>(*std::next(child_begin(), 3));
   1697   }
   1698   /// \brief Get 'expr' part of the associated expression/statement.
   1699   Expr *getExpr() { return cast_or_null<Expr>(*std::next(child_begin(), 4)); }
   1700   const Expr *getExpr() const {
   1701     return cast_or_null<Expr>(*std::next(child_begin(), 4));
   1702   }
   1703 
   1704   static bool classof(const Stmt *T) {
   1705     return T->getStmtClass() == OMPAtomicDirectiveClass;
   1706   }
   1707 };
   1708 
   1709 /// \brief This represents '#pragma omp target' directive.
   1710 ///
   1711 /// \code
   1712 /// #pragma omp target if(a)
   1713 /// \endcode
   1714 /// In this example directive '#pragma omp target' has clause 'if' with
   1715 /// condition 'a'.
   1716 ///
   1717 class OMPTargetDirective : public OMPExecutableDirective {
   1718   friend class ASTStmtReader;
   1719   /// \brief Build directive with the given start and end location.
   1720   ///
   1721   /// \param StartLoc Starting location of the directive kind.
   1722   /// \param EndLoc Ending location of the directive.
   1723   /// \param NumClauses Number of clauses.
   1724   ///
   1725   OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1726                      unsigned NumClauses)
   1727       : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
   1728                                StartLoc, EndLoc, NumClauses, 1) {}
   1729 
   1730   /// \brief Build an empty directive.
   1731   ///
   1732   /// \param NumClauses Number of clauses.
   1733   ///
   1734   explicit OMPTargetDirective(unsigned NumClauses)
   1735       : OMPExecutableDirective(this, OMPTargetDirectiveClass, OMPD_target,
   1736                                SourceLocation(), SourceLocation(), NumClauses,
   1737                                1) {}
   1738 
   1739 public:
   1740   /// \brief Creates directive with a list of \a Clauses.
   1741   ///
   1742   /// \param C AST context.
   1743   /// \param StartLoc Starting location of the directive kind.
   1744   /// \param EndLoc Ending Location of the directive.
   1745   /// \param Clauses List of clauses.
   1746   /// \param AssociatedStmt Statement, associated with the directive.
   1747   ///
   1748   static OMPTargetDirective *
   1749   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
   1750          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
   1751 
   1752   /// \brief Creates an empty directive with the place for \a NumClauses
   1753   /// clauses.
   1754   ///
   1755   /// \param C AST context.
   1756   /// \param NumClauses Number of clauses.
   1757   ///
   1758   static OMPTargetDirective *CreateEmpty(const ASTContext &C,
   1759                                          unsigned NumClauses, EmptyShell);
   1760 
   1761   static bool classof(const Stmt *T) {
   1762     return T->getStmtClass() == OMPTargetDirectiveClass;
   1763   }
   1764 };
   1765 
   1766 /// \brief This represents '#pragma omp teams' directive.
   1767 ///
   1768 /// \code
   1769 /// #pragma omp teams if(a)
   1770 /// \endcode
   1771 /// In this example directive '#pragma omp teams' has clause 'if' with
   1772 /// condition 'a'.
   1773 ///
   1774 class OMPTeamsDirective : public OMPExecutableDirective {
   1775   friend class ASTStmtReader;
   1776   /// \brief Build directive with the given start and end location.
   1777   ///
   1778   /// \param StartLoc Starting location of the directive kind.
   1779   /// \param EndLoc Ending location of the directive.
   1780   /// \param NumClauses Number of clauses.
   1781   ///
   1782   OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc,
   1783                     unsigned NumClauses)
   1784       : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
   1785                                StartLoc, EndLoc, NumClauses, 1) {}
   1786 
   1787   /// \brief Build an empty directive.
   1788   ///
   1789   /// \param NumClauses Number of clauses.
   1790   ///
   1791   explicit OMPTeamsDirective(unsigned NumClauses)
   1792       : OMPExecutableDirective(this, OMPTeamsDirectiveClass, OMPD_teams,
   1793                                SourceLocation(), SourceLocation(), NumClauses,
   1794                                1) {}
   1795 
   1796 public:
   1797   /// \brief Creates directive with a list of \a Clauses.
   1798   ///
   1799   /// \param C AST context.
   1800   /// \param StartLoc Starting location of the directive kind.
   1801   /// \param EndLoc Ending Location of the directive.
   1802   /// \param Clauses List of clauses.
   1803   /// \param AssociatedStmt Statement, associated with the directive.
   1804   ///
   1805   static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc,
   1806                                    SourceLocation EndLoc,
   1807                                    ArrayRef<OMPClause *> Clauses,
   1808                                    Stmt *AssociatedStmt);
   1809 
   1810   /// \brief Creates an empty directive with the place for \a NumClauses
   1811   /// clauses.
   1812   ///
   1813   /// \param C AST context.
   1814   /// \param NumClauses Number of clauses.
   1815   ///
   1816   static OMPTeamsDirective *CreateEmpty(const ASTContext &C,
   1817                                         unsigned NumClauses, EmptyShell);
   1818 
   1819   static bool classof(const Stmt *T) {
   1820     return T->getStmtClass() == OMPTeamsDirectiveClass;
   1821   }
   1822 };
   1823 
   1824 } // end namespace clang
   1825 
   1826 #endif
   1827