- //===- StmtOpenMP.h - Classes for OpenMP directives  ------------*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- /// \file 
- /// This file defines OpenMP AST classes for executable directives and 
- /// clauses. 
- /// 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_CLANG_AST_STMTOPENMP_H 
- #define LLVM_CLANG_AST_STMTOPENMP_H 
-   
- #include "clang/AST/ASTContext.h" 
- #include "clang/AST/Expr.h" 
- #include "clang/AST/OpenMPClause.h" 
- #include "clang/AST/Stmt.h" 
- #include "clang/AST/StmtCXX.h" 
- #include "clang/Basic/OpenMPKinds.h" 
- #include "clang/Basic/SourceLocation.h" 
-   
- namespace clang { 
-   
- //===----------------------------------------------------------------------===// 
- // AST classes for directives. 
- //===----------------------------------------------------------------------===// 
-   
- /// Representation of an OpenMP canonical loop. 
- /// 
- /// OpenMP 1.0 C/C++, section 2.4.1 for Construct; canonical-shape 
- /// OpenMP 2.0 C/C++, section 2.4.1 for Construct; canonical-shape 
- /// OpenMP 2.5, section 2.5.1 Loop Construct; canonical form 
- /// OpenMP 3.1, section 2.5.1 Loop Construct; canonical form 
- /// OpenMP 4.0, section 2.6 Canonical Loop Form 
- /// OpenMP 4.5, section 2.6 Canonical Loop Form 
- /// OpenMP 5.0, section 2.9.1 Canonical Loop Form 
- /// OpenMP 5.1, section 2.11.1 Canonical Loop Nest Form 
- /// 
- /// An OpenMP canonical loop is a for-statement or range-based for-statement 
- /// with additional requirements that ensure that the number of iterations is 
- /// known before entering the loop and allow skipping to an arbitrary iteration. 
- /// The OMPCanonicalLoop AST node wraps a ForStmt or CXXForRangeStmt that is 
- /// known to fulfill OpenMP's canonical loop requirements because of being 
- /// associated to an OMPLoopBasedDirective. That is, the general structure is: 
- /// 
- ///  OMPLoopBasedDirective 
- /// [`- CapturedStmt   ] 
- /// [   `- CapturedDecl] 
- ///        ` OMPCanonicalLoop 
- ///          `- ForStmt/CXXForRangeStmt 
- ///             `- Stmt 
- /// 
- /// One or multiple CapturedStmt/CapturedDecl pairs may be inserted by some 
- /// directives such as OMPParallelForDirective, but others do not need them 
- /// (such as OMPTileDirective). In  The OMPCanonicalLoop and 
- /// ForStmt/CXXForRangeStmt pair is repeated for loop associated with the 
- /// directive. A OMPCanonicalLoop must not appear in the AST unless associated 
- /// with a OMPLoopBasedDirective. In an imperfectly nested loop nest, the 
- /// OMPCanonicalLoop may also be wrapped in a CompoundStmt: 
- /// 
- /// [...] 
- ///  ` OMPCanonicalLoop 
- ///    `- ForStmt/CXXForRangeStmt 
- ///       `- CompoundStmt 
- ///          |- Leading in-between code (if any) 
- ///          |- OMPCanonicalLoop 
- ///          |  `- ForStmt/CXXForRangeStmt 
- ///          |     `- ... 
- ///          `- Trailing in-between code (if any) 
- /// 
- /// The leading/trailing in-between code must not itself be a OMPCanonicalLoop 
- /// to avoid confusion which loop belongs to the nesting. 
- /// 
- /// There are three different kinds of iteration variables for different 
- /// purposes: 
- /// * Loop user variable: The user-accessible variable with different value for 
- ///   each iteration. 
- /// * Loop iteration variable: The variable used to identify a loop iteration; 
- ///   for range-based for-statement, this is the hidden iterator '__begin'. For 
- ///   other loops, it is identical to the loop user variable. Must be a 
- ///   random-access iterator, pointer or integer type. 
- /// * Logical iteration counter: Normalized loop counter starting at 0 and 
- ///   incrementing by one at each iteration. Allows abstracting over the type 
- ///   of the loop iteration variable and is always an unsigned integer type 
- ///   appropriate to represent the range of the loop iteration variable. Its 
- ///   value corresponds to the logical iteration number in the OpenMP 
- ///   specification. 
- /// 
- /// This AST node provides two captured statements: 
- /// * The distance function which computes the number of iterations. 
- /// * The loop user variable function that computes the loop user variable when 
- ///   given a logical iteration number. 
- /// 
- /// These captured statements provide the link between C/C++ semantics and the 
- /// logical iteration counters used by the OpenMPIRBuilder which is 
- /// language-agnostic and therefore does not know e.g. how to advance a 
- /// random-access iterator. The OpenMPIRBuilder will use this information to 
- /// apply simd, workshare-loop, distribute, taskloop and loop directives to the 
- /// loop. For compatibility with the non-OpenMPIRBuilder codegen path, an 
- /// OMPCanonicalLoop can itself also be wrapped into the CapturedStmts of an 
- /// OMPLoopDirective and skipped when searching for the associated syntactical 
- /// loop. 
- /// 
- /// Example: 
- /// <code> 
- ///   std::vector<std::string> Container{1,2,3}; 
- ///   for (std::string Str : Container) 
- ///      Body(Str); 
- /// </code> 
- /// which is syntactic sugar for approximately: 
- /// <code> 
- ///   auto &&__range = Container; 
- ///   auto __begin = std::begin(__range); 
- ///   auto __end = std::end(__range); 
- ///   for (; __begin != __end; ++__begin) { 
- ///     std::String Str = *__begin; 
- ///     Body(Str); 
- ///   } 
- /// </code> 
- /// In this example, the loop user variable is `Str`, the loop iteration 
- /// variable is `__begin` of type `std::vector<std::string>::iterator` and the 
- /// logical iteration number type is `size_t` (unsigned version of 
- /// `std::vector<std::string>::iterator::difference_type` aka `ptrdiff_t`). 
- /// Therefore, the distance function will be 
- /// <code> 
- ///   [&](size_t &Result) { Result = __end - __begin; } 
- /// </code> 
- /// and the loop variable function is 
- /// <code> 
- ///   [&,__begin](std::vector<std::string>::iterator &Result, size_t Logical) { 
- ///     Result = __begin + Logical; 
- ///   } 
- /// </code> 
- /// The variable `__begin`, aka the loop iteration variable, is captured by 
- /// value because it is modified in the loop body, but both functions require 
- /// the initial value. The OpenMP specification explicitly leaves unspecified 
- /// when the loop expressions are evaluated such that a capture by reference is 
- /// sufficient. 
- class OMPCanonicalLoop : public Stmt { 
-   friend class ASTStmtReader; 
-   friend class ASTStmtWriter; 
-   
-   /// Children of this AST node. 
-   enum { 
-     LOOP_STMT, 
-     DISTANCE_FUNC, 
-     LOOPVAR_FUNC, 
-     LOOPVAR_REF, 
-     LastSubStmt = LOOPVAR_REF 
-   }; 
-   
- private: 
-   /// This AST node's children. 
-   Stmt *SubStmts[LastSubStmt + 1] = {}; 
-   
-   OMPCanonicalLoop() : Stmt(StmtClass::OMPCanonicalLoopClass) {} 
-   
- public: 
-   /// Create a new OMPCanonicalLoop. 
-   static OMPCanonicalLoop *create(const ASTContext &Ctx, Stmt *LoopStmt, 
-                                   CapturedStmt *DistanceFunc, 
-                                   CapturedStmt *LoopVarFunc, 
-                                   DeclRefExpr *LoopVarRef) { 
-     OMPCanonicalLoop *S = new (Ctx) OMPCanonicalLoop(); 
-     S->setLoopStmt(LoopStmt); 
-     S->setDistanceFunc(DistanceFunc); 
-     S->setLoopVarFunc(LoopVarFunc); 
-     S->setLoopVarRef(LoopVarRef); 
-     return S; 
-   } 
-   
-   /// Create an empty OMPCanonicalLoop for deserialization. 
-   static OMPCanonicalLoop *createEmpty(const ASTContext &Ctx) { 
-     return new (Ctx) OMPCanonicalLoop(); 
-   } 
-   
-   static bool classof(const Stmt *S) { 
-     return S->getStmtClass() == StmtClass::OMPCanonicalLoopClass; 
-   } 
-   
-   SourceLocation getBeginLoc() const { return getLoopStmt()->getBeginLoc(); } 
-   SourceLocation getEndLoc() const { return getLoopStmt()->getEndLoc(); } 
-   
-   /// Return this AST node's children. 
-   /// @{ 
-   child_range children() { 
-     return child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1); 
-   } 
-   const_child_range children() const { 
-     return const_child_range(&SubStmts[0], &SubStmts[0] + LastSubStmt + 1); 
-   } 
-   /// @} 
-   
-   /// The wrapped syntactic loop statement (ForStmt or CXXForRangeStmt). 
-   /// @{ 
-   Stmt *getLoopStmt() { return SubStmts[LOOP_STMT]; } 
-   const Stmt *getLoopStmt() const { return SubStmts[LOOP_STMT]; } 
-   void setLoopStmt(Stmt *S) { 
-     assert((isa<ForStmt>(S) || isa<CXXForRangeStmt>(S)) && 
-            "Canonical loop must be a for loop (range-based or otherwise)"); 
-     SubStmts[LOOP_STMT] = S; 
-   } 
-   /// @} 
-   
-   /// The function that computes the number of loop iterations. Can be evaluated 
-   /// before entering the loop but after the syntactical loop's init 
-   /// statement(s). 
-   /// 
-   /// Function signature: void(LogicalTy &Result) 
-   /// Any values necessary to compute the distance are captures of the closure. 
-   /// @{ 
-   CapturedStmt *getDistanceFunc() { 
-     return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]); 
-   } 
-   const CapturedStmt *getDistanceFunc() const { 
-     return cast<CapturedStmt>(SubStmts[DISTANCE_FUNC]); 
-   } 
-   void setDistanceFunc(CapturedStmt *S) { 
-     assert(S && "Expected non-null captured statement"); 
-     SubStmts[DISTANCE_FUNC] = S; 
-   } 
-   /// @} 
-   
-   /// The function that computes the loop user variable from a logical iteration 
-   /// counter. Can be evaluated as first statement in the loop. 
-   /// 
-   /// Function signature: void(LoopVarTy &Result, LogicalTy Number) 
-   /// Any other values required to compute the loop user variable (such as start 
-   /// value, step size) are captured by the closure. In particular, the initial 
-   /// value of loop iteration variable is captured by value to be unaffected by 
-   /// previous iterations. 
-   /// @{ 
-   CapturedStmt *getLoopVarFunc() { 
-     return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]); 
-   } 
-   const CapturedStmt *getLoopVarFunc() const { 
-     return cast<CapturedStmt>(SubStmts[LOOPVAR_FUNC]); 
-   } 
-   void setLoopVarFunc(CapturedStmt *S) { 
-     assert(S && "Expected non-null captured statement"); 
-     SubStmts[LOOPVAR_FUNC] = S; 
-   } 
-   /// @} 
-   
-   /// Reference to the loop user variable as accessed in the loop body. 
-   /// @{ 
-   DeclRefExpr *getLoopVarRef() { 
-     return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]); 
-   } 
-   const DeclRefExpr *getLoopVarRef() const { 
-     return cast<DeclRefExpr>(SubStmts[LOOPVAR_REF]); 
-   } 
-   void setLoopVarRef(DeclRefExpr *E) { 
-     assert(E && "Expected non-null loop variable"); 
-     SubStmts[LOOPVAR_REF] = E; 
-   } 
-   /// @} 
- }; 
-   
- /// This is a basic class for representing single OpenMP executable 
- /// directive. 
- /// 
- class OMPExecutableDirective : public Stmt { 
-   friend class ASTStmtReader; 
-   friend class ASTStmtWriter; 
-   
-   /// Kind of the directive. 
-   OpenMPDirectiveKind Kind = llvm::omp::OMPD_unknown; 
-   /// Starting location of the directive (directive keyword). 
-   SourceLocation StartLoc; 
-   /// Ending location of the directive. 
-   SourceLocation EndLoc; 
-   
-   /// Get the clauses storage. 
-   MutableArrayRef<OMPClause *> getClauses() { 
-     if (!Data) 
-       return std::nullopt; 
-     return Data->getClauses(); 
-   } 
-   
- protected: 
-   /// Data, associated with the directive. 
-   OMPChildren *Data = nullptr; 
-   
-   /// Build instance of directive of class \a K. 
-   /// 
-   /// \param SC Statement class. 
-   /// \param K Kind of OpenMP directive. 
-   /// \param StartLoc Starting location of the directive (directive keyword). 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPExecutableDirective(StmtClass SC, OpenMPDirectiveKind K, 
-                          SourceLocation StartLoc, SourceLocation EndLoc) 
-       : Stmt(SC), Kind(K), StartLoc(std::move(StartLoc)), 
-         EndLoc(std::move(EndLoc)) {} 
-   
-   template <typename T, typename... Params> 
-   static T *createDirective(const ASTContext &C, ArrayRef<OMPClause *> Clauses, 
-                             Stmt *AssociatedStmt, unsigned NumChildren, 
-                             Params &&... P) { 
-     void *Mem = 
-         C.Allocate(sizeof(T) + OMPChildren::size(Clauses.size(), AssociatedStmt, 
-                                                  NumChildren), 
-                    alignof(T)); 
-   
-     auto *Data = OMPChildren::Create(reinterpret_cast<T *>(Mem) + 1, Clauses, 
-                                      AssociatedStmt, NumChildren); 
-     auto *Inst = new (Mem) T(std::forward<Params>(P)...); 
-     Inst->Data = Data; 
-     return Inst; 
-   } 
-   
-   template <typename T, typename... Params> 
-   static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses, 
-                                  bool HasAssociatedStmt, unsigned NumChildren, 
-                                  Params &&... P) { 
-     void *Mem = 
-         C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt, 
-                                                  NumChildren), 
-                    alignof(T)); 
-     auto *Data = 
-         OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses, 
-                                  HasAssociatedStmt, NumChildren); 
-     auto *Inst = new (Mem) T(std::forward<Params>(P)...); 
-     Inst->Data = Data; 
-     return Inst; 
-   } 
-   
-   template <typename T> 
-   static T *createEmptyDirective(const ASTContext &C, unsigned NumClauses, 
-                                  bool HasAssociatedStmt = false, 
-                                  unsigned NumChildren = 0) { 
-     void *Mem = 
-         C.Allocate(sizeof(T) + OMPChildren::size(NumClauses, HasAssociatedStmt, 
-                                                  NumChildren), 
-                    alignof(T)); 
-     auto *Data = 
-         OMPChildren::CreateEmpty(reinterpret_cast<T *>(Mem) + 1, NumClauses, 
-                                  HasAssociatedStmt, NumChildren); 
-     auto *Inst = new (Mem) T; 
-     Inst->Data = Data; 
-     return Inst; 
-   } 
-   
- public: 
-   /// Iterates over expressions/statements used in the construct. 
-   class used_clauses_child_iterator 
-       : public llvm::iterator_adaptor_base< 
-             used_clauses_child_iterator, ArrayRef<OMPClause *>::iterator, 
-             std::forward_iterator_tag, Stmt *, ptrdiff_t, Stmt *, Stmt *> { 
-     ArrayRef<OMPClause *>::iterator End; 
-     OMPClause::child_iterator ChildI, ChildEnd; 
-   
-     void MoveToNext() { 
-       if (ChildI != ChildEnd) 
-         return; 
-       while (this->I != End) { 
-         ++this->I; 
-         if (this->I != End) { 
-           ChildI = (*this->I)->used_children().begin(); 
-           ChildEnd = (*this->I)->used_children().end(); 
-           if (ChildI != ChildEnd) 
-             return; 
-         } 
-       } 
-     } 
-   
-   public: 
-     explicit used_clauses_child_iterator(ArrayRef<OMPClause *> Clauses) 
-         : used_clauses_child_iterator::iterator_adaptor_base(Clauses.begin()), 
-           End(Clauses.end()) { 
-       if (this->I != End) { 
-         ChildI = (*this->I)->used_children().begin(); 
-         ChildEnd = (*this->I)->used_children().end(); 
-         MoveToNext(); 
-       } 
-     } 
-     Stmt *operator*() const { return *ChildI; } 
-     Stmt *operator->() const { return **this; } 
-   
-     used_clauses_child_iterator &operator++() { 
-       ++ChildI; 
-       if (ChildI != ChildEnd) 
-         return *this; 
-       if (this->I != End) { 
-         ++this->I; 
-         if (this->I != End) { 
-           ChildI = (*this->I)->used_children().begin(); 
-           ChildEnd = (*this->I)->used_children().end(); 
-         } 
-       } 
-       MoveToNext(); 
-       return *this; 
-     } 
-   }; 
-   
-   static llvm::iterator_range<used_clauses_child_iterator> 
-   used_clauses_children(ArrayRef<OMPClause *> Clauses) { 
-     return { 
-         used_clauses_child_iterator(Clauses), 
-         used_clauses_child_iterator(llvm::ArrayRef(Clauses.end(), (size_t)0))}; 
-   } 
-   
-   /// Iterates over a filtered subrange of clauses applied to a 
-   /// directive. 
-   /// 
-   /// This iterator visits only clauses of type SpecificClause. 
-   template <typename SpecificClause> 
-   class specific_clause_iterator 
-       : public llvm::iterator_adaptor_base< 
-             specific_clause_iterator<SpecificClause>, 
-             ArrayRef<OMPClause *>::const_iterator, std::forward_iterator_tag, 
-             const SpecificClause *, ptrdiff_t, const SpecificClause *, 
-             const SpecificClause *> { 
-     ArrayRef<OMPClause *>::const_iterator End; 
-   
-     void SkipToNextClause() { 
-       while (this->I != End && !isa<SpecificClause>(*this->I)) 
-         ++this->I; 
-     } 
-   
-   public: 
-     explicit specific_clause_iterator(ArrayRef<OMPClause *> Clauses) 
-         : specific_clause_iterator::iterator_adaptor_base(Clauses.begin()), 
-           End(Clauses.end()) { 
-       SkipToNextClause(); 
-     } 
-   
-     const SpecificClause *operator*() const { 
-       return cast<SpecificClause>(*this->I); 
-     } 
-     const SpecificClause *operator->() const { return **this; } 
-   
-     specific_clause_iterator &operator++() { 
-       ++this->I; 
-       SkipToNextClause(); 
-       return *this; 
-     } 
-   }; 
-   
-   template <typename SpecificClause> 
-   static llvm::iterator_range<specific_clause_iterator<SpecificClause>> 
-   getClausesOfKind(ArrayRef<OMPClause *> Clauses) { 
-     return {specific_clause_iterator<SpecificClause>(Clauses), 
-             specific_clause_iterator<SpecificClause>( 
-                 llvm::ArrayRef(Clauses.end(), (size_t)0))}; 
-   } 
-   
-   template <typename SpecificClause> 
-   llvm::iterator_range<specific_clause_iterator<SpecificClause>> 
-   getClausesOfKind() const { 
-     return getClausesOfKind<SpecificClause>(clauses()); 
-   } 
-   
-   /// Gets a single clause of the specified kind associated with the 
-   /// current directive iff there is only one clause of this kind (and assertion 
-   /// is fired if there is more than one clause is associated with the 
-   /// directive). Returns nullptr if no clause of this kind is associated with 
-   /// the directive. 
-   template <typename SpecificClause> 
-   static const SpecificClause *getSingleClause(ArrayRef<OMPClause *> Clauses) { 
-     auto ClausesOfKind = getClausesOfKind<SpecificClause>(Clauses); 
-   
-     if (ClausesOfKind.begin() != ClausesOfKind.end()) { 
-       assert(std::next(ClausesOfKind.begin()) == ClausesOfKind.end() && 
-              "There are at least 2 clauses of the specified kind"); 
-       return *ClausesOfKind.begin(); 
-     } 
-     return nullptr; 
-   } 
-   
-   template <typename SpecificClause> 
-   const SpecificClause *getSingleClause() const { 
-     return getSingleClause<SpecificClause>(clauses()); 
-   } 
-   
-   /// Returns true if the current directive has one or more clauses of a 
-   /// specific kind. 
-   template <typename SpecificClause> 
-   bool hasClausesOfKind() const { 
-     auto Clauses = getClausesOfKind<SpecificClause>(); 
-     return Clauses.begin() != Clauses.end(); 
-   } 
-   
-   /// Returns starting location of directive kind. 
-   SourceLocation getBeginLoc() const { return StartLoc; } 
-   /// Returns ending location of directive. 
-   SourceLocation getEndLoc() const { return EndLoc; } 
-   
-   /// Set starting location of directive kind. 
-   /// 
-   /// \param Loc New starting location of directive. 
-   /// 
-   void setLocStart(SourceLocation Loc) { StartLoc = Loc; } 
-   /// Set ending location of directive. 
-   /// 
-   /// \param Loc New ending location of directive. 
-   /// 
-   void setLocEnd(SourceLocation Loc) { EndLoc = Loc; } 
-   
-   /// Get number of clauses. 
-   unsigned getNumClauses() const { 
-     if (!Data) 
-       return 0; 
-     return Data->getNumClauses(); 
-   } 
-   
-   /// Returns specified clause. 
-   /// 
-   /// \param I Number of clause. 
-   /// 
-   OMPClause *getClause(unsigned I) const { return clauses()[I]; } 
-   
-   /// Returns true if directive has associated statement. 
-   bool hasAssociatedStmt() const { return Data && Data->hasAssociatedStmt(); } 
-   
-   /// Returns statement associated with the directive. 
-   const Stmt *getAssociatedStmt() const { 
-     return const_cast<OMPExecutableDirective *>(this)->getAssociatedStmt(); 
-   } 
-   Stmt *getAssociatedStmt() { 
-     assert(hasAssociatedStmt() && 
-            "Expected directive with the associated statement."); 
-     return Data->getAssociatedStmt(); 
-   } 
-   
-   /// Returns the captured statement associated with the 
-   /// component region within the (combined) directive. 
-   /// 
-   /// \param RegionKind Component region kind. 
-   const CapturedStmt *getCapturedStmt(OpenMPDirectiveKind RegionKind) const { 
-     assert(hasAssociatedStmt() && 
-            "Expected directive with the associated statement."); 
-     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 
-     getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind()); 
-     return Data->getCapturedStmt(RegionKind, CaptureRegions); 
-   } 
-   
-   /// Get innermost captured statement for the construct. 
-   CapturedStmt *getInnermostCapturedStmt() { 
-     assert(hasAssociatedStmt() && 
-            "Expected directive with the associated statement."); 
-     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 
-     getOpenMPCaptureRegions(CaptureRegions, getDirectiveKind()); 
-     return Data->getInnermostCapturedStmt(CaptureRegions); 
-   } 
-   
-   const CapturedStmt *getInnermostCapturedStmt() const { 
-     return const_cast<OMPExecutableDirective *>(this) 
-         ->getInnermostCapturedStmt(); 
-   } 
-   
-   OpenMPDirectiveKind getDirectiveKind() const { return Kind; } 
-   
-   static bool classof(const Stmt *S) { 
-     return S->getStmtClass() >= firstOMPExecutableDirectiveConstant && 
-            S->getStmtClass() <= lastOMPExecutableDirectiveConstant; 
-   } 
-   
-   child_range children() { 
-     if (!Data) 
-       return child_range(child_iterator(), child_iterator()); 
-     return Data->getAssociatedStmtAsRange(); 
-   } 
-   
-   const_child_range children() const { 
-     return const_cast<OMPExecutableDirective *>(this)->children(); 
-   } 
-   
-   ArrayRef<OMPClause *> clauses() const { 
-     if (!Data) 
-       return std::nullopt; 
-     return Data->getClauses(); 
-   } 
-   
-   /// Returns whether or not this is a Standalone directive. 
-   /// 
-   /// Stand-alone directives are executable directives 
-   /// that have no associated user code. 
-   bool isStandaloneDirective() const; 
-   
-   /// Returns the AST node representing OpenMP structured-block of this 
-   /// OpenMP executable directive, 
-   /// Prerequisite: Executable Directive must not be Standalone directive. 
-   const Stmt *getStructuredBlock() const { 
-     return const_cast<OMPExecutableDirective *>(this)->getStructuredBlock(); 
-   } 
-   Stmt *getStructuredBlock(); 
-   
-   const Stmt *getRawStmt() const { 
-     return const_cast<OMPExecutableDirective *>(this)->getRawStmt(); 
-   } 
-   Stmt *getRawStmt() { 
-     assert(hasAssociatedStmt() && 
-            "Expected directive with the associated statement."); 
-     return Data->getRawStmt(); 
-   } 
- }; 
-   
- /// This represents '#pragma omp parallel' directive. 
- /// 
- /// \code 
- /// #pragma omp parallel private(a,b) reduction(+: c,d) 
- /// \endcode 
- /// In this example directive '#pragma omp parallel' has clauses 'private' 
- /// with the variables 'a' and 'b' and 'reduction' with operator '+' and 
- /// variables 'c' and 'd'. 
- /// 
- class OMPParallelDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// true if the construct has inner cancel directive. 
-   bool HasCancel = false; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive (directive keyword). 
-   /// \param EndLoc Ending Location of the directive. 
-   /// 
-   OMPParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPParallelDirectiveClass, 
-                                llvm::omp::OMPD_parallel, StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPParallelDirective() 
-       : OMPExecutableDirective(OMPParallelDirectiveClass, 
-                                llvm::omp::OMPD_parallel, SourceLocation(), 
-                                SourceLocation()) {} 
-   
-   /// Sets special task reduction descriptor. 
-   void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 
-   
-   /// Set cancel state. 
-   void setHasCancel(bool Has) { HasCancel = Has; } 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement associated with the directive. 
-   /// \param TaskRedRef Task reduction special reference expression to handle 
-   /// taskgroup descriptor. 
-   /// \param HasCancel true if this directive has inner cancel directive. 
-   /// 
-   static OMPParallelDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 
-          bool HasCancel); 
-   
-   /// Creates an empty directive with the place for \a N clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPParallelDirective *CreateEmpty(const ASTContext &C, 
-                                            unsigned NumClauses, EmptyShell); 
-   
-   /// Returns special task reduction reference expression. 
-   Expr *getTaskReductionRefExpr() { 
-     return cast_or_null<Expr>(Data->getChildren()[0]); 
-   } 
-   const Expr *getTaskReductionRefExpr() const { 
-     return const_cast<OMPParallelDirective *>(this)->getTaskReductionRefExpr(); 
-   } 
-   
-   /// Return true if current directive has inner cancel directive. 
-   bool hasCancel() const { return HasCancel; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPParallelDirectiveClass; 
-   } 
- }; 
-   
- /// The base class for all loop-based directives, including loop transformation 
- /// directives. 
- class OMPLoopBasedDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   
- protected: 
-   /// Number of collapsed loops as specified by 'collapse' clause. 
-   unsigned NumAssociatedLoops = 0; 
-   
-   /// Build instance of loop directive of class \a Kind. 
-   /// 
-   /// \param SC Statement class. 
-   /// \param Kind Kind of OpenMP directive. 
-   /// \param StartLoc Starting location of the directive (directive keyword). 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param NumAssociatedLoops Number of loops associated with the construct. 
-   /// 
-   OMPLoopBasedDirective(StmtClass SC, OpenMPDirectiveKind Kind, 
-                         SourceLocation StartLoc, SourceLocation EndLoc, 
-                         unsigned NumAssociatedLoops) 
-       : OMPExecutableDirective(SC, Kind, StartLoc, EndLoc), 
-         NumAssociatedLoops(NumAssociatedLoops) {} 
-   
- public: 
-   /// The expressions built to support OpenMP loops in combined/composite 
-   /// pragmas (e.g. pragma omp distribute parallel for) 
-   struct DistCombinedHelperExprs { 
-     /// DistributeLowerBound - used when composing 'omp distribute' with 
-     /// 'omp for' in a same construct. 
-     Expr *LB; 
-     /// DistributeUpperBound - used when composing 'omp distribute' with 
-     /// 'omp for' in a same construct. 
-     Expr *UB; 
-     /// DistributeEnsureUpperBound - used when composing 'omp distribute' 
-     ///  with 'omp for' in a same construct, EUB depends on DistUB 
-     Expr *EUB; 
-     /// Distribute loop iteration variable init used when composing 'omp 
-     /// distribute' 
-     ///  with 'omp for' in a same construct 
-     Expr *Init; 
-     /// Distribute Loop condition used when composing 'omp distribute' 
-     ///  with 'omp for' in a same construct 
-     Expr *Cond; 
-     /// Update of LowerBound for statically scheduled omp loops for 
-     /// outer loop in combined constructs (e.g. 'distribute parallel for') 
-     Expr *NLB; 
-     /// Update of UpperBound for statically scheduled omp loops for 
-     /// outer loop in combined constructs (e.g. 'distribute parallel for') 
-     Expr *NUB; 
-     /// Distribute Loop condition used when composing 'omp distribute' 
-     ///  with 'omp for' in a same construct when schedule is chunked. 
-     Expr *DistCond; 
-     /// 'omp parallel for' loop condition used when composed with 
-     /// 'omp distribute' in the same construct and when schedule is 
-     /// chunked and the chunk size is 1. 
-     Expr *ParForInDistCond; 
-   }; 
-   
-   /// The expressions built for the OpenMP loop CodeGen for the 
-   /// whole collapsed loop nest. 
-   struct HelperExprs { 
-     /// Loop iteration variable. 
-     Expr *IterationVarRef; 
-     /// Loop last iteration number. 
-     Expr *LastIteration; 
-     /// Loop number of iterations. 
-     Expr *NumIterations; 
-     /// Calculation of last iteration. 
-     Expr *CalcLastIteration; 
-     /// Loop pre-condition. 
-     Expr *PreCond; 
-     /// Loop condition. 
-     Expr *Cond; 
-     /// Loop iteration variable init. 
-     Expr *Init; 
-     /// Loop increment. 
-     Expr *Inc; 
-     /// IsLastIteration - local flag variable passed to runtime. 
-     Expr *IL; 
-     /// LowerBound - local variable passed to runtime. 
-     Expr *LB; 
-     /// UpperBound - local variable passed to runtime. 
-     Expr *UB; 
-     /// Stride - local variable passed to runtime. 
-     Expr *ST; 
-     /// EnsureUpperBound -- expression UB = min(UB, NumIterations). 
-     Expr *EUB; 
-     /// Update of LowerBound for statically scheduled 'omp for' loops. 
-     Expr *NLB; 
-     /// Update of UpperBound for statically scheduled 'omp for' loops. 
-     Expr *NUB; 
-     /// PreviousLowerBound - local variable passed to runtime in the 
-     /// enclosing schedule or null if that does not apply. 
-     Expr *PrevLB; 
-     /// PreviousUpperBound - local variable passed to runtime in the 
-     /// enclosing schedule or null if that does not apply. 
-     Expr *PrevUB; 
-     /// DistInc - increment expression for distribute loop when found 
-     /// combined with a further loop level (e.g. in 'distribute parallel for') 
-     /// expression IV = IV + ST 
-     Expr *DistInc; 
-     /// PrevEUB - expression similar to EUB but to be used when loop 
-     /// scheduling uses PrevLB and PrevUB (e.g.  in 'distribute parallel for' 
-     /// when ensuring that the UB is either the calculated UB by the runtime or 
-     /// the end of the assigned distribute chunk) 
-     /// expression UB = min (UB, PrevUB) 
-     Expr *PrevEUB; 
-     /// Counters Loop counters. 
-     SmallVector<Expr *, 4> Counters; 
-     /// PrivateCounters Loop counters. 
-     SmallVector<Expr *, 4> PrivateCounters; 
-     /// Expressions for loop counters inits for CodeGen. 
-     SmallVector<Expr *, 4> Inits; 
-     /// Expressions for loop counters update for CodeGen. 
-     SmallVector<Expr *, 4> Updates; 
-     /// Final loop counter values for GodeGen. 
-     SmallVector<Expr *, 4> Finals; 
-     /// List of counters required for the generation of the non-rectangular 
-     /// loops. 
-     SmallVector<Expr *, 4> DependentCounters; 
-     /// List of initializers required for the generation of the non-rectangular 
-     /// loops. 
-     SmallVector<Expr *, 4> DependentInits; 
-     /// List of final conditions required for the generation of the 
-     /// non-rectangular loops. 
-     SmallVector<Expr *, 4> FinalsConditions; 
-     /// Init statement for all captured expressions. 
-     Stmt *PreInits; 
-   
-     /// Expressions used when combining OpenMP loop pragmas 
-     DistCombinedHelperExprs DistCombinedFields; 
-   
-     /// Check if all the expressions are built (does not check the 
-     /// worksharing ones). 
-     bool builtAll() { 
-       return IterationVarRef != nullptr && LastIteration != nullptr && 
-              NumIterations != nullptr && PreCond != nullptr && 
-              Cond != nullptr && Init != nullptr && Inc != nullptr; 
-     } 
-   
-     /// Initialize all the fields to null. 
-     /// \param Size Number of elements in the 
-     /// counters/finals/updates/dependent_counters/dependent_inits/finals_conditions 
-     /// arrays. 
-     void clear(unsigned Size) { 
-       IterationVarRef = nullptr; 
-       LastIteration = nullptr; 
-       CalcLastIteration = nullptr; 
-       PreCond = nullptr; 
-       Cond = nullptr; 
-       Init = nullptr; 
-       Inc = nullptr; 
-       IL = nullptr; 
-       LB = nullptr; 
-       UB = nullptr; 
-       ST = nullptr; 
-       EUB = nullptr; 
-       NLB = nullptr; 
-       NUB = nullptr; 
-       NumIterations = nullptr; 
-       PrevLB = nullptr; 
-       PrevUB = nullptr; 
-       DistInc = nullptr; 
-       PrevEUB = nullptr; 
-       Counters.resize(Size); 
-       PrivateCounters.resize(Size); 
-       Inits.resize(Size); 
-       Updates.resize(Size); 
-       Finals.resize(Size); 
-       DependentCounters.resize(Size); 
-       DependentInits.resize(Size); 
-       FinalsConditions.resize(Size); 
-       for (unsigned I = 0; I < Size; ++I) { 
-         Counters[I] = nullptr; 
-         PrivateCounters[I] = nullptr; 
-         Inits[I] = nullptr; 
-         Updates[I] = nullptr; 
-         Finals[I] = nullptr; 
-         DependentCounters[I] = nullptr; 
-         DependentInits[I] = nullptr; 
-         FinalsConditions[I] = nullptr; 
-       } 
-       PreInits = nullptr; 
-       DistCombinedFields.LB = nullptr; 
-       DistCombinedFields.UB = nullptr; 
-       DistCombinedFields.EUB = nullptr; 
-       DistCombinedFields.Init = nullptr; 
-       DistCombinedFields.Cond = nullptr; 
-       DistCombinedFields.NLB = nullptr; 
-       DistCombinedFields.NUB = nullptr; 
-       DistCombinedFields.DistCond = nullptr; 
-       DistCombinedFields.ParForInDistCond = nullptr; 
-     } 
-   }; 
-   
-   /// Get number of collapsed loops. 
-   unsigned getLoopsNumber() const { return NumAssociatedLoops; } 
-   
-   /// Try to find the next loop sub-statement in the specified statement \p 
-   /// CurStmt. 
-   /// \param TryImperfectlyNestedLoops true, if we need to try to look for the 
-   /// imperfectly nested loop. 
-   static Stmt *tryToFindNextInnerLoop(Stmt *CurStmt, 
-                                       bool TryImperfectlyNestedLoops); 
-   static const Stmt *tryToFindNextInnerLoop(const Stmt *CurStmt, 
-                                             bool TryImperfectlyNestedLoops) { 
-     return tryToFindNextInnerLoop(const_cast<Stmt *>(CurStmt), 
-                                   TryImperfectlyNestedLoops); 
-   } 
-   
-   /// Calls the specified callback function for all the loops in \p CurStmt, 
-   /// from the outermost to the innermost. 
-   static bool 
-   doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops, 
-                 unsigned NumLoops, 
-                 llvm::function_ref<bool(unsigned, Stmt *)> Callback, 
-                 llvm::function_ref<void(OMPLoopTransformationDirective *)> 
-                     OnTransformationCallback); 
-   static bool 
-   doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops, 
-                 unsigned NumLoops, 
-                 llvm::function_ref<bool(unsigned, const Stmt *)> Callback, 
-                 llvm::function_ref<void(const OMPLoopTransformationDirective *)> 
-                     OnTransformationCallback) { 
-     auto &&NewCallback = [Callback](unsigned Cnt, Stmt *CurStmt) { 
-       return Callback(Cnt, CurStmt); 
-     }; 
-     auto &&NewTransformCb = 
-         [OnTransformationCallback](OMPLoopTransformationDirective *A) { 
-           OnTransformationCallback(A); 
-         }; 
-     return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, 
-                          NumLoops, NewCallback, NewTransformCb); 
-   } 
-   
-   /// Calls the specified callback function for all the loops in \p CurStmt, 
-   /// from the outermost to the innermost. 
-   static bool 
-   doForAllLoops(Stmt *CurStmt, bool TryImperfectlyNestedLoops, 
-                 unsigned NumLoops, 
-                 llvm::function_ref<bool(unsigned, Stmt *)> Callback) { 
-     auto &&TransformCb = [](OMPLoopTransformationDirective *) {}; 
-     return doForAllLoops(CurStmt, TryImperfectlyNestedLoops, NumLoops, Callback, 
-                          TransformCb); 
-   } 
-   static bool 
-   doForAllLoops(const Stmt *CurStmt, bool TryImperfectlyNestedLoops, 
-                 unsigned NumLoops, 
-                 llvm::function_ref<bool(unsigned, const Stmt *)> Callback) { 
-     auto &&NewCallback = [Callback](unsigned Cnt, const Stmt *CurStmt) { 
-       return Callback(Cnt, CurStmt); 
-     }; 
-     return doForAllLoops(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, 
-                          NumLoops, NewCallback); 
-   } 
-   
-   /// Calls the specified callback function for all the loop bodies in \p 
-   /// CurStmt, from the outermost loop to the innermost. 
-   static void doForAllLoopsBodies( 
-       Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops, 
-       llvm::function_ref<void(unsigned, Stmt *, Stmt *)> Callback); 
-   static void doForAllLoopsBodies( 
-       const Stmt *CurStmt, bool TryImperfectlyNestedLoops, unsigned NumLoops, 
-       llvm::function_ref<void(unsigned, const Stmt *, const Stmt *)> Callback) { 
-     auto &&NewCallback = [Callback](unsigned Cnt, Stmt *Loop, Stmt *Body) { 
-       Callback(Cnt, Loop, Body); 
-     }; 
-     doForAllLoopsBodies(const_cast<Stmt *>(CurStmt), TryImperfectlyNestedLoops, 
-                         NumLoops, NewCallback); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     if (auto *D = dyn_cast<OMPExecutableDirective>(T)) 
-       return isOpenMPLoopDirective(D->getDirectiveKind()); 
-     return false; 
-   } 
- }; 
-   
- /// The base class for all loop transformation directives. 
- class OMPLoopTransformationDirective : public OMPLoopBasedDirective { 
-   friend class ASTStmtReader; 
-   
-   /// Number of loops generated by this loop transformation. 
-   unsigned NumGeneratedLoops = 0; 
-   
- protected: 
-   explicit OMPLoopTransformationDirective(StmtClass SC, 
-                                           OpenMPDirectiveKind Kind, 
-                                           SourceLocation StartLoc, 
-                                           SourceLocation EndLoc, 
-                                           unsigned NumAssociatedLoops) 
-       : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, NumAssociatedLoops) {} 
-   
-   /// Set the number of loops generated by this loop transformation. 
-   void setNumGeneratedLoops(unsigned Num) { NumGeneratedLoops = Num; } 
-   
- public: 
-   /// Return the number of associated (consumed) loops. 
-   unsigned getNumAssociatedLoops() const { return getLoopsNumber(); } 
-   
-   /// Return the number of loops generated by this loop transformation. 
-   unsigned getNumGeneratedLoops() { return NumGeneratedLoops; } 
-   
-   /// Get the de-sugared statements after the loop transformation. 
-   /// 
-   /// Might be nullptr if either the directive generates no loops and is handled 
-   /// directly in CodeGen, or resolving a template-dependence context is 
-   /// required. 
-   Stmt *getTransformedStmt() const; 
-   
-   /// Return preinits statement. 
-   Stmt *getPreInits() const; 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTileDirectiveClass || 
-            T->getStmtClass() == OMPUnrollDirectiveClass; 
-   } 
- }; 
-   
- /// This is a common base class for loop directives ('omp simd', 'omp 
- /// for', 'omp for simd' etc.). It is responsible for the loop code generation. 
- /// 
- class OMPLoopDirective : public OMPLoopBasedDirective { 
-   friend class ASTStmtReader; 
-   
-   /// Offsets to the stored exprs. 
-   /// This enumeration contains offsets to all the pointers to children 
-   /// expressions stored in OMPLoopDirective. 
-   /// The first 9 children are necessary for all the loop directives, 
-   /// the next 8 are specific to the worksharing ones, and the next 11 are 
-   /// used for combined constructs containing two pragmas associated to loops. 
-   /// After the fixed children, three arrays of length NumAssociatedLoops are 
-   /// allocated: loop counters, their updates and final values. 
-   /// PrevLowerBound and PrevUpperBound are used to communicate blocking 
-   /// information in composite constructs which require loop blocking 
-   /// DistInc is used to generate the increment expression for the distribute 
-   /// loop when combined with a further nested loop 
-   /// PrevEnsureUpperBound is used as the EnsureUpperBound expression for the 
-   /// for loop when combined with a previous distribute loop in the same pragma 
-   /// (e.g. 'distribute parallel for') 
-   /// 
-   enum { 
-     IterationVariableOffset = 0, 
-     LastIterationOffset = 1, 
-     CalcLastIterationOffset = 2, 
-     PreConditionOffset = 3, 
-     CondOffset = 4, 
-     InitOffset = 5, 
-     IncOffset = 6, 
-     PreInitsOffset = 7, 
-     // The '...End' enumerators do not correspond to child expressions - they 
-     // specify the offset to the end (and start of the following counters/ 
-     // updates/finals/dependent_counters/dependent_inits/finals_conditions 
-     // arrays). 
-     DefaultEnd = 8, 
-     // The following 8 exprs are used by worksharing and distribute loops only. 
-     IsLastIterVariableOffset = 8, 
-     LowerBoundVariableOffset = 9, 
-     UpperBoundVariableOffset = 10, 
-     StrideVariableOffset = 11, 
-     EnsureUpperBoundOffset = 12, 
-     NextLowerBoundOffset = 13, 
-     NextUpperBoundOffset = 14, 
-     NumIterationsOffset = 15, 
-     // Offset to the end for worksharing loop directives. 
-     WorksharingEnd = 16, 
-     PrevLowerBoundVariableOffset = 16, 
-     PrevUpperBoundVariableOffset = 17, 
-     DistIncOffset = 18, 
-     PrevEnsureUpperBoundOffset = 19, 
-     CombinedLowerBoundVariableOffset = 20, 
-     CombinedUpperBoundVariableOffset = 21, 
-     CombinedEnsureUpperBoundOffset = 22, 
-     CombinedInitOffset = 23, 
-     CombinedConditionOffset = 24, 
-     CombinedNextLowerBoundOffset = 25, 
-     CombinedNextUpperBoundOffset = 26, 
-     CombinedDistConditionOffset = 27, 
-     CombinedParForInDistConditionOffset = 28, 
-     // Offset to the end (and start of the following 
-     // counters/updates/finals/dependent_counters/dependent_inits/finals_conditions 
-     // arrays) for combined distribute loop directives. 
-     CombinedDistributeEnd = 29, 
-   }; 
-   
-   /// Get the counters storage. 
-   MutableArrayRef<Expr *> getCounters() { 
-     auto **Storage = reinterpret_cast<Expr **>( 
-         &Data->getChildren()[getArraysOffset(getDirectiveKind())]); 
-     return llvm::MutableArrayRef(Storage, getLoopsNumber()); 
-   } 
-   
-   /// Get the private counters storage. 
-   MutableArrayRef<Expr *> getPrivateCounters() { 
-     auto **Storage = reinterpret_cast<Expr **>( 
-         &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 
-                              getLoopsNumber()]); 
-     return llvm::MutableArrayRef(Storage, getLoopsNumber()); 
-   } 
-   
-   /// Get the updates storage. 
-   MutableArrayRef<Expr *> getInits() { 
-     auto **Storage = reinterpret_cast<Expr **>( 
-         &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 
-                              2 * getLoopsNumber()]); 
-     return llvm::MutableArrayRef(Storage, getLoopsNumber()); 
-   } 
-   
-   /// Get the updates storage. 
-   MutableArrayRef<Expr *> getUpdates() { 
-     auto **Storage = reinterpret_cast<Expr **>( 
-         &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 
-                              3 * getLoopsNumber()]); 
-     return llvm::MutableArrayRef(Storage, getLoopsNumber()); 
-   } 
-   
-   /// Get the final counter updates storage. 
-   MutableArrayRef<Expr *> getFinals() { 
-     auto **Storage = reinterpret_cast<Expr **>( 
-         &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 
-                              4 * getLoopsNumber()]); 
-     return llvm::MutableArrayRef(Storage, getLoopsNumber()); 
-   } 
-   
-   /// Get the dependent counters storage. 
-   MutableArrayRef<Expr *> getDependentCounters() { 
-     auto **Storage = reinterpret_cast<Expr **>( 
-         &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 
-                              5 * getLoopsNumber()]); 
-     return llvm::MutableArrayRef(Storage, getLoopsNumber()); 
-   } 
-   
-   /// Get the dependent inits storage. 
-   MutableArrayRef<Expr *> getDependentInits() { 
-     auto **Storage = reinterpret_cast<Expr **>( 
-         &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 
-                              6 * getLoopsNumber()]); 
-     return llvm::MutableArrayRef(Storage, getLoopsNumber()); 
-   } 
-   
-   /// Get the finals conditions storage. 
-   MutableArrayRef<Expr *> getFinalsConditions() { 
-     auto **Storage = reinterpret_cast<Expr **>( 
-         &Data->getChildren()[getArraysOffset(getDirectiveKind()) + 
-                              7 * getLoopsNumber()]); 
-     return llvm::MutableArrayRef(Storage, getLoopsNumber()); 
-   } 
-   
- protected: 
-   /// Build instance of loop directive of class \a Kind. 
-   /// 
-   /// \param SC Statement class. 
-   /// \param Kind Kind of OpenMP directive. 
-   /// \param StartLoc Starting location of the directive (directive keyword). 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops from 'collapse' clause. 
-   /// 
-   OMPLoopDirective(StmtClass SC, OpenMPDirectiveKind Kind, 
-                    SourceLocation StartLoc, SourceLocation EndLoc, 
-                    unsigned CollapsedNum) 
-       : OMPLoopBasedDirective(SC, Kind, StartLoc, EndLoc, CollapsedNum) {} 
-   
-   /// Offset to the start of children expression arrays. 
-   static unsigned getArraysOffset(OpenMPDirectiveKind Kind) { 
-     if (isOpenMPLoopBoundSharingDirective(Kind)) 
-       return CombinedDistributeEnd; 
-     if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) || 
-         isOpenMPGenericLoopDirective(Kind) || isOpenMPDistributeDirective(Kind)) 
-       return WorksharingEnd; 
-     return DefaultEnd; 
-   } 
-   
-   /// Children number. 
-   static unsigned numLoopChildren(unsigned CollapsedNum, 
-                                   OpenMPDirectiveKind Kind) { 
-     return getArraysOffset(Kind) + 
-            8 * CollapsedNum; // Counters, PrivateCounters, Inits, 
-                              // Updates, Finals, DependentCounters, 
-                              // DependentInits, FinalsConditions. 
-   } 
-   
-   void setIterationVariable(Expr *IV) { 
-     Data->getChildren()[IterationVariableOffset] = IV; 
-   } 
-   void setLastIteration(Expr *LI) { 
-     Data->getChildren()[LastIterationOffset] = LI; 
-   } 
-   void setCalcLastIteration(Expr *CLI) { 
-     Data->getChildren()[CalcLastIterationOffset] = CLI; 
-   } 
-   void setPreCond(Expr *PC) { Data->getChildren()[PreConditionOffset] = PC; } 
-   void setCond(Expr *Cond) { Data->getChildren()[CondOffset] = Cond; } 
-   void setInit(Expr *Init) { Data->getChildren()[InitOffset] = Init; } 
-   void setInc(Expr *Inc) { Data->getChildren()[IncOffset] = Inc; } 
-   void setPreInits(Stmt *PreInits) { 
-     Data->getChildren()[PreInitsOffset] = PreInits; 
-   } 
-   void setIsLastIterVariable(Expr *IL) { 
-     assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 
-             isOpenMPGenericLoopDirective(getDirectiveKind()) || 
-             isOpenMPTaskLoopDirective(getDirectiveKind()) || 
-             isOpenMPDistributeDirective(getDirectiveKind())) && 
-            "expected worksharing loop directive"); 
-     Data->getChildren()[IsLastIterVariableOffset] = IL; 
-   } 
-   void setLowerBoundVariable(Expr *LB) { 
-     assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 
-             isOpenMPGenericLoopDirective(getDirectiveKind()) || 
-             isOpenMPTaskLoopDirective(getDirectiveKind()) || 
-             isOpenMPDistributeDirective(getDirectiveKind())) && 
-            "expected worksharing loop directive"); 
-     Data->getChildren()[LowerBoundVariableOffset] = LB; 
-   } 
-   void setUpperBoundVariable(Expr *UB) { 
-     assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 
-             isOpenMPGenericLoopDirective(getDirectiveKind()) || 
-             isOpenMPTaskLoopDirective(getDirectiveKind()) || 
-             isOpenMPDistributeDirective(getDirectiveKind())) && 
-            "expected worksharing loop directive"); 
-     Data->getChildren()[UpperBoundVariableOffset] = UB; 
-   } 
-   void setStrideVariable(Expr *ST) { 
-     assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 
-             isOpenMPGenericLoopDirective(getDirectiveKind()) || 
-             isOpenMPTaskLoopDirective(getDirectiveKind()) || 
-             isOpenMPDistributeDirective(getDirectiveKind())) && 
-            "expected worksharing loop directive"); 
-     Data->getChildren()[StrideVariableOffset] = ST; 
-   } 
-   void setEnsureUpperBound(Expr *EUB) { 
-     assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 
-             isOpenMPGenericLoopDirective(getDirectiveKind()) || 
-             isOpenMPTaskLoopDirective(getDirectiveKind()) || 
-             isOpenMPDistributeDirective(getDirectiveKind())) && 
-            "expected worksharing loop directive"); 
-     Data->getChildren()[EnsureUpperBoundOffset] = EUB; 
-   } 
-   void setNextLowerBound(Expr *NLB) { 
-     assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 
-             isOpenMPGenericLoopDirective(getDirectiveKind()) || 
-             isOpenMPTaskLoopDirective(getDirectiveKind()) || 
-             isOpenMPDistributeDirective(getDirectiveKind())) && 
-            "expected worksharing loop directive"); 
-     Data->getChildren()[NextLowerBoundOffset] = NLB; 
-   } 
-   void setNextUpperBound(Expr *NUB) { 
-     assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 
-             isOpenMPGenericLoopDirective(getDirectiveKind()) || 
-             isOpenMPTaskLoopDirective(getDirectiveKind()) || 
-             isOpenMPDistributeDirective(getDirectiveKind())) && 
-            "expected worksharing loop directive"); 
-     Data->getChildren()[NextUpperBoundOffset] = NUB; 
-   } 
-   void setNumIterations(Expr *NI) { 
-     assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 
-             isOpenMPGenericLoopDirective(getDirectiveKind()) || 
-             isOpenMPTaskLoopDirective(getDirectiveKind()) || 
-             isOpenMPDistributeDirective(getDirectiveKind())) && 
-            "expected worksharing loop directive"); 
-     Data->getChildren()[NumIterationsOffset] = NI; 
-   } 
-   void setPrevLowerBoundVariable(Expr *PrevLB) { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     Data->getChildren()[PrevLowerBoundVariableOffset] = PrevLB; 
-   } 
-   void setPrevUpperBoundVariable(Expr *PrevUB) { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     Data->getChildren()[PrevUpperBoundVariableOffset] = PrevUB; 
-   } 
-   void setDistInc(Expr *DistInc) { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     Data->getChildren()[DistIncOffset] = DistInc; 
-   } 
-   void setPrevEnsureUpperBound(Expr *PrevEUB) { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     Data->getChildren()[PrevEnsureUpperBoundOffset] = PrevEUB; 
-   } 
-   void setCombinedLowerBoundVariable(Expr *CombLB) { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     Data->getChildren()[CombinedLowerBoundVariableOffset] = CombLB; 
-   } 
-   void setCombinedUpperBoundVariable(Expr *CombUB) { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     Data->getChildren()[CombinedUpperBoundVariableOffset] = CombUB; 
-   } 
-   void setCombinedEnsureUpperBound(Expr *CombEUB) { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     Data->getChildren()[CombinedEnsureUpperBoundOffset] = CombEUB; 
-   } 
-   void setCombinedInit(Expr *CombInit) { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     Data->getChildren()[CombinedInitOffset] = CombInit; 
-   } 
-   void setCombinedCond(Expr *CombCond) { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     Data->getChildren()[CombinedConditionOffset] = CombCond; 
-   } 
-   void setCombinedNextLowerBound(Expr *CombNLB) { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     Data->getChildren()[CombinedNextLowerBoundOffset] = CombNLB; 
-   } 
-   void setCombinedNextUpperBound(Expr *CombNUB) { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     Data->getChildren()[CombinedNextUpperBoundOffset] = CombNUB; 
-   } 
-   void setCombinedDistCond(Expr *CombDistCond) { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound distribute sharing directive"); 
-     Data->getChildren()[CombinedDistConditionOffset] = CombDistCond; 
-   } 
-   void setCombinedParForInDistCond(Expr *CombParForInDistCond) { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound distribute sharing directive"); 
-     Data->getChildren()[CombinedParForInDistConditionOffset] = 
-         CombParForInDistCond; 
-   } 
-   void setCounters(ArrayRef<Expr *> A); 
-   void setPrivateCounters(ArrayRef<Expr *> A); 
-   void setInits(ArrayRef<Expr *> A); 
-   void setUpdates(ArrayRef<Expr *> A); 
-   void setFinals(ArrayRef<Expr *> A); 
-   void setDependentCounters(ArrayRef<Expr *> A); 
-   void setDependentInits(ArrayRef<Expr *> A); 
-   void setFinalsConditions(ArrayRef<Expr *> A); 
-   
- public: 
-   Expr *getIterationVariable() const { 
-     return cast<Expr>(Data->getChildren()[IterationVariableOffset]); 
-   } 
-   Expr *getLastIteration() const { 
-     return cast<Expr>(Data->getChildren()[LastIterationOffset]); 
-   } 
-   Expr *getCalcLastIteration() const { 
-     return cast<Expr>(Data->getChildren()[CalcLastIterationOffset]); 
-   } 
-   Expr *getPreCond() const { 
-     return cast<Expr>(Data->getChildren()[PreConditionOffset]); 
-   } 
-   Expr *getCond() const { return cast<Expr>(Data->getChildren()[CondOffset]); } 
-   Expr *getInit() const { return cast<Expr>(Data->getChildren()[InitOffset]); } 
-   Expr *getInc() const { return cast<Expr>(Data->getChildren()[IncOffset]); } 
-   const Stmt *getPreInits() const { 
-     return Data->getChildren()[PreInitsOffset]; 
-   } 
-   Stmt *getPreInits() { return Data->getChildren()[PreInitsOffset]; } 
-   Expr *getIsLastIterVariable() const { 
-     assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 
-             isOpenMPGenericLoopDirective(getDirectiveKind()) || 
-             isOpenMPTaskLoopDirective(getDirectiveKind()) || 
-             isOpenMPDistributeDirective(getDirectiveKind())) && 
-            "expected worksharing loop directive"); 
-     return cast<Expr>(Data->getChildren()[IsLastIterVariableOffset]); 
-   } 
-   Expr *getLowerBoundVariable() const { 
-     assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 
-             isOpenMPGenericLoopDirective(getDirectiveKind()) || 
-             isOpenMPTaskLoopDirective(getDirectiveKind()) || 
-             isOpenMPDistributeDirective(getDirectiveKind())) && 
-            "expected worksharing loop directive"); 
-     return cast<Expr>(Data->getChildren()[LowerBoundVariableOffset]); 
-   } 
-   Expr *getUpperBoundVariable() const { 
-     assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 
-             isOpenMPGenericLoopDirective(getDirectiveKind()) || 
-             isOpenMPTaskLoopDirective(getDirectiveKind()) || 
-             isOpenMPDistributeDirective(getDirectiveKind())) && 
-            "expected worksharing loop directive"); 
-     return cast<Expr>(Data->getChildren()[UpperBoundVariableOffset]); 
-   } 
-   Expr *getStrideVariable() const { 
-     assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 
-             isOpenMPGenericLoopDirective(getDirectiveKind()) || 
-             isOpenMPTaskLoopDirective(getDirectiveKind()) || 
-             isOpenMPDistributeDirective(getDirectiveKind())) && 
-            "expected worksharing loop directive"); 
-     return cast<Expr>(Data->getChildren()[StrideVariableOffset]); 
-   } 
-   Expr *getEnsureUpperBound() const { 
-     assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 
-             isOpenMPGenericLoopDirective(getDirectiveKind()) || 
-             isOpenMPTaskLoopDirective(getDirectiveKind()) || 
-             isOpenMPDistributeDirective(getDirectiveKind())) && 
-            "expected worksharing loop directive"); 
-     return cast<Expr>(Data->getChildren()[EnsureUpperBoundOffset]); 
-   } 
-   Expr *getNextLowerBound() const { 
-     assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 
-             isOpenMPGenericLoopDirective(getDirectiveKind()) || 
-             isOpenMPTaskLoopDirective(getDirectiveKind()) || 
-             isOpenMPDistributeDirective(getDirectiveKind())) && 
-            "expected worksharing loop directive"); 
-     return cast<Expr>(Data->getChildren()[NextLowerBoundOffset]); 
-   } 
-   Expr *getNextUpperBound() const { 
-     assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 
-             isOpenMPGenericLoopDirective(getDirectiveKind()) || 
-             isOpenMPTaskLoopDirective(getDirectiveKind()) || 
-             isOpenMPDistributeDirective(getDirectiveKind())) && 
-            "expected worksharing loop directive"); 
-     return cast<Expr>(Data->getChildren()[NextUpperBoundOffset]); 
-   } 
-   Expr *getNumIterations() const { 
-     assert((isOpenMPWorksharingDirective(getDirectiveKind()) || 
-             isOpenMPGenericLoopDirective(getDirectiveKind()) || 
-             isOpenMPTaskLoopDirective(getDirectiveKind()) || 
-             isOpenMPDistributeDirective(getDirectiveKind())) && 
-            "expected worksharing loop directive"); 
-     return cast<Expr>(Data->getChildren()[NumIterationsOffset]); 
-   } 
-   Expr *getPrevLowerBoundVariable() const { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     return cast<Expr>(Data->getChildren()[PrevLowerBoundVariableOffset]); 
-   } 
-   Expr *getPrevUpperBoundVariable() const { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     return cast<Expr>(Data->getChildren()[PrevUpperBoundVariableOffset]); 
-   } 
-   Expr *getDistInc() const { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     return cast<Expr>(Data->getChildren()[DistIncOffset]); 
-   } 
-   Expr *getPrevEnsureUpperBound() const { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     return cast<Expr>(Data->getChildren()[PrevEnsureUpperBoundOffset]); 
-   } 
-   Expr *getCombinedLowerBoundVariable() const { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     return cast<Expr>(Data->getChildren()[CombinedLowerBoundVariableOffset]); 
-   } 
-   Expr *getCombinedUpperBoundVariable() const { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     return cast<Expr>(Data->getChildren()[CombinedUpperBoundVariableOffset]); 
-   } 
-   Expr *getCombinedEnsureUpperBound() const { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     return cast<Expr>(Data->getChildren()[CombinedEnsureUpperBoundOffset]); 
-   } 
-   Expr *getCombinedInit() const { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     return cast<Expr>(Data->getChildren()[CombinedInitOffset]); 
-   } 
-   Expr *getCombinedCond() const { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     return cast<Expr>(Data->getChildren()[CombinedConditionOffset]); 
-   } 
-   Expr *getCombinedNextLowerBound() const { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     return cast<Expr>(Data->getChildren()[CombinedNextLowerBoundOffset]); 
-   } 
-   Expr *getCombinedNextUpperBound() const { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound sharing directive"); 
-     return cast<Expr>(Data->getChildren()[CombinedNextUpperBoundOffset]); 
-   } 
-   Expr *getCombinedDistCond() const { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound distribute sharing directive"); 
-     return cast<Expr>(Data->getChildren()[CombinedDistConditionOffset]); 
-   } 
-   Expr *getCombinedParForInDistCond() const { 
-     assert(isOpenMPLoopBoundSharingDirective(getDirectiveKind()) && 
-            "expected loop bound distribute sharing directive"); 
-     return cast<Expr>(Data->getChildren()[CombinedParForInDistConditionOffset]); 
-   } 
-   Stmt *getBody(); 
-   const Stmt *getBody() const { 
-     return const_cast<OMPLoopDirective *>(this)->getBody(); 
-   } 
-   
-   ArrayRef<Expr *> counters() { return getCounters(); } 
-   
-   ArrayRef<Expr *> counters() const { 
-     return const_cast<OMPLoopDirective *>(this)->getCounters(); 
-   } 
-   
-   ArrayRef<Expr *> private_counters() { return getPrivateCounters(); } 
-   
-   ArrayRef<Expr *> private_counters() const { 
-     return const_cast<OMPLoopDirective *>(this)->getPrivateCounters(); 
-   } 
-   
-   ArrayRef<Expr *> inits() { return getInits(); } 
-   
-   ArrayRef<Expr *> inits() const { 
-     return const_cast<OMPLoopDirective *>(this)->getInits(); 
-   } 
-   
-   ArrayRef<Expr *> updates() { return getUpdates(); } 
-   
-   ArrayRef<Expr *> updates() const { 
-     return const_cast<OMPLoopDirective *>(this)->getUpdates(); 
-   } 
-   
-   ArrayRef<Expr *> finals() { return getFinals(); } 
-   
-   ArrayRef<Expr *> finals() const { 
-     return const_cast<OMPLoopDirective *>(this)->getFinals(); 
-   } 
-   
-   ArrayRef<Expr *> dependent_counters() { return getDependentCounters(); } 
-   
-   ArrayRef<Expr *> dependent_counters() const { 
-     return const_cast<OMPLoopDirective *>(this)->getDependentCounters(); 
-   } 
-   
-   ArrayRef<Expr *> dependent_inits() { return getDependentInits(); } 
-   
-   ArrayRef<Expr *> dependent_inits() const { 
-     return const_cast<OMPLoopDirective *>(this)->getDependentInits(); 
-   } 
-   
-   ArrayRef<Expr *> finals_conditions() { return getFinalsConditions(); } 
-   
-   ArrayRef<Expr *> finals_conditions() const { 
-     return const_cast<OMPLoopDirective *>(this)->getFinalsConditions(); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPSimdDirectiveClass || 
-            T->getStmtClass() == OMPForDirectiveClass || 
-            T->getStmtClass() == OMPForSimdDirectiveClass || 
-            T->getStmtClass() == OMPParallelForDirectiveClass || 
-            T->getStmtClass() == OMPParallelForSimdDirectiveClass || 
-            T->getStmtClass() == OMPTaskLoopDirectiveClass || 
-            T->getStmtClass() == OMPTaskLoopSimdDirectiveClass || 
-            T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass || 
-            T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass || 
-            T->getStmtClass() == OMPMasterTaskLoopDirectiveClass || 
-            T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass || 
-            T->getStmtClass() == OMPGenericLoopDirectiveClass || 
-            T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass || 
-            T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass || 
-            T->getStmtClass() == OMPParallelGenericLoopDirectiveClass || 
-            T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass || 
-            T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass || 
-            T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass || 
-            T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass || 
-            T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass || 
-            T->getStmtClass() == OMPDistributeDirectiveClass || 
-            T->getStmtClass() == OMPTargetParallelForDirectiveClass || 
-            T->getStmtClass() == OMPDistributeParallelForDirectiveClass || 
-            T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass || 
-            T->getStmtClass() == OMPDistributeSimdDirectiveClass || 
-            T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass || 
-            T->getStmtClass() == OMPTargetSimdDirectiveClass || 
-            T->getStmtClass() == OMPTeamsDistributeDirectiveClass || 
-            T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass || 
-            T->getStmtClass() == 
-                OMPTeamsDistributeParallelForSimdDirectiveClass || 
-            T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass || 
-            T->getStmtClass() == 
-                OMPTargetTeamsDistributeParallelForDirectiveClass || 
-            T->getStmtClass() == 
-                OMPTargetTeamsDistributeParallelForSimdDirectiveClass || 
-            T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass || 
-            T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp simd' directive. 
- /// 
- /// \code 
- /// #pragma omp simd private(a,b) linear(i,j:s) reduction(+:c,d) 
- /// \endcode 
- /// In this example directive '#pragma omp simd' has clauses 'private' 
- /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and 
- /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. 
- /// 
- class OMPSimdDirective : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 
-                    unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, StartLoc, 
-                          EndLoc, CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPSimdDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPSimdDirectiveClass, llvm::omp::OMPD_simd, 
-                          SourceLocation(), SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPSimdDirective *Create(const ASTContext &C, SourceLocation StartLoc, 
-                                   SourceLocation EndLoc, unsigned CollapsedNum, 
-                                   ArrayRef<OMPClause *> Clauses, 
-                                   Stmt *AssociatedStmt, 
-                                   const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPSimdDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 
-                                        unsigned CollapsedNum, EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPSimdDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp for' directive. 
- /// 
- /// \code 
- /// #pragma omp for private(a,b) reduction(+:c,d) 
- /// \endcode 
- /// In this example directive '#pragma omp for' has clauses 'private' with the 
- /// variables 'a' and 'b' and 'reduction' with operator '+' and variables 'c' 
- /// and 'd'. 
- /// 
- class OMPForDirective : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// true if current directive has inner cancel directive. 
-   bool HasCancel = false; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 
-                   unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, StartLoc, 
-                          EndLoc, CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPForDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPForDirectiveClass, llvm::omp::OMPD_for, 
-                          SourceLocation(), SourceLocation(), CollapsedNum) {} 
-   
-   /// Sets special task reduction descriptor. 
-   void setTaskReductionRefExpr(Expr *E) { 
-     Data->getChildren()[numLoopChildren(getLoopsNumber(), 
-                                         llvm::omp::OMPD_for)] = E; 
-   } 
-   
-   /// Set cancel state. 
-   void setHasCancel(bool Has) { HasCancel = Has; } 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// \param TaskRedRef Task reduction special reference expression to handle 
-   /// taskgroup descriptor. 
-   /// \param HasCancel true if current directive has inner cancel directive. 
-   /// 
-   static OMPForDirective *Create(const ASTContext &C, SourceLocation StartLoc, 
-                                  SourceLocation EndLoc, unsigned CollapsedNum, 
-                                  ArrayRef<OMPClause *> Clauses, 
-                                  Stmt *AssociatedStmt, const HelperExprs &Exprs, 
-                                  Expr *TaskRedRef, bool HasCancel); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPForDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 
-                                       unsigned CollapsedNum, EmptyShell); 
-   
-   /// Returns special task reduction reference expression. 
-   Expr *getTaskReductionRefExpr() { 
-     return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 
-         getLoopsNumber(), llvm::omp::OMPD_for)]); 
-   } 
-   const Expr *getTaskReductionRefExpr() const { 
-     return const_cast<OMPForDirective *>(this)->getTaskReductionRefExpr(); 
-   } 
-   
-   /// Return true if current directive has inner cancel directive. 
-   bool hasCancel() const { return HasCancel; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPForDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp for simd' directive. 
- /// 
- /// \code 
- /// #pragma omp for simd private(a,b) linear(i,j:s) reduction(+:c,d) 
- /// \endcode 
- /// In this example directive '#pragma omp for simd' has clauses 'private' 
- /// with the variables 'a' and 'b', 'linear' with variables 'i', 'j' and 
- /// linear step 's', 'reduction' with operator '+' and variables 'c' and 'd'. 
- /// 
- class OMPForSimdDirective : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 
-                       unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd, 
-                          StartLoc, EndLoc, CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPForSimdDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPForSimdDirectiveClass, llvm::omp::OMPD_for_simd, 
-                          SourceLocation(), SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPForSimdDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPForSimdDirective *CreateEmpty(const ASTContext &C, 
-                                           unsigned NumClauses, 
-                                           unsigned CollapsedNum, EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPForSimdDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp sections' directive. 
- /// 
- /// \code 
- /// #pragma omp sections private(a,b) reduction(+:c,d) 
- /// \endcode 
- /// In this example directive '#pragma omp sections' has clauses 'private' with 
- /// the variables 'a' and 'b' and 'reduction' with operator '+' and variables 
- /// 'c' and 'd'. 
- /// 
- class OMPSectionsDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// true if current directive has inner cancel directive. 
-   bool HasCancel = false; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPSectionsDirectiveClass, 
-                                llvm::omp::OMPD_sections, StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPSectionsDirective() 
-       : OMPExecutableDirective(OMPSectionsDirectiveClass, 
-                                llvm::omp::OMPD_sections, SourceLocation(), 
-                                SourceLocation()) {} 
-   
-   /// Sets special task reduction descriptor. 
-   void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 
-   
-   /// Set cancel state. 
-   void setHasCancel(bool Has) { HasCancel = Has; } 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param TaskRedRef Task reduction special reference expression to handle 
-   /// taskgroup descriptor. 
-   /// \param HasCancel true if current directive has inner directive. 
-   /// 
-   static OMPSectionsDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 
-          bool HasCancel); 
-   
-   /// Creates an empty directive with the place for \a NumClauses 
-   /// clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPSectionsDirective *CreateEmpty(const ASTContext &C, 
-                                            unsigned NumClauses, EmptyShell); 
-   
-   /// Returns special task reduction reference expression. 
-   Expr *getTaskReductionRefExpr() { 
-     return cast_or_null<Expr>(Data->getChildren()[0]); 
-   } 
-   const Expr *getTaskReductionRefExpr() const { 
-     return const_cast<OMPSectionsDirective *>(this)->getTaskReductionRefExpr(); 
-   } 
-   
-   /// Return true if current directive has inner cancel directive. 
-   bool hasCancel() const { return HasCancel; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPSectionsDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp section' directive. 
- /// 
- /// \code 
- /// #pragma omp section 
- /// \endcode 
- /// 
- class OMPSectionDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// true if current directive has inner cancel directive. 
-   bool HasCancel = false; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPSectionDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPSectionDirectiveClass, 
-                                llvm::omp::OMPD_section, StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPSectionDirective() 
-       : OMPExecutableDirective(OMPSectionDirectiveClass, 
-                                llvm::omp::OMPD_section, SourceLocation(), 
-                                SourceLocation()) {} 
-   
- public: 
-   /// Creates directive. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param HasCancel true if current directive has inner directive. 
-   /// 
-   static OMPSectionDirective *Create(const ASTContext &C, 
-                                      SourceLocation StartLoc, 
-                                      SourceLocation EndLoc, 
-                                      Stmt *AssociatedStmt, bool HasCancel); 
-   
-   /// Creates an empty directive. 
-   /// 
-   /// \param C AST context. 
-   /// 
-   static OMPSectionDirective *CreateEmpty(const ASTContext &C, EmptyShell); 
-   
-   /// Set cancel state. 
-   void setHasCancel(bool Has) { HasCancel = Has; } 
-   
-   /// Return true if current directive has inner cancel directive. 
-   bool hasCancel() const { return HasCancel; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPSectionDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp single' directive. 
- /// 
- /// \code 
- /// #pragma omp single private(a,b) copyprivate(c,d) 
- /// \endcode 
- /// In this example directive '#pragma omp single' has clauses 'private' with 
- /// the variables 'a' and 'b' and 'copyprivate' with variables 'c' and 'd'. 
- /// 
- class OMPSingleDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPSingleDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single, 
-                                StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPSingleDirective() 
-       : OMPExecutableDirective(OMPSingleDirectiveClass, llvm::omp::OMPD_single, 
-                                SourceLocation(), SourceLocation()) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// 
-   static OMPSingleDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 
-   
-   /// Creates an empty directive with the place for \a NumClauses 
-   /// clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPSingleDirective *CreateEmpty(const ASTContext &C, 
-                                          unsigned NumClauses, EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPSingleDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp master' directive. 
- /// 
- /// \code 
- /// #pragma omp master 
- /// \endcode 
- /// 
- class OMPMasterDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master, 
-                                StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPMasterDirective() 
-       : OMPExecutableDirective(OMPMasterDirectiveClass, llvm::omp::OMPD_master, 
-                                SourceLocation(), SourceLocation()) {} 
-   
- public: 
-   /// Creates directive. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// 
-   static OMPMasterDirective *Create(const ASTContext &C, 
-                                     SourceLocation StartLoc, 
-                                     SourceLocation EndLoc, 
-                                     Stmt *AssociatedStmt); 
-   
-   /// Creates an empty directive. 
-   /// 
-   /// \param C AST context. 
-   /// 
-   static OMPMasterDirective *CreateEmpty(const ASTContext &C, EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPMasterDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp critical' directive. 
- /// 
- /// \code 
- /// #pragma omp critical 
- /// \endcode 
- /// 
- class OMPCriticalDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Name of the directive. 
-   DeclarationNameInfo DirName; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param Name Name of the directive. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPCriticalDirective(const DeclarationNameInfo &Name, SourceLocation StartLoc, 
-                        SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPCriticalDirectiveClass, 
-                                llvm::omp::OMPD_critical, StartLoc, EndLoc), 
-         DirName(Name) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPCriticalDirective() 
-       : OMPExecutableDirective(OMPCriticalDirectiveClass, 
-                                llvm::omp::OMPD_critical, SourceLocation(), 
-                                SourceLocation()) {} 
-   
-   /// Set name of the directive. 
-   /// 
-   /// \param Name Name of the directive. 
-   /// 
-   void setDirectiveName(const DeclarationNameInfo &Name) { DirName = Name; } 
-   
- public: 
-   /// Creates directive. 
-   /// 
-   /// \param C AST context. 
-   /// \param Name Name of the directive. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// 
-   static OMPCriticalDirective * 
-   Create(const ASTContext &C, const DeclarationNameInfo &Name, 
-          SourceLocation StartLoc, SourceLocation EndLoc, 
-          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 
-   
-   /// Creates an empty directive. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPCriticalDirective *CreateEmpty(const ASTContext &C, 
-                                            unsigned NumClauses, EmptyShell); 
-   
-   /// Return name of the directive. 
-   /// 
-   DeclarationNameInfo getDirectiveName() const { return DirName; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPCriticalDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp parallel for' directive. 
- /// 
- /// \code 
- /// #pragma omp parallel for private(a,b) reduction(+:c,d) 
- /// \endcode 
- /// In this example directive '#pragma omp parallel for' has clauses 'private' 
- /// with the variables 'a' and 'b' and 'reduction' with operator '+' and 
- /// variables 'c' and 'd'. 
- /// 
- class OMPParallelForDirective : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// true if current region has inner cancel directive. 
-   bool HasCancel = false; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 
-                           unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPParallelForDirectiveClass, 
-                          llvm::omp::OMPD_parallel_for, StartLoc, EndLoc, 
-                          CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPParallelForDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPParallelForDirectiveClass, 
-                          llvm::omp::OMPD_parallel_for, SourceLocation(), 
-                          SourceLocation(), CollapsedNum) {} 
-   
-   /// Sets special task reduction descriptor. 
-   void setTaskReductionRefExpr(Expr *E) { 
-     Data->getChildren()[numLoopChildren(getLoopsNumber(), 
-                                         llvm::omp::OMPD_parallel_for)] = E; 
-   } 
-   
-   /// Set cancel state. 
-   void setHasCancel(bool Has) { HasCancel = Has; } 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// \param TaskRedRef Task reduction special reference expression to handle 
-   /// taskgroup descriptor. 
-   /// \param HasCancel true if current directive has inner cancel directive. 
-   /// 
-   static OMPParallelForDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 
-          bool HasCancel); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPParallelForDirective *CreateEmpty(const ASTContext &C, 
-                                               unsigned NumClauses, 
-                                               unsigned CollapsedNum, 
-                                               EmptyShell); 
-   
-   /// Returns special task reduction reference expression. 
-   Expr *getTaskReductionRefExpr() { 
-     return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 
-         getLoopsNumber(), llvm::omp::OMPD_parallel_for)]); 
-   } 
-   const Expr *getTaskReductionRefExpr() const { 
-     return const_cast<OMPParallelForDirective *>(this) 
-         ->getTaskReductionRefExpr(); 
-   } 
-   
-   /// Return true if current directive has inner cancel directive. 
-   bool hasCancel() const { return HasCancel; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPParallelForDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp parallel for simd' directive. 
- /// 
- /// \code 
- /// #pragma omp parallel for simd private(a,b) linear(i,j:s) reduction(+:c,d) 
- /// \endcode 
- /// In this example directive '#pragma omp parallel for simd' has clauses 
- /// 'private' with the variables 'a' and 'b', 'linear' with variables 'i', 'j' 
- /// and linear step 's', 'reduction' with operator '+' and variables 'c' and 
- /// 'd'. 
- /// 
- class OMPParallelForSimdDirective : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPParallelForSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 
-                               unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPParallelForSimdDirectiveClass, 
-                          llvm::omp::OMPD_parallel_for_simd, StartLoc, EndLoc, 
-                          CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPParallelForSimdDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPParallelForSimdDirectiveClass, 
-                          llvm::omp::OMPD_parallel_for_simd, SourceLocation(), 
-                          SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPParallelForSimdDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPParallelForSimdDirective *CreateEmpty(const ASTContext &C, 
-                                                   unsigned NumClauses, 
-                                                   unsigned CollapsedNum, 
-                                                   EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPParallelForSimdDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp parallel master' directive. 
- /// 
- /// \code 
- /// #pragma omp parallel master private(a,b) 
- /// \endcode 
- /// In this example directive '#pragma omp parallel master' has clauses 
- /// 'private' with the variables 'a' and 'b' 
- /// 
- class OMPParallelMasterDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   OMPParallelMasterDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPParallelMasterDirectiveClass, 
-                                llvm::omp::OMPD_parallel_master, StartLoc, 
-                                EndLoc) {} 
-   
-   explicit OMPParallelMasterDirective() 
-       : OMPExecutableDirective(OMPParallelMasterDirectiveClass, 
-                                llvm::omp::OMPD_parallel_master, 
-                                SourceLocation(), SourceLocation()) {} 
-   
-   /// Sets special task reduction descriptor. 
-   void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param TaskRedRef Task reduction special reference expression to handle 
-   /// taskgroup descriptor. 
-   /// 
-   static OMPParallelMasterDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef); 
-   
-   /// Creates an empty directive with the place for \a NumClauses 
-   /// clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPParallelMasterDirective * 
-   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 
-   
-   /// Returns special task reduction reference expression. 
-   Expr *getTaskReductionRefExpr() { 
-     return cast_or_null<Expr>(Data->getChildren()[0]); 
-   } 
-   const Expr *getTaskReductionRefExpr() const { 
-     return const_cast<OMPParallelMasterDirective *>(this) 
-         ->getTaskReductionRefExpr(); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPParallelMasterDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp parallel masked' directive. 
- /// 
- /// \code 
- /// #pragma omp parallel masked filter(tid) 
- /// \endcode 
- /// In this example directive '#pragma omp parallel masked' has a clause 
- /// 'filter' with the variable tid 
- /// 
- class OMPParallelMaskedDirective final : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   OMPParallelMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPParallelMaskedDirectiveClass, 
-                                llvm::omp::OMPD_parallel_masked, StartLoc, 
-                                EndLoc) {} 
-   
-   explicit OMPParallelMaskedDirective() 
-       : OMPExecutableDirective(OMPParallelMaskedDirectiveClass, 
-                                llvm::omp::OMPD_parallel_masked, 
-                                SourceLocation(), SourceLocation()) {} 
-   
-   /// Sets special task reduction descriptor. 
-   void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param TaskRedRef Task reduction special reference expression to handle 
-   /// taskgroup descriptor. 
-   /// 
-   static OMPParallelMaskedDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef); 
-   
-   /// Creates an empty directive with the place for \a NumClauses 
-   /// clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPParallelMaskedDirective * 
-   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 
-   
-   /// Returns special task reduction reference expression. 
-   Expr *getTaskReductionRefExpr() { 
-     return cast_or_null<Expr>(Data->getChildren()[0]); 
-   } 
-   const Expr *getTaskReductionRefExpr() const { 
-     return const_cast<OMPParallelMaskedDirective *>(this) 
-         ->getTaskReductionRefExpr(); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPParallelMaskedDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp parallel sections' directive. 
- /// 
- /// \code 
- /// #pragma omp parallel sections private(a,b) reduction(+:c,d) 
- /// \endcode 
- /// In this example directive '#pragma omp parallel sections' has clauses 
- /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' 
- /// and variables 'c' and 'd'. 
- /// 
- class OMPParallelSectionsDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// true if current directive has inner cancel directive. 
-   bool HasCancel = false; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPParallelSectionsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPParallelSectionsDirectiveClass, 
-                                llvm::omp::OMPD_parallel_sections, StartLoc, 
-                                EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPParallelSectionsDirective() 
-       : OMPExecutableDirective(OMPParallelSectionsDirectiveClass, 
-                                llvm::omp::OMPD_parallel_sections, 
-                                SourceLocation(), SourceLocation()) {} 
-   
-   /// Sets special task reduction descriptor. 
-   void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 
-   
-   /// Set cancel state. 
-   void setHasCancel(bool Has) { HasCancel = Has; } 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param TaskRedRef Task reduction special reference expression to handle 
-   /// taskgroup descriptor. 
-   /// \param HasCancel true if current directive has inner cancel directive. 
-   /// 
-   static OMPParallelSectionsDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 
-          bool HasCancel); 
-   
-   /// Creates an empty directive with the place for \a NumClauses 
-   /// clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPParallelSectionsDirective * 
-   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 
-   
-   /// Returns special task reduction reference expression. 
-   Expr *getTaskReductionRefExpr() { 
-     return cast_or_null<Expr>(Data->getChildren()[0]); 
-   } 
-   const Expr *getTaskReductionRefExpr() const { 
-     return const_cast<OMPParallelSectionsDirective *>(this) 
-         ->getTaskReductionRefExpr(); 
-   } 
-   
-   /// Return true if current directive has inner cancel directive. 
-   bool hasCancel() const { return HasCancel; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPParallelSectionsDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp task' directive. 
- /// 
- /// \code 
- /// #pragma omp task private(a,b) final(d) 
- /// \endcode 
- /// In this example directive '#pragma omp task' has clauses 'private' with the 
- /// variables 'a' and 'b' and 'final' with condition 'd'. 
- /// 
- class OMPTaskDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// true if this directive has inner cancel directive. 
-   bool HasCancel = false; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPTaskDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task, 
-                                StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPTaskDirective() 
-       : OMPExecutableDirective(OMPTaskDirectiveClass, llvm::omp::OMPD_task, 
-                                SourceLocation(), SourceLocation()) {} 
-   
-   /// Set cancel state. 
-   void setHasCancel(bool Has) { HasCancel = Has; } 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param HasCancel true, if current directive has inner cancel directive. 
-   /// 
-   static OMPTaskDirective *Create(const ASTContext &C, SourceLocation StartLoc, 
-                                   SourceLocation EndLoc, 
-                                   ArrayRef<OMPClause *> Clauses, 
-                                   Stmt *AssociatedStmt, bool HasCancel); 
-   
-   /// Creates an empty directive with the place for \a NumClauses 
-   /// clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTaskDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 
-                                        EmptyShell); 
-   
-   /// Return true if current directive has inner cancel directive. 
-   bool hasCancel() const { return HasCancel; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTaskDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp taskyield' directive. 
- /// 
- /// \code 
- /// #pragma omp taskyield 
- /// \endcode 
- /// 
- class OMPTaskyieldDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPTaskyieldDirectiveClass, 
-                                llvm::omp::OMPD_taskyield, StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPTaskyieldDirective() 
-       : OMPExecutableDirective(OMPTaskyieldDirectiveClass, 
-                                llvm::omp::OMPD_taskyield, SourceLocation(), 
-                                SourceLocation()) {} 
-   
- public: 
-   /// Creates directive. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// 
-   static OMPTaskyieldDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); 
-   
-   /// Creates an empty directive. 
-   /// 
-   /// \param C AST context. 
-   /// 
-   static OMPTaskyieldDirective *CreateEmpty(const ASTContext &C, EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTaskyieldDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp barrier' directive. 
- /// 
- /// \code 
- /// #pragma omp barrier 
- /// \endcode 
- /// 
- class OMPBarrierDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPBarrierDirectiveClass, 
-                                llvm::omp::OMPD_barrier, StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPBarrierDirective() 
-       : OMPExecutableDirective(OMPBarrierDirectiveClass, 
-                                llvm::omp::OMPD_barrier, SourceLocation(), 
-                                SourceLocation()) {} 
-   
- public: 
-   /// Creates directive. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// 
-   static OMPBarrierDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc); 
-   
-   /// Creates an empty directive. 
-   /// 
-   /// \param C AST context. 
-   /// 
-   static OMPBarrierDirective *CreateEmpty(const ASTContext &C, EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPBarrierDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp taskwait' directive. 
- /// 
- /// \code 
- /// #pragma omp taskwait 
- /// \endcode 
- /// 
- class OMPTaskwaitDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPTaskwaitDirectiveClass, 
-                                llvm::omp::OMPD_taskwait, StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPTaskwaitDirective() 
-       : OMPExecutableDirective(OMPTaskwaitDirectiveClass, 
-                                llvm::omp::OMPD_taskwait, SourceLocation(), 
-                                SourceLocation()) {} 
-   
- public: 
-   /// Creates directive. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// 
-   static OMPTaskwaitDirective *Create(const ASTContext &C, 
-                                       SourceLocation StartLoc, 
-                                       SourceLocation EndLoc, 
-                                       ArrayRef<OMPClause *> Clauses); 
-   
-   /// Creates an empty directive. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTaskwaitDirective *CreateEmpty(const ASTContext &C, 
-                                            unsigned NumClauses, EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTaskwaitDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp taskgroup' directive. 
- /// 
- /// \code 
- /// #pragma omp taskgroup 
- /// \endcode 
- /// 
- class OMPTaskgroupDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPTaskgroupDirectiveClass, 
-                                llvm::omp::OMPD_taskgroup, StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPTaskgroupDirective() 
-       : OMPExecutableDirective(OMPTaskgroupDirectiveClass, 
-                                llvm::omp::OMPD_taskgroup, SourceLocation(), 
-                                SourceLocation()) {} 
-   
-   /// Sets the task_reduction return variable. 
-   void setReductionRef(Expr *RR) { Data->getChildren()[0] = RR; } 
-   
- public: 
-   /// Creates directive. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param ReductionRef Reference to the task_reduction return variable. 
-   /// 
-   static OMPTaskgroupDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, 
-          Expr *ReductionRef); 
-   
-   /// Creates an empty directive. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, 
-                                             unsigned NumClauses, EmptyShell); 
-   
-   
-   /// Returns reference to the task_reduction return variable. 
-   const Expr *getReductionRef() const { 
-     return const_cast<OMPTaskgroupDirective *>(this)->getReductionRef(); 
-   } 
-   Expr *getReductionRef() { return cast_or_null<Expr>(Data->getChildren()[0]); } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTaskgroupDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp flush' directive. 
- /// 
- /// \code 
- /// #pragma omp flush(a,b) 
- /// \endcode 
- /// In this example directive '#pragma omp flush' has 2 arguments- variables 'a' 
- /// and 'b'. 
- /// 'omp flush' directive does not have clauses but have an optional list of 
- /// variables to flush. This list of variables is stored within some fake clause 
- /// FlushClause. 
- class OMPFlushDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPFlushDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush, 
-                                StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPFlushDirective() 
-       : OMPExecutableDirective(OMPFlushDirectiveClass, llvm::omp::OMPD_flush, 
-                                SourceLocation(), SourceLocation()) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses (only single OMPFlushClause clause is 
-   /// allowed). 
-   /// 
-   static OMPFlushDirective *Create(const ASTContext &C, SourceLocation StartLoc, 
-                                    SourceLocation EndLoc, 
-                                    ArrayRef<OMPClause *> Clauses); 
-   
-   /// Creates an empty directive with the place for \a NumClauses 
-   /// clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPFlushDirective *CreateEmpty(const ASTContext &C, 
-                                         unsigned NumClauses, EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPFlushDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp depobj' directive. 
- /// 
- /// \code 
- /// #pragma omp depobj(a) depend(in:x,y) 
- /// \endcode 
- /// In this example directive '#pragma omp  depobj' initializes a depobj object 
- /// 'a' with dependence type 'in' and a list with 'x' and 'y' locators. 
- class OMPDepobjDirective final : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPDepobjDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj, 
-                                StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPDepobjDirective() 
-       : OMPExecutableDirective(OMPDepobjDirectiveClass, llvm::omp::OMPD_depobj, 
-                                SourceLocation(), SourceLocation()) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// 
-   static OMPDepobjDirective *Create(const ASTContext &C, 
-                                     SourceLocation StartLoc, 
-                                     SourceLocation EndLoc, 
-                                     ArrayRef<OMPClause *> Clauses); 
-   
-   /// Creates an empty directive with the place for \a NumClauses 
-   /// clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPDepobjDirective *CreateEmpty(const ASTContext &C, 
-                                          unsigned NumClauses, EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPDepobjDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp ordered' directive. 
- /// 
- /// \code 
- /// #pragma omp ordered 
- /// \endcode 
- /// 
- class OMPOrderedDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPOrderedDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPOrderedDirectiveClass, 
-                                llvm::omp::OMPD_ordered, StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPOrderedDirective() 
-       : OMPExecutableDirective(OMPOrderedDirectiveClass, 
-                                llvm::omp::OMPD_ordered, SourceLocation(), 
-                                SourceLocation()) {} 
-   
- public: 
-   /// Creates directive. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// 
-   static OMPOrderedDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 
-   
-   /// Creates an empty directive. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// \param IsStandalone true, if the standalone directive is created. 
-   /// 
-   static OMPOrderedDirective *CreateEmpty(const ASTContext &C, 
-                                           unsigned NumClauses, 
-                                           bool IsStandalone, EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPOrderedDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp atomic' directive. 
- /// 
- /// \code 
- /// #pragma omp atomic capture 
- /// \endcode 
- /// In this example directive '#pragma omp atomic' has clause 'capture'. 
- /// 
- class OMPAtomicDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   struct FlagTy { 
-     /// Used for 'atomic update' or 'atomic capture' constructs. They may 
-     /// have atomic expressions of forms: 
-     /// \code 
-     /// x = x binop expr; 
-     /// x = expr binop x; 
-     /// \endcode 
-     /// This field is 1 for the first form of the expression and 0 for the 
-     /// second. Required for correct codegen of non-associative operations (like 
-     /// << or >>). 
-     uint8_t IsXLHSInRHSPart : 1; 
-     /// Used for 'atomic update' or 'atomic capture' constructs. They may 
-     /// have atomic expressions of forms: 
-     /// \code 
-     /// v = x; <update x>; 
-     /// <update x>; v = x; 
-     /// \endcode 
-     /// This field is 1 for the first(postfix) form of the expression and 0 
-     /// otherwise. 
-     uint8_t IsPostfixUpdate : 1; 
-     /// 1 if 'v' is updated only when the condition is false (compare capture 
-     /// only). 
-     uint8_t IsFailOnly : 1; 
-   } Flags; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPAtomicDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic, 
-                                StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPAtomicDirective() 
-       : OMPExecutableDirective(OMPAtomicDirectiveClass, llvm::omp::OMPD_atomic, 
-                                SourceLocation(), SourceLocation()) {} 
-   
-   enum DataPositionTy : size_t { 
-     POS_X = 0, 
-     POS_V, 
-     POS_E, 
-     POS_UpdateExpr, 
-     POS_D, 
-     POS_Cond, 
-     POS_R, 
-   }; 
-   
-   /// Set 'x' part of the associated expression/statement. 
-   void setX(Expr *X) { Data->getChildren()[DataPositionTy::POS_X] = X; } 
-   /// Set helper expression of the form 
-   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 
-   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 
-   void setUpdateExpr(Expr *UE) { 
-     Data->getChildren()[DataPositionTy::POS_UpdateExpr] = UE; 
-   } 
-   /// Set 'v' part of the associated expression/statement. 
-   void setV(Expr *V) { Data->getChildren()[DataPositionTy::POS_V] = V; } 
-   /// Set 'r' part of the associated expression/statement. 
-   void setR(Expr *R) { Data->getChildren()[DataPositionTy::POS_R] = R; } 
-   /// Set 'expr' part of the associated expression/statement. 
-   void setExpr(Expr *E) { Data->getChildren()[DataPositionTy::POS_E] = E; } 
-   /// Set 'd' part of the associated expression/statement. 
-   void setD(Expr *D) { Data->getChildren()[DataPositionTy::POS_D] = D; } 
-   /// Set conditional expression in `atomic compare`. 
-   void setCond(Expr *C) { Data->getChildren()[DataPositionTy::POS_Cond] = C; } 
-   
- public: 
-   struct Expressions { 
-     /// 'x' part of the associated expression/statement. 
-     Expr *X = nullptr; 
-     /// 'v' part of the associated expression/statement. 
-     Expr *V = nullptr; 
-     // 'r' part of the associated expression/statement. 
-     Expr *R = nullptr; 
-     /// 'expr' part of the associated expression/statement. 
-     Expr *E = nullptr; 
-     /// UE Helper expression of the form: 
-     /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 
-     /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 
-     Expr *UE = nullptr; 
-     /// 'd' part of the associated expression/statement. 
-     Expr *D = nullptr; 
-     /// Conditional expression in `atomic compare` construct. 
-     Expr *Cond = nullptr; 
-     /// True if UE has the first form and false if the second. 
-     bool IsXLHSInRHSPart; 
-     /// True if original value of 'x' must be stored in 'v', not an updated one. 
-     bool IsPostfixUpdate; 
-     /// True if 'v' is updated only when the condition is false (compare capture 
-     /// only). 
-     bool IsFailOnly; 
-   }; 
-   
-   /// Creates directive with a list of \a Clauses and 'x', 'v' and 'expr' 
-   /// parts of the atomic construct (see Section 2.12.6, atomic Construct, for 
-   /// detailed description of 'x', 'v' and 'expr'). 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Associated expressions or statements. 
-   static OMPAtomicDirective *Create(const ASTContext &C, 
-                                     SourceLocation StartLoc, 
-                                     SourceLocation EndLoc, 
-                                     ArrayRef<OMPClause *> Clauses, 
-                                     Stmt *AssociatedStmt, Expressions Exprs); 
-   
-   /// Creates an empty directive with the place for \a NumClauses 
-   /// clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPAtomicDirective *CreateEmpty(const ASTContext &C, 
-                                          unsigned NumClauses, EmptyShell); 
-   
-   /// Get 'x' part of the associated expression/statement. 
-   Expr *getX() { 
-     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]); 
-   } 
-   const Expr *getX() const { 
-     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_X]); 
-   } 
-   /// Get helper expression of the form 
-   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 
-   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 
-   Expr *getUpdateExpr() { 
-     return cast_or_null<Expr>( 
-         Data->getChildren()[DataPositionTy::POS_UpdateExpr]); 
-   } 
-   const Expr *getUpdateExpr() const { 
-     return cast_or_null<Expr>( 
-         Data->getChildren()[DataPositionTy::POS_UpdateExpr]); 
-   } 
-   /// Return true if helper update expression has form 
-   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' and false if it has form 
-   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 
-   bool isXLHSInRHSPart() const { return Flags.IsXLHSInRHSPart; } 
-   /// Return true if 'v' expression must be updated to original value of 
-   /// 'x', false if 'v' must be updated to the new value of 'x'. 
-   bool isPostfixUpdate() const { return Flags.IsPostfixUpdate; } 
-   /// Return true if 'v' is updated only when the condition is evaluated false 
-   /// (compare capture only). 
-   bool isFailOnly() const { return Flags.IsFailOnly; } 
-   /// Get 'v' part of the associated expression/statement. 
-   Expr *getV() { 
-     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]); 
-   } 
-   const Expr *getV() const { 
-     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_V]); 
-   } 
-   /// Get 'r' part of the associated expression/statement. 
-   Expr *getR() { 
-     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]); 
-   } 
-   const Expr *getR() const { 
-     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_R]); 
-   } 
-   /// Get 'expr' part of the associated expression/statement. 
-   Expr *getExpr() { 
-     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]); 
-   } 
-   const Expr *getExpr() const { 
-     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_E]); 
-   } 
-   /// Get 'd' part of the associated expression/statement. 
-   Expr *getD() { 
-     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]); 
-   } 
-   Expr *getD() const { 
-     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_D]); 
-   } 
-   /// Get the 'cond' part of the source atomic expression. 
-   Expr *getCondExpr() { 
-     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]); 
-   } 
-   Expr *getCondExpr() const { 
-     return cast_or_null<Expr>(Data->getChildren()[DataPositionTy::POS_Cond]); 
-   } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPAtomicDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp target' directive. 
- /// 
- /// \code 
- /// #pragma omp target if(a) 
- /// \endcode 
- /// In this example directive '#pragma omp target' has clause 'if' with 
- /// condition 'a'. 
- /// 
- class OMPTargetDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPTargetDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target, 
-                                StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPTargetDirective() 
-       : OMPExecutableDirective(OMPTargetDirectiveClass, llvm::omp::OMPD_target, 
-                                SourceLocation(), SourceLocation()) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// 
-   static OMPTargetDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 
-   
-   /// Creates an empty directive with the place for \a NumClauses 
-   /// clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTargetDirective *CreateEmpty(const ASTContext &C, 
-                                          unsigned NumClauses, EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTargetDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp target data' directive. 
- /// 
- /// \code 
- /// #pragma omp target data device(0) if(a) map(b[:]) 
- /// \endcode 
- /// In this example directive '#pragma omp target data' has clauses 'device' 
- /// with the value '0', 'if' with condition 'a' and 'map' with array 
- /// section 'b[:]'. 
- /// 
- class OMPTargetDataDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// 
-   OMPTargetDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPTargetDataDirectiveClass, 
-                                llvm::omp::OMPD_target_data, StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPTargetDataDirective() 
-       : OMPExecutableDirective(OMPTargetDataDirectiveClass, 
-                                llvm::omp::OMPD_target_data, SourceLocation(), 
-                                SourceLocation()) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// 
-   static OMPTargetDataDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 
-   
-   /// Creates an empty directive with the place for \a N clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param N The number of clauses. 
-   /// 
-   static OMPTargetDataDirective *CreateEmpty(const ASTContext &C, unsigned N, 
-                                              EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTargetDataDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp target enter data' directive. 
- /// 
- /// \code 
- /// #pragma omp target enter data device(0) if(a) map(b[:]) 
- /// \endcode 
- /// In this example directive '#pragma omp target enter data' has clauses 
- /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array 
- /// section 'b[:]'. 
- /// 
- class OMPTargetEnterDataDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// 
-   OMPTargetEnterDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass, 
-                                llvm::omp::OMPD_target_enter_data, StartLoc, 
-                                EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPTargetEnterDataDirective() 
-       : OMPExecutableDirective(OMPTargetEnterDataDirectiveClass, 
-                                llvm::omp::OMPD_target_enter_data, 
-                                SourceLocation(), SourceLocation()) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// 
-   static OMPTargetEnterDataDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 
-   
-   /// Creates an empty directive with the place for \a N clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param N The number of clauses. 
-   /// 
-   static OMPTargetEnterDataDirective *CreateEmpty(const ASTContext &C, 
-                                                   unsigned N, EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTargetEnterDataDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp target exit data' directive. 
- /// 
- /// \code 
- /// #pragma omp target exit data device(0) if(a) map(b[:]) 
- /// \endcode 
- /// In this example directive '#pragma omp target exit data' has clauses 
- /// 'device' with the value '0', 'if' with condition 'a' and 'map' with array 
- /// section 'b[:]'. 
- /// 
- class OMPTargetExitDataDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// 
-   OMPTargetExitDataDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPTargetExitDataDirectiveClass, 
-                                llvm::omp::OMPD_target_exit_data, StartLoc, 
-                                EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPTargetExitDataDirective() 
-       : OMPExecutableDirective(OMPTargetExitDataDirectiveClass, 
-                                llvm::omp::OMPD_target_exit_data, 
-                                SourceLocation(), SourceLocation()) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// 
-   static OMPTargetExitDataDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 
-   
-   /// Creates an empty directive with the place for \a N clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param N The number of clauses. 
-   /// 
-   static OMPTargetExitDataDirective *CreateEmpty(const ASTContext &C, 
-                                                  unsigned N, EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTargetExitDataDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp target parallel' directive. 
- /// 
- /// \code 
- /// #pragma omp target parallel if(a) 
- /// \endcode 
- /// In this example directive '#pragma omp target parallel' has clause 'if' with 
- /// condition 'a'. 
- /// 
- class OMPTargetParallelDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// true if the construct has inner cancel directive. 
-   bool HasCancel = false; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPTargetParallelDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPTargetParallelDirectiveClass, 
-                                llvm::omp::OMPD_target_parallel, StartLoc, 
-                                EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPTargetParallelDirective() 
-       : OMPExecutableDirective(OMPTargetParallelDirectiveClass, 
-                                llvm::omp::OMPD_target_parallel, 
-                                SourceLocation(), SourceLocation()) {} 
-   
-   /// Sets special task reduction descriptor. 
-   void setTaskReductionRefExpr(Expr *E) { Data->getChildren()[0] = E; } 
-   /// Set cancel state. 
-   void setHasCancel(bool Has) { HasCancel = Has; } 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param TaskRedRef Task reduction special reference expression to handle 
-   /// taskgroup descriptor. 
-   /// \param HasCancel true if this directive has inner cancel directive. 
-   /// 
-   static OMPTargetParallelDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *TaskRedRef, 
-          bool HasCancel); 
-   
-   /// Creates an empty directive with the place for \a NumClauses 
-   /// clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTargetParallelDirective * 
-   CreateEmpty(const ASTContext &C, unsigned NumClauses, EmptyShell); 
-   
-   /// Returns special task reduction reference expression. 
-   Expr *getTaskReductionRefExpr() { 
-     return cast_or_null<Expr>(Data->getChildren()[0]); 
-   } 
-   const Expr *getTaskReductionRefExpr() const { 
-     return const_cast<OMPTargetParallelDirective *>(this) 
-         ->getTaskReductionRefExpr(); 
-   } 
-   
-   /// Return true if current directive has inner cancel directive. 
-   bool hasCancel() const { return HasCancel; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTargetParallelDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp target parallel for' directive. 
- /// 
- /// \code 
- /// #pragma omp target parallel for private(a,b) reduction(+:c,d) 
- /// \endcode 
- /// In this example directive '#pragma omp target parallel for' has clauses 
- /// 'private' with the variables 'a' and 'b' and 'reduction' with operator '+' 
- /// and variables 'c' and 'd'. 
- /// 
- class OMPTargetParallelForDirective : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// true if current region has inner cancel directive. 
-   bool HasCancel = false; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPTargetParallelForDirective(SourceLocation StartLoc, SourceLocation EndLoc, 
-                                 unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTargetParallelForDirectiveClass, 
-                          llvm::omp::OMPD_target_parallel_for, StartLoc, EndLoc, 
-                          CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPTargetParallelForDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTargetParallelForDirectiveClass, 
-                          llvm::omp::OMPD_target_parallel_for, SourceLocation(), 
-                          SourceLocation(), CollapsedNum) {} 
-   
-   /// Sets special task reduction descriptor. 
-   void setTaskReductionRefExpr(Expr *E) { 
-     Data->getChildren()[numLoopChildren( 
-         getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)] = E; 
-   } 
-   
-   /// Set cancel state. 
-   void setHasCancel(bool Has) { HasCancel = Has; } 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// \param TaskRedRef Task reduction special reference expression to handle 
-   /// taskgroup descriptor. 
-   /// \param HasCancel true if current directive has inner cancel directive. 
-   /// 
-   static OMPTargetParallelForDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 
-          bool HasCancel); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTargetParallelForDirective *CreateEmpty(const ASTContext &C, 
-                                                     unsigned NumClauses, 
-                                                     unsigned CollapsedNum, 
-                                                     EmptyShell); 
-   
-   /// Returns special task reduction reference expression. 
-   Expr *getTaskReductionRefExpr() { 
-     return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 
-         getLoopsNumber(), llvm::omp::OMPD_target_parallel_for)]); 
-   } 
-   const Expr *getTaskReductionRefExpr() const { 
-     return const_cast<OMPTargetParallelForDirective *>(this) 
-         ->getTaskReductionRefExpr(); 
-   } 
-   
-   /// Return true if current directive has inner cancel directive. 
-   bool hasCancel() const { return HasCancel; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTargetParallelForDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp teams' directive. 
- /// 
- /// \code 
- /// #pragma omp teams if(a) 
- /// \endcode 
- /// In this example directive '#pragma omp teams' has clause 'if' with 
- /// condition 'a'. 
- /// 
- class OMPTeamsDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams, 
-                                StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPTeamsDirective() 
-       : OMPExecutableDirective(OMPTeamsDirectiveClass, llvm::omp::OMPD_teams, 
-                                SourceLocation(), SourceLocation()) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// 
-   static OMPTeamsDirective *Create(const ASTContext &C, SourceLocation StartLoc, 
-                                    SourceLocation EndLoc, 
-                                    ArrayRef<OMPClause *> Clauses, 
-                                    Stmt *AssociatedStmt); 
-   
-   /// Creates an empty directive with the place for \a NumClauses 
-   /// clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTeamsDirective *CreateEmpty(const ASTContext &C, 
-                                         unsigned NumClauses, EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTeamsDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp cancellation point' directive. 
- /// 
- /// \code 
- /// #pragma omp cancellation point for 
- /// \endcode 
- /// 
- /// In this example a cancellation point is created for innermost 'for' region. 
- class OMPCancellationPointDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// statements and child expressions. 
-   /// 
-   OMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPCancellationPointDirectiveClass, 
-                                llvm::omp::OMPD_cancellation_point, StartLoc, 
-                                EndLoc) {} 
-   
-   /// Build an empty directive. 
-   explicit OMPCancellationPointDirective() 
-       : OMPExecutableDirective(OMPCancellationPointDirectiveClass, 
-                                llvm::omp::OMPD_cancellation_point, 
-                                SourceLocation(), SourceLocation()) {} 
-   
-   /// Set cancel region for current cancellation point. 
-   /// \param CR Cancellation region. 
-   void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } 
-   
- public: 
-   /// Creates directive. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// 
-   static OMPCancellationPointDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          OpenMPDirectiveKind CancelRegion); 
-   
-   /// Creates an empty directive. 
-   /// 
-   /// \param C AST context. 
-   /// 
-   static OMPCancellationPointDirective *CreateEmpty(const ASTContext &C, 
-                                                     EmptyShell); 
-   
-   /// Get cancellation region for the current cancellation point. 
-   OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPCancellationPointDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp cancel' directive. 
- /// 
- /// \code 
- /// #pragma omp cancel for 
- /// \endcode 
- /// 
- /// In this example a cancel is created for innermost 'for' region. 
- class OMPCancelDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   OpenMPDirectiveKind CancelRegion = llvm::omp::OMPD_unknown; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPCancelDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel, 
-                                StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPCancelDirective() 
-       : OMPExecutableDirective(OMPCancelDirectiveClass, llvm::omp::OMPD_cancel, 
-                                SourceLocation(), SourceLocation()) {} 
-   
-   /// Set cancel region for current cancellation point. 
-   /// \param CR Cancellation region. 
-   void setCancelRegion(OpenMPDirectiveKind CR) { CancelRegion = CR; } 
-   
- public: 
-   /// Creates directive. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// 
-   static OMPCancelDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          ArrayRef<OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion); 
-   
-   /// Creates an empty directive. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPCancelDirective *CreateEmpty(const ASTContext &C, 
-                                          unsigned NumClauses, EmptyShell); 
-   
-   /// Get cancellation region for the current cancellation point. 
-   OpenMPDirectiveKind getCancelRegion() const { return CancelRegion; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPCancelDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp taskloop' directive. 
- /// 
- /// \code 
- /// #pragma omp taskloop private(a,b) grainsize(val) num_tasks(num) 
- /// \endcode 
- /// In this example directive '#pragma omp taskloop' has clauses 'private' 
- /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and 
- /// 'num_tasks' with expression 'num'. 
- /// 
- class OMPTaskLoopDirective : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// true if the construct has inner cancel directive. 
-   bool HasCancel = false; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 
-                        unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, 
-                          StartLoc, EndLoc, CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPTaskLoopDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTaskLoopDirectiveClass, llvm::omp::OMPD_taskloop, 
-                          SourceLocation(), SourceLocation(), CollapsedNum) {} 
-   
-   /// Set cancel state. 
-   void setHasCancel(bool Has) { HasCancel = Has; } 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// \param HasCancel true if this directive has inner cancel directive. 
-   /// 
-   static OMPTaskLoopDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTaskLoopDirective *CreateEmpty(const ASTContext &C, 
-                                            unsigned NumClauses, 
-                                            unsigned CollapsedNum, EmptyShell); 
-   
-   /// Return true if current directive has inner cancel directive. 
-   bool hasCancel() const { return HasCancel; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTaskLoopDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp taskloop simd' directive. 
- /// 
- /// \code 
- /// #pragma omp taskloop simd private(a,b) grainsize(val) num_tasks(num) 
- /// \endcode 
- /// In this example directive '#pragma omp taskloop simd' has clauses 'private' 
- /// with the variables 'a' and 'b', 'grainsize' with expression 'val' and 
- /// 'num_tasks' with expression 'num'. 
- /// 
- class OMPTaskLoopSimdDirective : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 
-                            unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass, 
-                          llvm::omp::OMPD_taskloop_simd, StartLoc, EndLoc, 
-                          CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPTaskLoopSimdDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTaskLoopSimdDirectiveClass, 
-                          llvm::omp::OMPD_taskloop_simd, SourceLocation(), 
-                          SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPTaskLoopSimdDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 
-                                                unsigned NumClauses, 
-                                                unsigned CollapsedNum, 
-                                                EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTaskLoopSimdDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp master taskloop' directive. 
- /// 
- /// \code 
- /// #pragma omp master taskloop private(a,b) grainsize(val) num_tasks(num) 
- /// \endcode 
- /// In this example directive '#pragma omp master taskloop' has clauses 
- /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 
- /// and 'num_tasks' with expression 'num'. 
- /// 
- class OMPMasterTaskLoopDirective : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// true if the construct has inner cancel directive. 
-   bool HasCancel = false; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPMasterTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 
-                              unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass, 
-                          llvm::omp::OMPD_master_taskloop, StartLoc, EndLoc, 
-                          CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPMasterTaskLoopDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPMasterTaskLoopDirectiveClass, 
-                          llvm::omp::OMPD_master_taskloop, SourceLocation(), 
-                          SourceLocation(), CollapsedNum) {} 
-   
-   /// Set cancel state. 
-   void setHasCancel(bool Has) { HasCancel = Has; } 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// \param HasCancel true if this directive has inner cancel directive. 
-   /// 
-   static OMPMasterTaskLoopDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPMasterTaskLoopDirective *CreateEmpty(const ASTContext &C, 
-                                                  unsigned NumClauses, 
-                                                  unsigned CollapsedNum, 
-                                                  EmptyShell); 
-   
-   /// Return true if current directive has inner cancel directive. 
-   bool hasCancel() const { return HasCancel; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPMasterTaskLoopDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp masked taskloop' directive. 
- /// 
- /// \code 
- /// #pragma omp masked taskloop private(a,b) grainsize(val) num_tasks(num) 
- /// \endcode 
- /// In this example directive '#pragma omp masked taskloop' has clauses 
- /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 
- /// and 'num_tasks' with expression 'num'. 
- /// 
- class OMPMaskedTaskLoopDirective final : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// true if the construct has inner cancel directive. 
-   bool HasCancel = false; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPMaskedTaskLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 
-                              unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass, 
-                          llvm::omp::OMPD_masked_taskloop, StartLoc, EndLoc, 
-                          CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPMaskedTaskLoopDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPMaskedTaskLoopDirectiveClass, 
-                          llvm::omp::OMPD_masked_taskloop, SourceLocation(), 
-                          SourceLocation(), CollapsedNum) {} 
-   
-   /// Set cancel state. 
-   void setHasCancel(bool Has) { HasCancel = Has; } 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// \param HasCancel true if this directive has inner cancel directive. 
-   /// 
-   static OMPMaskedTaskLoopDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C, 
-                                                  unsigned NumClauses, 
-                                                  unsigned CollapsedNum, 
-                                                  EmptyShell); 
-   
-   /// Return true if current directive has inner cancel directive. 
-   bool hasCancel() const { return HasCancel; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPMaskedTaskLoopDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp master taskloop simd' directive. 
- /// 
- /// \code 
- /// #pragma omp master taskloop simd private(a,b) grainsize(val) num_tasks(num) 
- /// \endcode 
- /// In this example directive '#pragma omp master taskloop simd' has clauses 
- /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 
- /// and 'num_tasks' with expression 'num'. 
- /// 
- class OMPMasterTaskLoopSimdDirective : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPMasterTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 
-                                  unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass, 
-                          llvm::omp::OMPD_master_taskloop_simd, StartLoc, EndLoc, 
-                          CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPMasterTaskLoopSimdDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPMasterTaskLoopSimdDirectiveClass, 
-                          llvm::omp::OMPD_master_taskloop_simd, SourceLocation(), 
-                          SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \p Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPMasterTaskLoopSimdDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place for \p NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPMasterTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 
-                                                      unsigned NumClauses, 
-                                                      unsigned CollapsedNum, 
-                                                      EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPMasterTaskLoopSimdDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp masked taskloop simd' directive. 
- /// 
- /// \code 
- /// #pragma omp masked taskloop simd private(a,b) grainsize(val) num_tasks(num) 
- /// \endcode 
- /// In this example directive '#pragma omp masked taskloop simd' has clauses 
- /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 
- /// and 'num_tasks' with expression 'num'. 
- /// 
- class OMPMaskedTaskLoopSimdDirective final : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPMaskedTaskLoopSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 
-                                  unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass, 
-                          llvm::omp::OMPD_masked_taskloop_simd, StartLoc, EndLoc, 
-                          CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPMaskedTaskLoopSimdDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPMaskedTaskLoopSimdDirectiveClass, 
-                          llvm::omp::OMPD_masked_taskloop_simd, SourceLocation(), 
-                          SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \p Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPMaskedTaskLoopSimdDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place for \p NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPMaskedTaskLoopSimdDirective *CreateEmpty(const ASTContext &C, 
-                                                      unsigned NumClauses, 
-                                                      unsigned CollapsedNum, 
-                                                      EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPMaskedTaskLoopSimdDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp parallel master taskloop' directive. 
- /// 
- /// \code 
- /// #pragma omp parallel master taskloop private(a,b) grainsize(val) 
- /// num_tasks(num) 
- /// \endcode 
- /// In this example directive '#pragma omp parallel master taskloop' has clauses 
- /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 
- /// and 'num_tasks' with expression 'num'. 
- /// 
- class OMPParallelMasterTaskLoopDirective : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// true if the construct has inner cancel directive. 
-   bool HasCancel = false; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPParallelMasterTaskLoopDirective(SourceLocation StartLoc, 
-                                      SourceLocation EndLoc, 
-                                      unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass, 
-                          llvm::omp::OMPD_parallel_master_taskloop, StartLoc, 
-                          EndLoc, CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPParallelMasterTaskLoopDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPParallelMasterTaskLoopDirectiveClass, 
-                          llvm::omp::OMPD_parallel_master_taskloop, 
-                          SourceLocation(), SourceLocation(), CollapsedNum) {} 
-   
-   /// Set cancel state. 
-   void setHasCancel(bool Has) { HasCancel = Has; } 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// \param HasCancel true if this directive has inner cancel directive. 
-   /// 
-   static OMPParallelMasterTaskLoopDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPParallelMasterTaskLoopDirective *CreateEmpty(const ASTContext &C, 
-                                                          unsigned NumClauses, 
-                                                          unsigned CollapsedNum, 
-                                                          EmptyShell); 
-   
-   /// Return true if current directive has inner cancel directive. 
-   bool hasCancel() const { return HasCancel; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPParallelMasterTaskLoopDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp parallel masked taskloop' directive. 
- /// 
- /// \code 
- /// #pragma omp parallel masked taskloop private(a,b) grainsize(val) 
- /// num_tasks(num) 
- /// \endcode 
- /// In this example directive '#pragma omp parallel masked taskloop' has clauses 
- /// 'private' with the variables 'a' and 'b', 'grainsize' with expression 'val' 
- /// and 'num_tasks' with expression 'num'. 
- /// 
- class OMPParallelMaskedTaskLoopDirective final : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// true if the construct has inner cancel directive. 
-   bool HasCancel = false; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPParallelMaskedTaskLoopDirective(SourceLocation StartLoc, 
-                                      SourceLocation EndLoc, 
-                                      unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass, 
-                          llvm::omp::OMPD_parallel_masked_taskloop, StartLoc, 
-                          EndLoc, CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPParallelMaskedTaskLoopDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPParallelMaskedTaskLoopDirectiveClass, 
-                          llvm::omp::OMPD_parallel_masked_taskloop, 
-                          SourceLocation(), SourceLocation(), CollapsedNum) {} 
-   
-   /// Set cancel state. 
-   void setHasCancel(bool Has) { HasCancel = Has; } 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// \param HasCancel true if this directive has inner cancel directive. 
-   /// 
-   static OMPParallelMaskedTaskLoopDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPParallelMaskedTaskLoopDirective *CreateEmpty(const ASTContext &C, 
-                                                          unsigned NumClauses, 
-                                                          unsigned CollapsedNum, 
-                                                          EmptyShell); 
-   
-   /// Return true if current directive has inner cancel directive. 
-   bool hasCancel() const { return HasCancel; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPParallelMaskedTaskLoopDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp parallel master taskloop simd' directive. 
- /// 
- /// \code 
- /// #pragma omp parallel master taskloop simd private(a,b) grainsize(val) 
- /// num_tasks(num) 
- /// \endcode 
- /// In this example directive '#pragma omp parallel master taskloop simd' has 
- /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with 
- /// expression 'val' and 'num_tasks' with expression 'num'. 
- /// 
- class OMPParallelMasterTaskLoopSimdDirective : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPParallelMasterTaskLoopSimdDirective(SourceLocation StartLoc, 
-                                          SourceLocation EndLoc, 
-                                          unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass, 
-                          llvm::omp::OMPD_parallel_master_taskloop_simd, 
-                          StartLoc, EndLoc, CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPParallelMasterTaskLoopSimdDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPParallelMasterTaskLoopSimdDirectiveClass, 
-                          llvm::omp::OMPD_parallel_master_taskloop_simd, 
-                          SourceLocation(), SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \p Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPParallelMasterTaskLoopSimdDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPParallelMasterTaskLoopSimdDirective * 
-   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 
-               EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPParallelMasterTaskLoopSimdDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp parallel masked taskloop simd' directive. 
- /// 
- /// \code 
- /// #pragma omp parallel masked taskloop simd private(a,b) grainsize(val) 
- /// num_tasks(num) 
- /// \endcode 
- /// In this example directive '#pragma omp parallel masked taskloop simd' has 
- /// clauses 'private' with the variables 'a' and 'b', 'grainsize' with 
- /// expression 'val' and 'num_tasks' with expression 'num'. 
- /// 
- class OMPParallelMaskedTaskLoopSimdDirective final : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPParallelMaskedTaskLoopSimdDirective(SourceLocation StartLoc, 
-                                          SourceLocation EndLoc, 
-                                          unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass, 
-                          llvm::omp::OMPD_parallel_masked_taskloop_simd, 
-                          StartLoc, EndLoc, CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPParallelMaskedTaskLoopSimdDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPParallelMaskedTaskLoopSimdDirectiveClass, 
-                          llvm::omp::OMPD_parallel_masked_taskloop_simd, 
-                          SourceLocation(), SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \p Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPParallelMaskedTaskLoopSimdDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPParallelMaskedTaskLoopSimdDirective * 
-   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 
-               EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPParallelMaskedTaskLoopSimdDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp distribute' directive. 
- /// 
- /// \code 
- /// #pragma omp distribute private(a,b) 
- /// \endcode 
- /// In this example directive '#pragma omp distribute' has clauses 'private' 
- /// with the variables 'a' and 'b' 
- /// 
- class OMPDistributeDirective : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, 
-                          unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPDistributeDirectiveClass, 
-                          llvm::omp::OMPD_distribute, StartLoc, EndLoc, 
-                          CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPDistributeDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPDistributeDirectiveClass, 
-                          llvm::omp::OMPD_distribute, SourceLocation(), 
-                          SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPDistributeDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPDistributeDirective *CreateEmpty(const ASTContext &C, 
-                                              unsigned NumClauses, 
-                                              unsigned CollapsedNum, EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPDistributeDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp target update' directive. 
- /// 
- /// \code 
- /// #pragma omp target update to(a) from(b) device(1) 
- /// \endcode 
- /// In this example directive '#pragma omp target update' has clause 'to' with 
- /// argument 'a', clause 'from' with argument 'b' and clause 'device' with 
- /// argument '1'. 
- /// 
- class OMPTargetUpdateDirective : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// 
-   OMPTargetUpdateDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPTargetUpdateDirectiveClass, 
-                                llvm::omp::OMPD_target_update, StartLoc, 
-                                EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPTargetUpdateDirective() 
-       : OMPExecutableDirective(OMPTargetUpdateDirectiveClass, 
-                                llvm::omp::OMPD_target_update, SourceLocation(), 
-                                SourceLocation()) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// 
-   static OMPTargetUpdateDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 
-   
-   /// Creates an empty directive with the place for \a NumClauses 
-   /// clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses The number of clauses. 
-   /// 
-   static OMPTargetUpdateDirective *CreateEmpty(const ASTContext &C, 
-                                                unsigned NumClauses, EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTargetUpdateDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp distribute parallel for' composite 
- ///  directive. 
- /// 
- /// \code 
- /// #pragma omp distribute parallel for private(a,b) 
- /// \endcode 
- /// In this example directive '#pragma omp distribute parallel for' has clause 
- /// 'private' with the variables 'a' and 'b' 
- /// 
- class OMPDistributeParallelForDirective : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// true if the construct has inner cancel directive. 
-   bool HasCancel = false; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPDistributeParallelForDirective(SourceLocation StartLoc, 
-                                     SourceLocation EndLoc, 
-                                     unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPDistributeParallelForDirectiveClass, 
-                          llvm::omp::OMPD_distribute_parallel_for, StartLoc, 
-                          EndLoc, CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPDistributeParallelForDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPDistributeParallelForDirectiveClass, 
-                          llvm::omp::OMPD_distribute_parallel_for, 
-                          SourceLocation(), SourceLocation(), CollapsedNum) {} 
-   
-   /// Sets special task reduction descriptor. 
-   void setTaskReductionRefExpr(Expr *E) { 
-     Data->getChildren()[numLoopChildren( 
-         getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)] = E; 
-   } 
-   
-   /// Set cancel state. 
-   void setHasCancel(bool Has) { HasCancel = Has; } 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// \param TaskRedRef Task reduction special reference expression to handle 
-   /// taskgroup descriptor. 
-   /// \param HasCancel true if this directive has inner cancel directive. 
-   /// 
-   static OMPDistributeParallelForDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 
-          bool HasCancel); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPDistributeParallelForDirective *CreateEmpty(const ASTContext &C, 
-                                                         unsigned NumClauses, 
-                                                         unsigned CollapsedNum, 
-                                                         EmptyShell); 
-   
-   /// Returns special task reduction reference expression. 
-   Expr *getTaskReductionRefExpr() { 
-     return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 
-         getLoopsNumber(), llvm::omp::OMPD_distribute_parallel_for)]); 
-   } 
-   const Expr *getTaskReductionRefExpr() const { 
-     return const_cast<OMPDistributeParallelForDirective *>(this) 
-         ->getTaskReductionRefExpr(); 
-   } 
-   
-   /// Return true if current directive has inner cancel directive. 
-   bool hasCancel() const { return HasCancel; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPDistributeParallelForDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp distribute parallel for simd' composite 
- /// directive. 
- /// 
- /// \code 
- /// #pragma omp distribute parallel for simd private(x) 
- /// \endcode 
- /// In this example directive '#pragma omp distribute parallel for simd' has 
- /// clause 'private' with the variables 'x' 
- /// 
- class OMPDistributeParallelForSimdDirective final : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPDistributeParallelForSimdDirective(SourceLocation StartLoc, 
-                                         SourceLocation EndLoc, 
-                                         unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass, 
-                          llvm::omp::OMPD_distribute_parallel_for_simd, StartLoc, 
-                          EndLoc, CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPDistributeParallelForSimdDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPDistributeParallelForSimdDirectiveClass, 
-                          llvm::omp::OMPD_distribute_parallel_for_simd, 
-                          SourceLocation(), SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPDistributeParallelForSimdDirective *Create( 
-       const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-       unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-       Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPDistributeParallelForSimdDirective *CreateEmpty( 
-       const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 
-       EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPDistributeParallelForSimdDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp distribute simd' composite directive. 
- /// 
- /// \code 
- /// #pragma omp distribute simd private(x) 
- /// \endcode 
- /// In this example directive '#pragma omp distribute simd' has clause 
- /// 'private' with the variables 'x' 
- /// 
- class OMPDistributeSimdDirective final : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPDistributeSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 
-                              unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPDistributeSimdDirectiveClass, 
-                          llvm::omp::OMPD_distribute_simd, StartLoc, EndLoc, 
-                          CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPDistributeSimdDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPDistributeSimdDirectiveClass, 
-                          llvm::omp::OMPD_distribute_simd, SourceLocation(), 
-                          SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPDistributeSimdDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPDistributeSimdDirective *CreateEmpty(const ASTContext &C, 
-                                                  unsigned NumClauses, 
-                                                  unsigned CollapsedNum, 
-                                                  EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPDistributeSimdDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp target parallel for simd' directive. 
- /// 
- /// \code 
- /// #pragma omp target parallel for simd private(a) map(b) safelen(c) 
- /// \endcode 
- /// In this example directive '#pragma omp target parallel for simd' has clauses 
- /// 'private' with the variable 'a', 'map' with the variable 'b' and 'safelen' 
- /// with the variable 'c'. 
- /// 
- class OMPTargetParallelForSimdDirective final : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPTargetParallelForSimdDirective(SourceLocation StartLoc, 
-                                     SourceLocation EndLoc, 
-                                     unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass, 
-                          llvm::omp::OMPD_target_parallel_for_simd, StartLoc, 
-                          EndLoc, CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPTargetParallelForSimdDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTargetParallelForSimdDirectiveClass, 
-                          llvm::omp::OMPD_target_parallel_for_simd, 
-                          SourceLocation(), SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPTargetParallelForSimdDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTargetParallelForSimdDirective *CreateEmpty(const ASTContext &C, 
-                                                         unsigned NumClauses, 
-                                                         unsigned CollapsedNum, 
-                                                         EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTargetParallelForSimdDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp target simd' directive. 
- /// 
- /// \code 
- /// #pragma omp target simd private(a) map(b) safelen(c) 
- /// \endcode 
- /// In this example directive '#pragma omp target simd' has clauses 'private' 
- /// with the variable 'a', 'map' with the variable 'b' and 'safelen' with 
- /// the variable 'c'. 
- /// 
- class OMPTargetSimdDirective final : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPTargetSimdDirective(SourceLocation StartLoc, SourceLocation EndLoc, 
-                          unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTargetSimdDirectiveClass, 
-                          llvm::omp::OMPD_target_simd, StartLoc, EndLoc, 
-                          CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPTargetSimdDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTargetSimdDirectiveClass, 
-                          llvm::omp::OMPD_target_simd, SourceLocation(), 
-                          SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPTargetSimdDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTargetSimdDirective *CreateEmpty(const ASTContext &C, 
-                                              unsigned NumClauses, 
-                                              unsigned CollapsedNum, 
-                                              EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTargetSimdDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp teams distribute' directive. 
- /// 
- /// \code 
- /// #pragma omp teams distribute private(a,b) 
- /// \endcode 
- /// In this example directive '#pragma omp teams distribute' has clauses 
- /// 'private' with the variables 'a' and 'b' 
- /// 
- class OMPTeamsDistributeDirective final : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPTeamsDistributeDirective(SourceLocation StartLoc, SourceLocation EndLoc, 
-                               unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTeamsDistributeDirectiveClass, 
-                          llvm::omp::OMPD_teams_distribute, StartLoc, EndLoc, 
-                          CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPTeamsDistributeDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTeamsDistributeDirectiveClass, 
-                          llvm::omp::OMPD_teams_distribute, SourceLocation(), 
-                          SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPTeamsDistributeDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTeamsDistributeDirective *CreateEmpty(const ASTContext &C, 
-                                                   unsigned NumClauses, 
-                                                   unsigned CollapsedNum, 
-                                                   EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTeamsDistributeDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp teams distribute simd' 
- /// combined directive. 
- /// 
- /// \code 
- /// #pragma omp teams distribute simd private(a,b) 
- /// \endcode 
- /// In this example directive '#pragma omp teams distribute simd' 
- /// has clause 'private' with the variables 'a' and 'b' 
- /// 
- class OMPTeamsDistributeSimdDirective final : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPTeamsDistributeSimdDirective(SourceLocation StartLoc, 
-                                   SourceLocation EndLoc, unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass, 
-                          llvm::omp::OMPD_teams_distribute_simd, StartLoc, 
-                          EndLoc, CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPTeamsDistributeSimdDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTeamsDistributeSimdDirectiveClass, 
-                          llvm::omp::OMPD_teams_distribute_simd, 
-                          SourceLocation(), SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPTeamsDistributeSimdDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTeamsDistributeSimdDirective *CreateEmpty(const ASTContext &C, 
-                                                       unsigned NumClauses, 
-                                                       unsigned CollapsedNum, 
-                                                       EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTeamsDistributeSimdDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp teams distribute parallel for simd' composite 
- /// directive. 
- /// 
- /// \code 
- /// #pragma omp teams distribute parallel for simd private(x) 
- /// \endcode 
- /// In this example directive '#pragma omp teams distribute parallel for simd' 
- /// has clause 'private' with the variables 'x' 
- /// 
- class OMPTeamsDistributeParallelForSimdDirective final 
-     : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc, 
-                                              SourceLocation EndLoc, 
-                                              unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass, 
-                          llvm::omp::OMPD_teams_distribute_parallel_for_simd, 
-                          StartLoc, EndLoc, CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPTeamsDistributeParallelForSimdDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTeamsDistributeParallelForSimdDirectiveClass, 
-                          llvm::omp::OMPD_teams_distribute_parallel_for_simd, 
-                          SourceLocation(), SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPTeamsDistributeParallelForSimdDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTeamsDistributeParallelForSimdDirective * 
-   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 
-               EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTeamsDistributeParallelForSimdDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp teams distribute parallel for' composite 
- /// directive. 
- /// 
- /// \code 
- /// #pragma omp teams distribute parallel for private(x) 
- /// \endcode 
- /// In this example directive '#pragma omp teams distribute parallel for' 
- /// has clause 'private' with the variables 'x' 
- /// 
- class OMPTeamsDistributeParallelForDirective final : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// true if the construct has inner cancel directive. 
-   bool HasCancel = false; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPTeamsDistributeParallelForDirective(SourceLocation StartLoc, 
-                                          SourceLocation EndLoc, 
-                                          unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass, 
-                          llvm::omp::OMPD_teams_distribute_parallel_for, 
-                          StartLoc, EndLoc, CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPTeamsDistributeParallelForDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTeamsDistributeParallelForDirectiveClass, 
-                          llvm::omp::OMPD_teams_distribute_parallel_for, 
-                          SourceLocation(), SourceLocation(), CollapsedNum) {} 
-   
-   /// Sets special task reduction descriptor. 
-   void setTaskReductionRefExpr(Expr *E) { 
-     Data->getChildren()[numLoopChildren( 
-         getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)] = E; 
-   } 
-   
-   /// Set cancel state. 
-   void setHasCancel(bool Has) { HasCancel = Has; } 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// \param TaskRedRef Task reduction special reference expression to handle 
-   /// taskgroup descriptor. 
-   /// \param HasCancel true if this directive has inner cancel directive. 
-   /// 
-   static OMPTeamsDistributeParallelForDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 
-          bool HasCancel); 
-   
-   /// Creates an empty directive with the place for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTeamsDistributeParallelForDirective * 
-   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 
-               EmptyShell); 
-   
-   /// Returns special task reduction reference expression. 
-   Expr *getTaskReductionRefExpr() { 
-     return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 
-         getLoopsNumber(), llvm::omp::OMPD_teams_distribute_parallel_for)]); 
-   } 
-   const Expr *getTaskReductionRefExpr() const { 
-     return const_cast<OMPTeamsDistributeParallelForDirective *>(this) 
-         ->getTaskReductionRefExpr(); 
-   } 
-   
-   /// Return true if current directive has inner cancel directive. 
-   bool hasCancel() const { return HasCancel; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTeamsDistributeParallelForDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp target teams' directive. 
- /// 
- /// \code 
- /// #pragma omp target teams if(a>0) 
- /// \endcode 
- /// In this example directive '#pragma omp target teams' has clause 'if' with 
- /// condition 'a>0'. 
- /// 
- class OMPTargetTeamsDirective final : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPTargetTeamsDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPTargetTeamsDirectiveClass, 
-                                llvm::omp::OMPD_target_teams, StartLoc, EndLoc) { 
-   } 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPTargetTeamsDirective() 
-       : OMPExecutableDirective(OMPTargetTeamsDirectiveClass, 
-                                llvm::omp::OMPD_target_teams, SourceLocation(), 
-                                SourceLocation()) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// 
-   static OMPTargetTeamsDirective *Create(const ASTContext &C, 
-                                          SourceLocation StartLoc, 
-                                          SourceLocation EndLoc, 
-                                          ArrayRef<OMPClause *> Clauses, 
-                                          Stmt *AssociatedStmt); 
-   
-   /// Creates an empty directive with the place for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTargetTeamsDirective *CreateEmpty(const ASTContext &C, 
-                                               unsigned NumClauses, EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTargetTeamsDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp target teams distribute' combined directive. 
- /// 
- /// \code 
- /// #pragma omp target teams distribute private(x) 
- /// \endcode 
- /// In this example directive '#pragma omp target teams distribute' has clause 
- /// 'private' with the variables 'x' 
- /// 
- class OMPTargetTeamsDistributeDirective final : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPTargetTeamsDistributeDirective(SourceLocation StartLoc, 
-                                     SourceLocation EndLoc, 
-                                     unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass, 
-                          llvm::omp::OMPD_target_teams_distribute, StartLoc, 
-                          EndLoc, CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPTargetTeamsDistributeDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTargetTeamsDistributeDirectiveClass, 
-                          llvm::omp::OMPD_target_teams_distribute, 
-                          SourceLocation(), SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPTargetTeamsDistributeDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTargetTeamsDistributeDirective * 
-   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 
-               EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTargetTeamsDistributeDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp target teams distribute parallel for' combined 
- /// directive. 
- /// 
- /// \code 
- /// #pragma omp target teams distribute parallel for private(x) 
- /// \endcode 
- /// In this example directive '#pragma omp target teams distribute parallel 
- /// for' has clause 'private' with the variables 'x' 
- /// 
- class OMPTargetTeamsDistributeParallelForDirective final 
-     : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// true if the construct has inner cancel directive. 
-   bool HasCancel = false; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPTargetTeamsDistributeParallelForDirective(SourceLocation StartLoc, 
-                                                SourceLocation EndLoc, 
-                                                unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass, 
-                          llvm::omp::OMPD_target_teams_distribute_parallel_for, 
-                          StartLoc, EndLoc, CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPTargetTeamsDistributeParallelForDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTargetTeamsDistributeParallelForDirectiveClass, 
-                          llvm::omp::OMPD_target_teams_distribute_parallel_for, 
-                          SourceLocation(), SourceLocation(), CollapsedNum) {} 
-   
-   /// Sets special task reduction descriptor. 
-   void setTaskReductionRefExpr(Expr *E) { 
-     Data->getChildren()[numLoopChildren( 
-         getLoopsNumber(), 
-         llvm::omp::OMPD_target_teams_distribute_parallel_for)] = E; 
-   } 
-   
-   /// Set cancel state. 
-   void setHasCancel(bool Has) { HasCancel = Has; } 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// \param TaskRedRef Task reduction special reference expression to handle 
-   /// taskgroup descriptor. 
-   /// \param HasCancel true if this directive has inner cancel directive. 
-   /// 
-   static OMPTargetTeamsDistributeParallelForDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs, Expr *TaskRedRef, 
-          bool HasCancel); 
-   
-   /// Creates an empty directive with the place for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTargetTeamsDistributeParallelForDirective * 
-   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 
-               EmptyShell); 
-   
-   /// Returns special task reduction reference expression. 
-   Expr *getTaskReductionRefExpr() { 
-     return cast_or_null<Expr>(Data->getChildren()[numLoopChildren( 
-         getLoopsNumber(), 
-         llvm::omp::OMPD_target_teams_distribute_parallel_for)]); 
-   } 
-   const Expr *getTaskReductionRefExpr() const { 
-     return const_cast<OMPTargetTeamsDistributeParallelForDirective *>(this) 
-         ->getTaskReductionRefExpr(); 
-   } 
-   
-   /// Return true if current directive has inner cancel directive. 
-   bool hasCancel() const { return HasCancel; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == 
-            OMPTargetTeamsDistributeParallelForDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp target teams distribute parallel for simd' 
- /// combined directive. 
- /// 
- /// \code 
- /// #pragma omp target teams distribute parallel for simd private(x) 
- /// \endcode 
- /// In this example directive '#pragma omp target teams distribute parallel 
- /// for simd' has clause 'private' with the variables 'x' 
- /// 
- class OMPTargetTeamsDistributeParallelForSimdDirective final 
-     : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPTargetTeamsDistributeParallelForSimdDirective(SourceLocation StartLoc, 
-                                                    SourceLocation EndLoc, 
-                                                    unsigned CollapsedNum) 
-       : OMPLoopDirective( 
-             OMPTargetTeamsDistributeParallelForSimdDirectiveClass, 
-             llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, StartLoc, 
-             EndLoc, CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPTargetTeamsDistributeParallelForSimdDirective( 
-       unsigned CollapsedNum) 
-       : OMPLoopDirective( 
-             OMPTargetTeamsDistributeParallelForSimdDirectiveClass, 
-             llvm::omp::OMPD_target_teams_distribute_parallel_for_simd, 
-             SourceLocation(), SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPTargetTeamsDistributeParallelForSimdDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTargetTeamsDistributeParallelForSimdDirective * 
-   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 
-               EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == 
-            OMPTargetTeamsDistributeParallelForSimdDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp target teams distribute simd' combined 
- /// directive. 
- /// 
- /// \code 
- /// #pragma omp target teams distribute simd private(x) 
- /// \endcode 
- /// In this example directive '#pragma omp target teams distribute simd' 
- /// has clause 'private' with the variables 'x' 
- /// 
- class OMPTargetTeamsDistributeSimdDirective final : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPTargetTeamsDistributeSimdDirective(SourceLocation StartLoc, 
-                                         SourceLocation EndLoc, 
-                                         unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass, 
-                          llvm::omp::OMPD_target_teams_distribute_simd, StartLoc, 
-                          EndLoc, CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPTargetTeamsDistributeSimdDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTargetTeamsDistributeSimdDirectiveClass, 
-                          llvm::omp::OMPD_target_teams_distribute_simd, 
-                          SourceLocation(), SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPTargetTeamsDistributeSimdDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTargetTeamsDistributeSimdDirective * 
-   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 
-               EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTargetTeamsDistributeSimdDirectiveClass; 
-   } 
- }; 
-   
- /// This represents the '#pragma omp tile' loop transformation directive. 
- class OMPTileDirective final : public OMPLoopTransformationDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// Default list of offsets. 
-   enum { 
-     PreInitsOffset = 0, 
-     TransformedStmtOffset, 
-   }; 
-   
-   explicit OMPTileDirective(SourceLocation StartLoc, SourceLocation EndLoc, 
-                             unsigned NumLoops) 
-       : OMPLoopTransformationDirective(OMPTileDirectiveClass, 
-                                        llvm::omp::OMPD_tile, StartLoc, EndLoc, 
-                                        NumLoops) { 
-     setNumGeneratedLoops(3 * NumLoops); 
-   } 
-   
-   void setPreInits(Stmt *PreInits) { 
-     Data->getChildren()[PreInitsOffset] = PreInits; 
-   } 
-   
-   void setTransformedStmt(Stmt *S) { 
-     Data->getChildren()[TransformedStmtOffset] = S; 
-   } 
-   
- public: 
-   /// Create a new AST node representation for '#pragma omp tile'. 
-   /// 
-   /// \param C         Context of the AST. 
-   /// \param StartLoc  Location of the introducer (e.g. the 'omp' token). 
-   /// \param EndLoc    Location of the directive's end (e.g. the tok::eod). 
-   /// \param Clauses   The directive's clauses. 
-   /// \param NumLoops  Number of associated loops (number of items in the 
-   ///                  'sizes' clause). 
-   /// \param AssociatedStmt The outermost associated loop. 
-   /// \param TransformedStmt The loop nest after tiling, or nullptr in 
-   ///                        dependent contexts. 
-   /// \param PreInits Helper preinits statements for the loop nest. 
-   static OMPTileDirective *Create(const ASTContext &C, SourceLocation StartLoc, 
-                                   SourceLocation EndLoc, 
-                                   ArrayRef<OMPClause *> Clauses, 
-                                   unsigned NumLoops, Stmt *AssociatedStmt, 
-                                   Stmt *TransformedStmt, Stmt *PreInits); 
-   
-   /// Build an empty '#pragma omp tile' AST node for deserialization. 
-   /// 
-   /// \param C          Context of the AST. 
-   /// \param NumClauses Number of clauses to allocate. 
-   /// \param NumLoops   Number of associated loops to allocate. 
-   static OMPTileDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 
-                                        unsigned NumLoops); 
-   
-   /// Gets/sets the associated loops after tiling. 
-   /// 
-   /// This is in de-sugared format stored as a CompoundStmt. 
-   /// 
-   /// \code 
-   ///   for (...) 
-   ///     ... 
-   /// \endcode 
-   /// 
-   /// Note that if the generated loops a become associated loops of another 
-   /// directive, they may need to be hoisted before them. 
-   Stmt *getTransformedStmt() const { 
-     return Data->getChildren()[TransformedStmtOffset]; 
-   } 
-   
-   /// Return preinits statement. 
-   Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTileDirectiveClass; 
-   } 
- }; 
-   
- /// This represents the '#pragma omp unroll' loop transformation directive. 
- /// 
- /// \code 
- /// #pragma omp unroll 
- /// for (int i = 0; i < 64; ++i) 
- /// \endcode 
- class OMPUnrollDirective final : public OMPLoopTransformationDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// Default list of offsets. 
-   enum { 
-     PreInitsOffset = 0, 
-     TransformedStmtOffset, 
-   }; 
-   
-   explicit OMPUnrollDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPLoopTransformationDirective(OMPUnrollDirectiveClass, 
-                                        llvm::omp::OMPD_unroll, StartLoc, EndLoc, 
-                                        1) {} 
-   
-   /// Set the pre-init statements. 
-   void setPreInits(Stmt *PreInits) { 
-     Data->getChildren()[PreInitsOffset] = PreInits; 
-   } 
-   
-   /// Set the de-sugared statement. 
-   void setTransformedStmt(Stmt *S) { 
-     Data->getChildren()[TransformedStmtOffset] = S; 
-   } 
-   
- public: 
-   /// Create a new AST node representation for '#pragma omp unroll'. 
-   /// 
-   /// \param C         Context of the AST. 
-   /// \param StartLoc  Location of the introducer (e.g. the 'omp' token). 
-   /// \param EndLoc    Location of the directive's end (e.g. the tok::eod). 
-   /// \param Clauses   The directive's clauses. 
-   /// \param AssociatedStmt The outermost associated loop. 
-   /// \param TransformedStmt The loop nest after tiling, or nullptr in 
-   ///                        dependent contexts. 
-   /// \param PreInits   Helper preinits statements for the loop nest. 
-   static OMPUnrollDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, 
-          unsigned NumGeneratedLoops, Stmt *TransformedStmt, Stmt *PreInits); 
-   
-   /// Build an empty '#pragma omp unroll' AST node for deserialization. 
-   /// 
-   /// \param C          Context of the AST. 
-   /// \param NumClauses Number of clauses to allocate. 
-   static OMPUnrollDirective *CreateEmpty(const ASTContext &C, 
-                                          unsigned NumClauses); 
-   
-   /// Get the de-sugared associated loops after unrolling. 
-   /// 
-   /// This is only used if the unrolled loop becomes an associated loop of 
-   /// another directive, otherwise the loop is emitted directly using loop 
-   /// transformation metadata. When the unrolled loop cannot be used by another 
-   /// directive (e.g. because of the full clause), the transformed stmt can also 
-   /// be nullptr. 
-   Stmt *getTransformedStmt() const { 
-     return Data->getChildren()[TransformedStmtOffset]; 
-   } 
-   
-   /// Return the pre-init statements. 
-   Stmt *getPreInits() const { return Data->getChildren()[PreInitsOffset]; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPUnrollDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp scan' directive. 
- /// 
- /// \code 
- /// #pragma omp scan inclusive(a) 
- /// \endcode 
- /// In this example directive '#pragma omp scan' has clause 'inclusive' with 
- /// list item 'a'. 
- class OMPScanDirective final : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPScanDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan, 
-                                StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPScanDirective() 
-       : OMPExecutableDirective(OMPScanDirectiveClass, llvm::omp::OMPD_scan, 
-                                SourceLocation(), SourceLocation()) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses (only single OMPFlushClause clause is 
-   /// allowed). 
-   /// 
-   static OMPScanDirective *Create(const ASTContext &C, SourceLocation StartLoc, 
-                                   SourceLocation EndLoc, 
-                                   ArrayRef<OMPClause *> Clauses); 
-   
-   /// Creates an empty directive with the place for \a NumClauses 
-   /// clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPScanDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 
-                                        EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPScanDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp interop' directive. 
- /// 
- /// \code 
- /// #pragma omp interop init(target:obj) device(x) depend(inout:y) nowait 
- /// \endcode 
- /// In this example directive '#pragma omp interop' has 
- /// clauses 'init', 'device', 'depend' and 'nowait'. 
- /// 
- class OMPInteropDirective final : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPInteropDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPInteropDirectiveClass, 
-                                llvm::omp::OMPD_interop, StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPInteropDirective() 
-       : OMPExecutableDirective(OMPInteropDirectiveClass, 
-                                llvm::omp::OMPD_interop, SourceLocation(), 
-                                SourceLocation()) {} 
-   
- public: 
-   /// Creates directive. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses The directive's clauses. 
-   /// 
-   static OMPInteropDirective *Create(const ASTContext &C, 
-                                      SourceLocation StartLoc, 
-                                      SourceLocation EndLoc, 
-                                      ArrayRef<OMPClause *> Clauses); 
-   
-   /// Creates an empty directive. 
-   /// 
-   /// \param C AST context. 
-   /// 
-   static OMPInteropDirective *CreateEmpty(const ASTContext &C, 
-                                           unsigned NumClauses, EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPInteropDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp dispatch' directive. 
- /// 
- /// \code 
- /// #pragma omp dispatch device(dnum) 
- /// \endcode 
- /// This example shows a directive '#pragma omp dispatch' with a 
- /// device clause with variable 'dnum'. 
- /// 
- class OMPDispatchDirective final : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// The location of the target-call. 
-   SourceLocation TargetCallLoc; 
-   
-   /// Set the location of the target-call. 
-   void setTargetCallLoc(SourceLocation Loc) { TargetCallLoc = Loc; } 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPDispatchDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPDispatchDirectiveClass, 
-                                llvm::omp::OMPD_dispatch, StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPDispatchDirective() 
-       : OMPExecutableDirective(OMPDispatchDirectiveClass, 
-                                llvm::omp::OMPD_dispatch, SourceLocation(), 
-                                SourceLocation()) {} 
-   
- public: 
-   /// Creates directive with a list of \a Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param TargetCallLoc Location of the target-call. 
-   /// 
-   static OMPDispatchDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt, 
-          SourceLocation TargetCallLoc); 
-   
-   /// Creates an empty directive with the place for \a NumClauses 
-   /// clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPDispatchDirective *CreateEmpty(const ASTContext &C, 
-                                            unsigned NumClauses, EmptyShell); 
-   
-   /// Return location of target-call. 
-   SourceLocation getTargetCallLoc() const { return TargetCallLoc; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPDispatchDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp masked' directive. 
- /// \code 
- /// #pragma omp masked filter(tid) 
- /// \endcode 
- /// This example shows a directive '#pragma omp masked' with a filter clause 
- /// with variable 'tid'. 
- /// 
- class OMPMaskedDirective final : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPMaskedDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked, 
-                                StartLoc, EndLoc) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   explicit OMPMaskedDirective() 
-       : OMPExecutableDirective(OMPMaskedDirectiveClass, llvm::omp::OMPD_masked, 
-                                SourceLocation(), SourceLocation()) {} 
-   
- public: 
-   /// Creates directive. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// 
-   static OMPMaskedDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt); 
-   
-   /// Creates an empty directive. 
-   /// 
-   /// \param C AST context. 
-   /// 
-   static OMPMaskedDirective *CreateEmpty(const ASTContext &C, 
-                                          unsigned NumClauses, EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPMaskedDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp metadirective' directive. 
- /// 
- /// \code 
- /// #pragma omp metadirective when(user={condition(N>10)}: parallel for) 
- /// \endcode 
- /// In this example directive '#pragma omp metadirective' has clauses 'when' 
- /// with a dynamic user condition to check if a variable 'N > 10' 
- /// 
- class OMPMetaDirective final : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   Stmt *IfStmt; 
-   
-   OMPMetaDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPMetaDirectiveClass, 
-                                llvm::omp::OMPD_metadirective, StartLoc, 
-                                EndLoc) {} 
-   explicit OMPMetaDirective() 
-       : OMPExecutableDirective(OMPMetaDirectiveClass, 
-                                llvm::omp::OMPD_metadirective, SourceLocation(), 
-                                SourceLocation()) {} 
-   
-   void setIfStmt(Stmt *S) { IfStmt = S; } 
-   
- public: 
-   static OMPMetaDirective *Create(const ASTContext &C, SourceLocation StartLoc, 
-                                   SourceLocation EndLoc, 
-                                   ArrayRef<OMPClause *> Clauses, 
-                                   Stmt *AssociatedStmt, Stmt *IfStmt); 
-   static OMPMetaDirective *CreateEmpty(const ASTContext &C, unsigned NumClauses, 
-                                        EmptyShell); 
-   Stmt *getIfStmt() const { return IfStmt; } 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPMetaDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp loop' directive. 
- /// 
- /// \code 
- /// #pragma omp loop private(a,b) binding(parallel) order(concurrent) 
- /// \endcode 
- /// In this example directive '#pragma omp loop' has 
- /// clauses 'private' with the variables 'a' and 'b', 'binding' with 
- /// modifier 'parallel' and 'order(concurrent). 
- /// 
- class OMPGenericLoopDirective final : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 
-                           unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop, 
-                          StartLoc, EndLoc, CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPGenericLoopDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPGenericLoopDirectiveClass, llvm::omp::OMPD_loop, 
-                          SourceLocation(), SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \p Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPGenericLoopDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with a place for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param NumClauses Number of clauses. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   static OMPGenericLoopDirective *CreateEmpty(const ASTContext &C, 
-                                               unsigned NumClauses, 
-                                               unsigned CollapsedNum, 
-                                               EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPGenericLoopDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp teams loop' directive. 
- /// 
- /// \code 
- /// #pragma omp teams loop private(a,b) order(concurrent) 
- /// \endcode 
- /// In this example directive '#pragma omp teams loop' has 
- /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). 
- /// 
- class OMPTeamsGenericLoopDirective final : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPTeamsGenericLoopDirective(SourceLocation StartLoc, SourceLocation EndLoc, 
-                                unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass, 
-                          llvm::omp::OMPD_teams_loop, StartLoc, EndLoc, 
-                          CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPTeamsGenericLoopDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTeamsGenericLoopDirectiveClass, 
-                          llvm::omp::OMPD_teams_loop, SourceLocation(), 
-                          SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \p Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPTeamsGenericLoopDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C, 
-                                                    unsigned NumClauses, 
-                                                    unsigned CollapsedNum, 
-                                                    EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTeamsGenericLoopDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp target teams loop' directive. 
- /// 
- /// \code 
- /// #pragma omp target teams loop private(a,b) order(concurrent) 
- /// \endcode 
- /// In this example directive '#pragma omp target teams loop' has 
- /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). 
- /// 
- class OMPTargetTeamsGenericLoopDirective final : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPTargetTeamsGenericLoopDirective(SourceLocation StartLoc, 
-                                      SourceLocation EndLoc, 
-                                      unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass, 
-                          llvm::omp::OMPD_target_teams_loop, StartLoc, EndLoc, 
-                          CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPTargetTeamsGenericLoopDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTargetTeamsGenericLoopDirectiveClass, 
-                          llvm::omp::OMPD_target_teams_loop, SourceLocation(), 
-                          SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \p Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPTargetTeamsGenericLoopDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTargetTeamsGenericLoopDirective *CreateEmpty(const ASTContext &C, 
-                                                          unsigned NumClauses, 
-                                                          unsigned CollapsedNum, 
-                                                          EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTargetTeamsGenericLoopDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp parallel loop' directive. 
- /// 
- /// \code 
- /// #pragma omp parallel loop private(a,b) order(concurrent) 
- /// \endcode 
- /// In this example directive '#pragma omp parallel loop' has 
- /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). 
- /// 
- class OMPParallelGenericLoopDirective final : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPParallelGenericLoopDirective(SourceLocation StartLoc, 
-                                   SourceLocation EndLoc, unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass, 
-                          llvm::omp::OMPD_parallel_loop, StartLoc, EndLoc, 
-                          CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPParallelGenericLoopDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPParallelGenericLoopDirectiveClass, 
-                          llvm::omp::OMPD_parallel_loop, SourceLocation(), 
-                          SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \p Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPParallelGenericLoopDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPParallelGenericLoopDirective *CreateEmpty(const ASTContext &C, 
-                                                       unsigned NumClauses, 
-                                                       unsigned CollapsedNum, 
-                                                       EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPParallelGenericLoopDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp target parallel loop' directive. 
- /// 
- /// \code 
- /// #pragma omp target parallel loop private(a,b) order(concurrent) 
- /// \endcode 
- /// In this example directive '#pragma omp target parallel loop' has 
- /// clauses 'private' with the variables 'a' and 'b', and order(concurrent). 
- /// 
- class OMPTargetParallelGenericLoopDirective final : public OMPLoopDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   OMPTargetParallelGenericLoopDirective(SourceLocation StartLoc, 
-                                         SourceLocation EndLoc, 
-                                         unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass, 
-                          llvm::omp::OMPD_target_parallel_loop, StartLoc, EndLoc, 
-                          CollapsedNum) {} 
-   
-   /// Build an empty directive. 
-   /// 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// 
-   explicit OMPTargetParallelGenericLoopDirective(unsigned CollapsedNum) 
-       : OMPLoopDirective(OMPTargetParallelGenericLoopDirectiveClass, 
-                          llvm::omp::OMPD_target_parallel_loop, SourceLocation(), 
-                          SourceLocation(), CollapsedNum) {} 
-   
- public: 
-   /// Creates directive with a list of \p Clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param CollapsedNum Number of collapsed loops. 
-   /// \param Clauses List of clauses. 
-   /// \param AssociatedStmt Statement, associated with the directive. 
-   /// \param Exprs Helper expressions for CodeGen. 
-   /// 
-   static OMPTargetParallelGenericLoopDirective * 
-   Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, 
-          unsigned CollapsedNum, ArrayRef<OMPClause *> Clauses, 
-          Stmt *AssociatedStmt, const HelperExprs &Exprs); 
-   
-   /// Creates an empty directive with the place 
-   /// for \a NumClauses clauses. 
-   /// 
-   /// \param C AST context. 
-   /// \param CollapsedNum Number of collapsed nested loops. 
-   /// \param NumClauses Number of clauses. 
-   /// 
-   static OMPTargetParallelGenericLoopDirective * 
-   CreateEmpty(const ASTContext &C, unsigned NumClauses, unsigned CollapsedNum, 
-               EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPTargetParallelGenericLoopDirectiveClass; 
-   } 
- }; 
-   
- /// This represents '#pragma omp error' directive. 
- /// 
- /// \code 
- /// #pragma omp error 
- /// \endcode 
- class OMPErrorDirective final : public OMPExecutableDirective { 
-   friend class ASTStmtReader; 
-   friend class OMPExecutableDirective; 
-   /// Build directive with the given start and end location. 
-   /// 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending location of the directive. 
-   /// 
-   OMPErrorDirective(SourceLocation StartLoc, SourceLocation EndLoc) 
-       : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error, 
-                                StartLoc, EndLoc) {} 
-   /// Build an empty directive. 
-   /// 
-   explicit OMPErrorDirective() 
-       : OMPExecutableDirective(OMPErrorDirectiveClass, llvm::omp::OMPD_error, 
-                                SourceLocation(), SourceLocation()) {} 
-   
- public: 
-   /// 
-   /// \param C AST context. 
-   /// \param StartLoc Starting location of the directive kind. 
-   /// \param EndLoc Ending Location of the directive. 
-   /// \param Clauses List of clauses. 
-   /// 
-   static OMPErrorDirective *Create(const ASTContext &C, SourceLocation StartLoc, 
-                                    SourceLocation EndLoc, 
-                                    ArrayRef<OMPClause *> Clauses); 
-   
-   /// Creates an empty directive. 
-   /// 
-   /// \param C AST context. 
-   /// 
-   static OMPErrorDirective *CreateEmpty(const ASTContext &C, 
-                                         unsigned NumClauses, EmptyShell); 
-   
-   static bool classof(const Stmt *T) { 
-     return T->getStmtClass() == OMPErrorDirectiveClass; 
-   } 
- }; 
- } // end namespace clang 
-   
- #endif 
-