//===- OpenMPClause.h - Classes for OpenMP clauses --------------*- 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 clauses.
/// There are clauses for executable directives, clauses for declarative
/// directives and clauses which can be used in both kinds of directives.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_OPENMPCLAUSE_H
#define LLVM_CLANG_AST_OPENMPCLAUSE_H

#include "clang/AST/ASTFwd.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/Expr.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/StmtIterator.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/iterator.h"
#include "llvm/ADT/iterator_range.h"
#include "llvm/Frontend/OpenMP/OMPAssume.h"
#include "llvm/Frontend/OpenMP/OMPConstants.h"
#include "llvm/Frontend/OpenMP/OMPContext.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/TrailingObjects.h"
#include <cassert>
#include <cstddef>
#include <iterator>
#include <utility>

namespace clang {

class ASTContext;

//===----------------------------------------------------------------------===//
// AST classes for clauses.
//===----------------------------------------------------------------------===//

/// This is a basic class for representing single OpenMP clause.
class OMPClause {
  /// Starting location of the clause (the clause keyword).
  SourceLocation StartLoc;

  /// Ending location of the clause.
  SourceLocation EndLoc;

  /// Kind of the clause.
  OpenMPClauseKind Kind;

protected:
  OMPClause(OpenMPClauseKind K, SourceLocation StartLoc, SourceLocation EndLoc)
      : StartLoc(StartLoc), EndLoc(EndLoc), Kind(K) {}

public:
  /// Returns the starting location of the clause.
  SourceLocation getBeginLoc() const { return StartLoc; }

  /// Returns the ending location of the clause.
  SourceLocation getEndLoc() const { return EndLoc; }

  /// Sets the starting location of the clause.
  void setLocStart(SourceLocation Loc) { StartLoc = Loc; }

  /// Sets the ending location of the clause.
  void setLocEnd(SourceLocation Loc) { EndLoc = Loc; }

  /// Returns kind of OpenMP clause (private, shared, reduction, etc.).
  OpenMPClauseKind getClauseKind() const { return Kind; }

  bool isImplicit() const { return StartLoc.isInvalid(); }

  using child_iterator = StmtIterator;
  using const_child_iterator = ConstStmtIterator;
  using child_range = llvm::iterator_range<child_iterator>;
  using const_child_range = llvm::iterator_range<const_child_iterator>;

  child_range children();
  const_child_range children() const {
    auto Children = const_cast<OMPClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  /// Get the iterator range for the expressions used in the clauses. Used
  /// expressions include only the children that must be evaluated at the
  /// runtime before entering the construct.
  child_range used_children();
  const_child_range used_children() const {
    auto Children = const_cast<OMPClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  static bool classof(const OMPClause *) { return true; }
};

/// Class that handles pre-initialization statement for some clauses, like
/// 'shedule', 'firstprivate' etc.
class OMPClauseWithPreInit {
  friend class OMPClauseReader;

  /// Pre-initialization statement for the clause.
  Stmt *PreInit = nullptr;

  /// Region that captures the associated stmt.
  OpenMPDirectiveKind CaptureRegion = llvm::omp::OMPD_unknown;

protected:
  OMPClauseWithPreInit(const OMPClause *This) {
    assert(get(This) && "get is not tuned for pre-init.");
  }

  /// Set pre-initialization statement for the clause.
  void
  setPreInitStmt(Stmt *S,
                 OpenMPDirectiveKind ThisRegion = llvm::omp::OMPD_unknown) {
    PreInit = S;
    CaptureRegion = ThisRegion;
  }

public:
  /// Get pre-initialization statement for the clause.
  const Stmt *getPreInitStmt() const { return PreInit; }

  /// Get pre-initialization statement for the clause.
  Stmt *getPreInitStmt() { return PreInit; }

  /// Get capture region for the stmt in the clause.
  OpenMPDirectiveKind getCaptureRegion() const { return CaptureRegion; }

  static OMPClauseWithPreInit *get(OMPClause *C);
  static const OMPClauseWithPreInit *get(const OMPClause *C);
};

/// Class that handles post-update expression for some clauses, like
/// 'lastprivate', 'reduction' etc.
class OMPClauseWithPostUpdate : public OMPClauseWithPreInit {
  friend class OMPClauseReader;

  /// Post-update expression for the clause.
  Expr *PostUpdate = nullptr;

protected:
  OMPClauseWithPostUpdate(const OMPClause *This) : OMPClauseWithPreInit(This) {
    assert(get(This) && "get is not tuned for post-update.");
  }

  /// Set pre-initialization statement for the clause.
  void setPostUpdateExpr(Expr *S) { PostUpdate = S; }

public:
  /// Get post-update expression for the clause.
  const Expr *getPostUpdateExpr() const { return PostUpdate; }

  /// Get post-update expression for the clause.
  Expr *getPostUpdateExpr() { return PostUpdate; }

  static OMPClauseWithPostUpdate *get(OMPClause *C);
  static const OMPClauseWithPostUpdate *get(const OMPClause *C);
};

/// This structure contains most locations needed for by an OMPVarListClause.
struct OMPVarListLocTy {
  /// Starting location of the clause (the clause keyword).
  SourceLocation StartLoc;
  /// Location of '('.
  SourceLocation LParenLoc;
  /// Ending location of the clause.
  SourceLocation EndLoc;
  OMPVarListLocTy() = default;
  OMPVarListLocTy(SourceLocation StartLoc, SourceLocation LParenLoc,
                  SourceLocation EndLoc)
      : StartLoc(StartLoc), LParenLoc(LParenLoc), EndLoc(EndLoc) {}
};

/// This represents clauses with the list of variables like 'private',
/// 'firstprivate', 'copyin', 'shared', or 'reduction' clauses in the
/// '#pragma omp ...' directives.
template <class T> class OMPVarListClause : public OMPClause {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Number of variables in the list.
  unsigned NumVars;

protected:
  /// Build a clause with \a N variables
  ///
  /// \param K Kind of the clause.
  /// \param StartLoc Starting location of the clause (the clause keyword).
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param N Number of the variables in the clause.
  OMPVarListClause(OpenMPClauseKind K, SourceLocation StartLoc,
                   SourceLocation LParenLoc, SourceLocation EndLoc, unsigned N)
      : OMPClause(K, StartLoc, EndLoc), LParenLoc(LParenLoc), NumVars(N) {}

  /// Fetches list of variables associated with this clause.
  MutableArrayRef<Expr *> getVarRefs() {
    return MutableArrayRef<Expr *>(
        static_cast<T *>(this)->template getTrailingObjects<Expr *>(), NumVars);
  }

  /// Sets the list of variables for this clause.
  void setVarRefs(ArrayRef<Expr *> VL) {
    assert(VL.size() == NumVars &&
           "Number of variables is not the same as the preallocated buffer");
    std::copy(VL.begin(), VL.end(),
              static_cast<T *>(this)->template getTrailingObjects<Expr *>());
  }

public:
  using varlist_iterator = MutableArrayRef<Expr *>::iterator;
  using varlist_const_iterator = ArrayRef<const Expr *>::iterator;
  using varlist_range = llvm::iterator_range<varlist_iterator>;
  using varlist_const_range = llvm::iterator_range<varlist_const_iterator>;

  unsigned varlist_size() const { return NumVars; }
  bool varlist_empty() const { return NumVars == 0; }

  varlist_range varlists() {
    return varlist_range(varlist_begin(), varlist_end());
  }
  varlist_const_range varlists() const {
    return varlist_const_range(varlist_begin(), varlist_end());
  }

  varlist_iterator varlist_begin() { return getVarRefs().begin(); }
  varlist_iterator varlist_end() { return getVarRefs().end(); }
  varlist_const_iterator varlist_begin() const { return getVarRefs().begin(); }
  varlist_const_iterator varlist_end() const { return getVarRefs().end(); }

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Fetches list of all variables in the clause.
  ArrayRef<const Expr *> getVarRefs() const {
    return llvm::makeArrayRef(
        static_cast<const T *>(this)->template getTrailingObjects<Expr *>(),
        NumVars);
  }
};

/// This represents 'allocator' clause in the '#pragma omp ...'
/// directive.
///
/// \code
/// #pragma omp allocate(a) allocator(omp_default_mem_alloc)
/// \endcode
/// In this example directive '#pragma omp allocate' has simple 'allocator'
/// clause with the allocator 'omp_default_mem_alloc'.
class OMPAllocatorClause : public OMPClause {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Expression with the allocator.
  Stmt *Allocator = nullptr;

  /// Set allocator.
  void setAllocator(Expr *A) { Allocator = A; }

public:
  /// Build 'allocator' clause with the given allocator.
  ///
  /// \param A Allocator.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPAllocatorClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc,
                     SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_allocator, StartLoc, EndLoc),
        LParenLoc(LParenLoc), Allocator(A) {}

  /// Build an empty clause.
  OMPAllocatorClause()
      : OMPClause(llvm::omp::OMPC_allocator, SourceLocation(),
                  SourceLocation()) {}

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Returns allocator.
  Expr *getAllocator() const { return cast_or_null<Expr>(Allocator); }

  child_range children() { return child_range(&Allocator, &Allocator + 1); }

  const_child_range children() const {
    return const_child_range(&Allocator, &Allocator + 1);
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_allocator;
  }
};

/// This represents the 'align' clause in the '#pragma omp allocate'
/// directive.
///
/// \code
/// #pragma omp allocate(a) allocator(omp_default_mem_alloc) align(8)
/// \endcode
/// In this example directive '#pragma omp allocate' has simple 'allocator'
/// clause with the allocator 'omp_default_mem_alloc' and align clause with
/// value of 8.
class OMPAlignClause final : public OMPClause {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Alignment specified with align clause.
  Stmt *Alignment = nullptr;

  /// Set alignment value.
  void setAlignment(Expr *A) { Alignment = A; }

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Build 'align' clause with the given alignment
  ///
  /// \param A Alignment value.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPAlignClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc,
                 SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_align, StartLoc, EndLoc),
        LParenLoc(LParenLoc), Alignment(A) {}

  /// Build an empty clause.
  OMPAlignClause()
      : OMPClause(llvm::omp::OMPC_align, SourceLocation(), SourceLocation()) {}

public:
  /// Build 'align' clause with the given alignment
  ///
  /// \param A Alignment value.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  static OMPAlignClause *Create(const ASTContext &C, Expr *A,
                                SourceLocation StartLoc,
                                SourceLocation LParenLoc,
                                SourceLocation EndLoc);

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Returns alignment
  Expr *getAlignment() const { return cast_or_null<Expr>(Alignment); }

  child_range children() { return child_range(&Alignment, &Alignment + 1); }

  const_child_range children() const {
    return const_child_range(&Alignment, &Alignment + 1);
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_align;
  }
};

/// This represents clause 'allocate' in the '#pragma omp ...' directives.
///
/// \code
/// #pragma omp parallel private(a) allocate(omp_default_mem_alloc :a)
/// \endcode
/// In this example directive '#pragma omp parallel' has clause 'private'
/// and clause 'allocate' for the variable 'a'.
class OMPAllocateClause final
    : public OMPVarListClause<OMPAllocateClause>,
      private llvm::TrailingObjects<OMPAllocateClause, Expr *> {
  friend class OMPClauseReader;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Allocator specified in the clause, or 'nullptr' if the default one is
  /// used.
  Expr *Allocator = nullptr;
  /// Position of the ':' delimiter in the clause;
  SourceLocation ColonLoc;

  /// Build clause with number of variables \a N.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param Allocator Allocator expression.
  /// \param ColonLoc Location of ':' delimiter.
  /// \param EndLoc Ending location of the clause.
  /// \param N Number of the variables in the clause.
  OMPAllocateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                    Expr *Allocator, SourceLocation ColonLoc,
                    SourceLocation EndLoc, unsigned N)
      : OMPVarListClause<OMPAllocateClause>(llvm::omp::OMPC_allocate, StartLoc,
                                            LParenLoc, EndLoc, N),
        Allocator(Allocator), ColonLoc(ColonLoc) {}

  /// Build an empty clause.
  ///
  /// \param N Number of variables.
  explicit OMPAllocateClause(unsigned N)
      : OMPVarListClause<OMPAllocateClause>(llvm::omp::OMPC_allocate,
                                            SourceLocation(), SourceLocation(),
                                            SourceLocation(), N) {}

  /// Sets location of ':' symbol in clause.
  void setColonLoc(SourceLocation CL) { ColonLoc = CL; }

  void setAllocator(Expr *A) { Allocator = A; }

public:
  /// Creates clause with a list of variables \a VL.
  ///
  /// \param C AST context.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param Allocator Allocator expression.
  /// \param ColonLoc Location of ':' delimiter.
  /// \param EndLoc Ending location of the clause.
  /// \param VL List of references to the variables.
  static OMPAllocateClause *Create(const ASTContext &C, SourceLocation StartLoc,
                                   SourceLocation LParenLoc, Expr *Allocator,
                                   SourceLocation ColonLoc,
                                   SourceLocation EndLoc, ArrayRef<Expr *> VL);

  /// Returns the allocator expression or nullptr, if no allocator is specified.
  Expr *getAllocator() const { return Allocator; }

  /// Returns the location of the ':' delimiter.
  SourceLocation getColonLoc() const { return ColonLoc; }

  /// Creates an empty clause with the place for \a N variables.
  ///
  /// \param C AST context.
  /// \param N The number of variables.
  static OMPAllocateClause *CreateEmpty(const ASTContext &C, unsigned N);

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPAllocateClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_allocate;
  }
};

/// This represents 'if' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp parallel if(parallel:a > 5)
/// \endcode
/// In this example directive '#pragma omp parallel' has simple 'if' clause with
/// condition 'a > 5' and directive name modifier 'parallel'.
class OMPIfClause : public OMPClause, public OMPClauseWithPreInit {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Condition of the 'if' clause.
  Stmt *Condition = nullptr;

  /// Location of ':' (if any).
  SourceLocation ColonLoc;

  /// Directive name modifier for the clause.
  OpenMPDirectiveKind NameModifier = llvm::omp::OMPD_unknown;

  /// Name modifier location.
  SourceLocation NameModifierLoc;

  /// Set condition.
  void setCondition(Expr *Cond) { Condition = Cond; }

  /// Set directive name modifier for the clause.
  void setNameModifier(OpenMPDirectiveKind NM) { NameModifier = NM; }

  /// Set location of directive name modifier for the clause.
  void setNameModifierLoc(SourceLocation Loc) { NameModifierLoc = Loc; }

  /// Set location of ':'.
  void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }

public:
  /// Build 'if' clause with condition \a Cond.
  ///
  /// \param NameModifier [OpenMP 4.1] Directive name modifier of clause.
  /// \param Cond Condition of the clause.
  /// \param HelperCond Helper condition for the clause.
  /// \param CaptureRegion Innermost OpenMP region where expressions in this
  /// clause must be captured.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param NameModifierLoc Location of directive name modifier.
  /// \param ColonLoc [OpenMP 4.1] Location of ':'.
  /// \param EndLoc Ending location of the clause.
  OMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Cond, Stmt *HelperCond,
              OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
              SourceLocation LParenLoc, SourceLocation NameModifierLoc,
              SourceLocation ColonLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_if, StartLoc, EndLoc),
        OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond),
        ColonLoc(ColonLoc), NameModifier(NameModifier),
        NameModifierLoc(NameModifierLoc) {
    setPreInitStmt(HelperCond, CaptureRegion);
  }

  /// Build an empty clause.
  OMPIfClause()
      : OMPClause(llvm::omp::OMPC_if, SourceLocation(), SourceLocation()),
        OMPClauseWithPreInit(this) {}

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Return the location of ':'.
  SourceLocation getColonLoc() const { return ColonLoc; }

  /// Returns condition.
  Expr *getCondition() const { return cast_or_null<Expr>(Condition); }

  /// Return directive name modifier associated with the clause.
  OpenMPDirectiveKind getNameModifier() const { return NameModifier; }

  /// Return the location of directive name modifier.
  SourceLocation getNameModifierLoc() const { return NameModifierLoc; }

  child_range children() { return child_range(&Condition, &Condition + 1); }

  const_child_range children() const {
    return const_child_range(&Condition, &Condition + 1);
  }

  child_range used_children();
  const_child_range used_children() const {
    auto Children = const_cast<OMPIfClause *>(this)->used_children();
    return const_child_range(Children.begin(), Children.end());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_if;
  }
};

/// This represents 'final' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp task final(a > 5)
/// \endcode
/// In this example directive '#pragma omp task' has simple 'final'
/// clause with condition 'a > 5'.
class OMPFinalClause : public OMPClause, public OMPClauseWithPreInit {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Condition of the 'if' clause.
  Stmt *Condition = nullptr;

  /// Set condition.
  void setCondition(Expr *Cond) { Condition = Cond; }

public:
  /// Build 'final' clause with condition \a Cond.
  ///
  /// \param Cond Condition of the clause.
  /// \param HelperCond Helper condition for the construct.
  /// \param CaptureRegion Innermost OpenMP region where expressions in this
  /// clause must be captured.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPFinalClause(Expr *Cond, Stmt *HelperCond,
                 OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
                 SourceLocation LParenLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_final, StartLoc, EndLoc),
        OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond) {
    setPreInitStmt(HelperCond, CaptureRegion);
  }

  /// Build an empty clause.
  OMPFinalClause()
      : OMPClause(llvm::omp::OMPC_final, SourceLocation(), SourceLocation()),
        OMPClauseWithPreInit(this) {}

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Returns condition.
  Expr *getCondition() const { return cast_or_null<Expr>(Condition); }

  child_range children() { return child_range(&Condition, &Condition + 1); }

  const_child_range children() const {
    return const_child_range(&Condition, &Condition + 1);
  }

  child_range used_children();
  const_child_range used_children() const {
    auto Children = const_cast<OMPFinalClause *>(this)->used_children();
    return const_child_range(Children.begin(), Children.end());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_final;
  }
};

/// This represents 'num_threads' clause in the '#pragma omp ...'
/// directive.
///
/// \code
/// #pragma omp parallel num_threads(6)
/// \endcode
/// In this example directive '#pragma omp parallel' has simple 'num_threads'
/// clause with number of threads '6'.
class OMPNumThreadsClause : public OMPClause, public OMPClauseWithPreInit {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Condition of the 'num_threads' clause.
  Stmt *NumThreads = nullptr;

  /// Set condition.
  void setNumThreads(Expr *NThreads) { NumThreads = NThreads; }

public:
  /// Build 'num_threads' clause with condition \a NumThreads.
  ///
  /// \param NumThreads Number of threads for the construct.
  /// \param HelperNumThreads Helper Number of threads for the construct.
  /// \param CaptureRegion Innermost OpenMP region where expressions in this
  /// clause must be captured.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPNumThreadsClause(Expr *NumThreads, Stmt *HelperNumThreads,
                      OpenMPDirectiveKind CaptureRegion,
                      SourceLocation StartLoc, SourceLocation LParenLoc,
                      SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_num_threads, StartLoc, EndLoc),
        OMPClauseWithPreInit(this), LParenLoc(LParenLoc),
        NumThreads(NumThreads) {
    setPreInitStmt(HelperNumThreads, CaptureRegion);
  }

  /// Build an empty clause.
  OMPNumThreadsClause()
      : OMPClause(llvm::omp::OMPC_num_threads, SourceLocation(),
                  SourceLocation()),
        OMPClauseWithPreInit(this) {}

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Returns number of threads.
  Expr *getNumThreads() const { return cast_or_null<Expr>(NumThreads); }

  child_range children() { return child_range(&NumThreads, &NumThreads + 1); }

  const_child_range children() const {
    return const_child_range(&NumThreads, &NumThreads + 1);
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_num_threads;
  }
};

/// This represents 'safelen' clause in the '#pragma omp ...'
/// directive.
///
/// \code
/// #pragma omp simd safelen(4)
/// \endcode
/// In this example directive '#pragma omp simd' has clause 'safelen'
/// with single expression '4'.
/// If the safelen clause is used then no two iterations executed
/// concurrently with SIMD instructions can have a greater distance
/// in the logical iteration space than its value. The parameter of
/// the safelen clause must be a constant positive integer expression.
class OMPSafelenClause : public OMPClause {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Safe iteration space distance.
  Stmt *Safelen = nullptr;

  /// Set safelen.
  void setSafelen(Expr *Len) { Safelen = Len; }

public:
  /// Build 'safelen' clause.
  ///
  /// \param Len Expression associated with this clause.
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc,
                   SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_safelen, StartLoc, EndLoc),
        LParenLoc(LParenLoc), Safelen(Len) {}

  /// Build an empty clause.
  explicit OMPSafelenClause()
      : OMPClause(llvm::omp::OMPC_safelen, SourceLocation(), SourceLocation()) {
  }

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Return safe iteration space distance.
  Expr *getSafelen() const { return cast_or_null<Expr>(Safelen); }

  child_range children() { return child_range(&Safelen, &Safelen + 1); }

  const_child_range children() const {
    return const_child_range(&Safelen, &Safelen + 1);
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_safelen;
  }
};

/// This represents 'simdlen' clause in the '#pragma omp ...'
/// directive.
///
/// \code
/// #pragma omp simd simdlen(4)
/// \endcode
/// In this example directive '#pragma omp simd' has clause 'simdlen'
/// with single expression '4'.
/// If the 'simdlen' clause is used then it specifies the preferred number of
/// iterations to be executed concurrently. The parameter of the 'simdlen'
/// clause must be a constant positive integer expression.
class OMPSimdlenClause : public OMPClause {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Safe iteration space distance.
  Stmt *Simdlen = nullptr;

  /// Set simdlen.
  void setSimdlen(Expr *Len) { Simdlen = Len; }

public:
  /// Build 'simdlen' clause.
  ///
  /// \param Len Expression associated with this clause.
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPSimdlenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc,
                   SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_simdlen, StartLoc, EndLoc),
        LParenLoc(LParenLoc), Simdlen(Len) {}

  /// Build an empty clause.
  explicit OMPSimdlenClause()
      : OMPClause(llvm::omp::OMPC_simdlen, SourceLocation(), SourceLocation()) {
  }

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Return safe iteration space distance.
  Expr *getSimdlen() const { return cast_or_null<Expr>(Simdlen); }

  child_range children() { return child_range(&Simdlen, &Simdlen + 1); }

  const_child_range children() const {
    return const_child_range(&Simdlen, &Simdlen + 1);
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_simdlen;
  }
};

/// This represents the 'sizes' clause in the '#pragma omp tile' directive.
///
/// \code
/// #pragma omp tile sizes(5,5)
/// for (int i = 0; i < 64; ++i)
///   for (int j = 0; j < 64; ++j)
/// \endcode
class OMPSizesClause final
    : public OMPClause,
      private llvm::TrailingObjects<OMPSizesClause, Expr *> {
  friend class OMPClauseReader;
  friend class llvm::TrailingObjects<OMPSizesClause, Expr *>;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Number of tile sizes in the clause.
  unsigned NumSizes;

  /// Build an empty clause.
  explicit OMPSizesClause(int NumSizes)
      : OMPClause(llvm::omp::OMPC_sizes, SourceLocation(), SourceLocation()),
        NumSizes(NumSizes) {}

public:
  /// Build a 'sizes' AST node.
  ///
  /// \param C         Context of the AST.
  /// \param StartLoc  Location of the 'sizes' identifier.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc    Location of ')'.
  /// \param Sizes     Content of the clause.
  static OMPSizesClause *Create(const ASTContext &C, SourceLocation StartLoc,
                                SourceLocation LParenLoc, SourceLocation EndLoc,
                                ArrayRef<Expr *> Sizes);

  /// Build an empty 'sizes' AST node for deserialization.
  ///
  /// \param C     Context of the AST.
  /// \param NumSizes Number of items in the clause.
  static OMPSizesClause *CreateEmpty(const ASTContext &C, unsigned NumSizes);

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Returns the number of list items.
  unsigned getNumSizes() const { return NumSizes; }

  /// Returns the tile size expressions.
  MutableArrayRef<Expr *> getSizesRefs() {
    return MutableArrayRef<Expr *>(static_cast<OMPSizesClause *>(this)
                                       ->template getTrailingObjects<Expr *>(),
                                   NumSizes);
  }
  ArrayRef<Expr *> getSizesRefs() const {
    return ArrayRef<Expr *>(static_cast<const OMPSizesClause *>(this)
                                ->template getTrailingObjects<Expr *>(),
                            NumSizes);
  }

  /// Sets the tile size expressions.
  void setSizesRefs(ArrayRef<Expr *> VL) {
    assert(VL.size() == NumSizes);
    std::copy(VL.begin(), VL.end(),
              static_cast<OMPSizesClause *>(this)
                  ->template getTrailingObjects<Expr *>());
  }

  child_range children() {
    MutableArrayRef<Expr *> Sizes = getSizesRefs();
    return child_range(reinterpret_cast<Stmt **>(Sizes.begin()),
                       reinterpret_cast<Stmt **>(Sizes.end()));
  }
  const_child_range children() const {
    ArrayRef<Expr *> Sizes = getSizesRefs();
    return const_child_range(reinterpret_cast<Stmt *const *>(Sizes.begin()),
                             reinterpret_cast<Stmt *const *>(Sizes.end()));
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_sizes;
  }
};

/// Representation of the 'full' clause of the '#pragma omp unroll' directive.
///
/// \code
/// #pragma omp unroll full
/// for (int i = 0; i < 64; ++i)
/// \endcode
class OMPFullClause final : public OMPClause {
  friend class OMPClauseReader;

  /// Build an empty clause.
  explicit OMPFullClause() : OMPClause(llvm::omp::OMPC_full, {}, {}) {}

public:
  /// Build an AST node for a 'full' clause.
  ///
  /// \param C        Context of the AST.
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc   Ending location of the clause.
  static OMPFullClause *Create(const ASTContext &C, SourceLocation StartLoc,
                               SourceLocation EndLoc);

  /// Build an empty 'full' AST node for deserialization.
  ///
  /// \param C Context of the AST.
  static OMPFullClause *CreateEmpty(const ASTContext &C);

  child_range children() { return {child_iterator(), child_iterator()}; }
  const_child_range children() const {
    return {const_child_iterator(), const_child_iterator()};
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_full;
  }
};

/// Representation of the 'partial' clause of the '#pragma omp unroll'
/// directive.
///
/// \code
/// #pragma omp unroll partial(4)
/// for (int i = start; i < end; ++i)
/// \endcode
class OMPPartialClause final : public OMPClause {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Optional argument to the clause (unroll factor).
  Stmt *Factor;

  /// Build an empty clause.
  explicit OMPPartialClause() : OMPClause(llvm::omp::OMPC_partial, {}, {}) {}

  /// Set the unroll factor.
  void setFactor(Expr *E) { Factor = E; }

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

public:
  /// Build an AST node for a 'partial' clause.
  ///
  /// \param C         Context of the AST.
  /// \param StartLoc  Location of the 'partial' identifier.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc    Location of ')'.
  /// \param Factor    Clause argument.
  static OMPPartialClause *Create(const ASTContext &C, SourceLocation StartLoc,
                                  SourceLocation LParenLoc,
                                  SourceLocation EndLoc, Expr *Factor);

  /// Build an empty 'partial' AST node for deserialization.
  ///
  /// \param C     Context of the AST.
  static OMPPartialClause *CreateEmpty(const ASTContext &C);

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Returns the argument of the clause or nullptr if not set.
  Expr *getFactor() const { return cast_or_null<Expr>(Factor); }

  child_range children() { return child_range(&Factor, &Factor + 1); }
  const_child_range children() const {
    return const_child_range(&Factor, &Factor + 1);
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_partial;
  }
};

/// This represents 'collapse' clause in the '#pragma omp ...'
/// directive.
///
/// \code
/// #pragma omp simd collapse(3)
/// \endcode
/// In this example directive '#pragma omp simd' has clause 'collapse'
/// with single expression '3'.
/// The parameter must be a constant positive integer expression, it specifies
/// the number of nested loops that should be collapsed into a single iteration
/// space.
class OMPCollapseClause : public OMPClause {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Number of for-loops.
  Stmt *NumForLoops = nullptr;

  /// Set the number of associated for-loops.
  void setNumForLoops(Expr *Num) { NumForLoops = Num; }

public:
  /// Build 'collapse' clause.
  ///
  /// \param Num Expression associated with this clause.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPCollapseClause(Expr *Num, SourceLocation StartLoc,
                    SourceLocation LParenLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_collapse, StartLoc, EndLoc),
        LParenLoc(LParenLoc), NumForLoops(Num) {}

  /// Build an empty clause.
  explicit OMPCollapseClause()
      : OMPClause(llvm::omp::OMPC_collapse, SourceLocation(),
                  SourceLocation()) {}

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Return the number of associated for-loops.
  Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); }

  child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); }

  const_child_range children() const {
    return const_child_range(&NumForLoops, &NumForLoops + 1);
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_collapse;
  }
};

/// This represents 'default' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp parallel default(shared)
/// \endcode
/// In this example directive '#pragma omp parallel' has simple 'default'
/// clause with kind 'shared'.
class OMPDefaultClause : public OMPClause {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// A kind of the 'default' clause.
  llvm::omp::DefaultKind Kind = llvm::omp::OMP_DEFAULT_unknown;

  /// Start location of the kind in source code.
  SourceLocation KindKwLoc;

  /// Set kind of the clauses.
  ///
  /// \param K Argument of clause.
  void setDefaultKind(llvm::omp::DefaultKind K) { Kind = K; }

  /// Set argument location.
  ///
  /// \param KLoc Argument location.
  void setDefaultKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }

public:
  /// Build 'default' clause with argument \a A ('none' or 'shared').
  ///
  /// \param A Argument of the clause ('none' or 'shared').
  /// \param ALoc Starting location of the argument.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPDefaultClause(llvm::omp::DefaultKind A, SourceLocation ALoc,
                   SourceLocation StartLoc, SourceLocation LParenLoc,
                   SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_default, StartLoc, EndLoc),
        LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {}

  /// Build an empty clause.
  OMPDefaultClause()
      : OMPClause(llvm::omp::OMPC_default, SourceLocation(), SourceLocation()) {
  }

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Returns kind of the clause.
  llvm::omp::DefaultKind getDefaultKind() const { return Kind; }

  /// Returns location of clause kind.
  SourceLocation getDefaultKindKwLoc() const { return KindKwLoc; }

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_default;
  }
};

/// This represents 'proc_bind' clause in the '#pragma omp ...'
/// directive.
///
/// \code
/// #pragma omp parallel proc_bind(master)
/// \endcode
/// In this example directive '#pragma omp parallel' has simple 'proc_bind'
/// clause with kind 'master'.
class OMPProcBindClause : public OMPClause {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// A kind of the 'proc_bind' clause.
  llvm::omp::ProcBindKind Kind = llvm::omp::OMP_PROC_BIND_unknown;

  /// Start location of the kind in source code.
  SourceLocation KindKwLoc;

  /// Set kind of the clause.
  ///
  /// \param K Kind of clause.
  void setProcBindKind(llvm::omp::ProcBindKind K) { Kind = K; }

  /// Set clause kind location.
  ///
  /// \param KLoc Kind location.
  void setProcBindKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }

public:
  /// Build 'proc_bind' clause with argument \a A ('master', 'close' or
  ///        'spread').
  ///
  /// \param A Argument of the clause ('master', 'close' or 'spread').
  /// \param ALoc Starting location of the argument.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPProcBindClause(llvm::omp::ProcBindKind A, SourceLocation ALoc,
                    SourceLocation StartLoc, SourceLocation LParenLoc,
                    SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_proc_bind, StartLoc, EndLoc),
        LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {}

  /// Build an empty clause.
  OMPProcBindClause()
      : OMPClause(llvm::omp::OMPC_proc_bind, SourceLocation(),
                  SourceLocation()) {}

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Returns kind of the clause.
  llvm::omp::ProcBindKind getProcBindKind() const { return Kind; }

  /// Returns location of clause kind.
  SourceLocation getProcBindKindKwLoc() const { return KindKwLoc; }

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_proc_bind;
  }
};

/// This represents 'unified_address' clause in the '#pragma omp requires'
/// directive.
///
/// \code
/// #pragma omp requires unified_address
/// \endcode
/// In this example directive '#pragma omp requires' has 'unified_address'
/// clause.
class OMPUnifiedAddressClause final : public OMPClause {
public:
  friend class OMPClauseReader;
  /// Build 'unified_address' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_unified_address, StartLoc, EndLoc) {}

  /// Build an empty clause.
  OMPUnifiedAddressClause()
      : OMPClause(llvm::omp::OMPC_unified_address, SourceLocation(),
                  SourceLocation()) {}

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_unified_address;
  }
};

/// This represents 'unified_shared_memory' clause in the '#pragma omp requires'
/// directive.
///
/// \code
/// #pragma omp requires unified_shared_memory
/// \endcode
/// In this example directive '#pragma omp requires' has 'unified_shared_memory'
/// clause.
class OMPUnifiedSharedMemoryClause final : public OMPClause {
public:
  friend class OMPClauseReader;
  /// Build 'unified_shared_memory' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_unified_shared_memory, StartLoc, EndLoc) {}

  /// Build an empty clause.
  OMPUnifiedSharedMemoryClause()
      : OMPClause(llvm::omp::OMPC_unified_shared_memory, SourceLocation(),
                  SourceLocation()) {}

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_unified_shared_memory;
  }
};

/// This represents 'reverse_offload' clause in the '#pragma omp requires'
/// directive.
///
/// \code
/// #pragma omp requires reverse_offload
/// \endcode
/// In this example directive '#pragma omp requires' has 'reverse_offload'
/// clause.
class OMPReverseOffloadClause final : public OMPClause {
public:
  friend class OMPClauseReader;
  /// Build 'reverse_offload' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_reverse_offload, StartLoc, EndLoc) {}

  /// Build an empty clause.
  OMPReverseOffloadClause()
      : OMPClause(llvm::omp::OMPC_reverse_offload, SourceLocation(),
                  SourceLocation()) {}

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_reverse_offload;
  }
};

/// This represents 'dynamic_allocators' clause in the '#pragma omp requires'
/// directive.
///
/// \code
/// #pragma omp requires dynamic_allocators
/// \endcode
/// In this example directive '#pragma omp requires' has 'dynamic_allocators'
/// clause.
class OMPDynamicAllocatorsClause final : public OMPClause {
public:
  friend class OMPClauseReader;
  /// Build 'dynamic_allocators' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPDynamicAllocatorsClause(SourceLocation StartLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_dynamic_allocators, StartLoc, EndLoc) {}

  /// Build an empty clause.
  OMPDynamicAllocatorsClause()
      : OMPClause(llvm::omp::OMPC_dynamic_allocators, SourceLocation(),
                  SourceLocation()) {}

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_dynamic_allocators;
  }
};

/// This represents 'atomic_default_mem_order' clause in the '#pragma omp
/// requires'  directive.
///
/// \code
/// #pragma omp requires atomic_default_mem_order(seq_cst)
/// \endcode
/// In this example directive '#pragma omp requires' has simple
/// atomic_default_mem_order' clause with kind 'seq_cst'.
class OMPAtomicDefaultMemOrderClause final : public OMPClause {
  friend class OMPClauseReader;

  /// Location of '('
  SourceLocation LParenLoc;

  /// A kind of the 'atomic_default_mem_order' clause.
  OpenMPAtomicDefaultMemOrderClauseKind Kind =
      OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown;

  /// Start location of the kind in source code.
  SourceLocation KindKwLoc;

  /// Set kind of the clause.
  ///
  /// \param K Kind of clause.
  void setAtomicDefaultMemOrderKind(OpenMPAtomicDefaultMemOrderClauseKind K) {
    Kind = K;
  }

  /// Set clause kind location.
  ///
  /// \param KLoc Kind location.
  void setAtomicDefaultMemOrderKindKwLoc(SourceLocation KLoc) {
    KindKwLoc = KLoc;
  }

public:
  /// Build 'atomic_default_mem_order' clause with argument \a A ('seq_cst',
  /// 'acq_rel' or 'relaxed').
  ///
  /// \param A Argument of the clause ('seq_cst', 'acq_rel' or 'relaxed').
  /// \param ALoc Starting location of the argument.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind A,
                                 SourceLocation ALoc, SourceLocation StartLoc,
                                 SourceLocation LParenLoc,
                                 SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_atomic_default_mem_order, StartLoc, EndLoc),
        LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {}

  /// Build an empty clause.
  OMPAtomicDefaultMemOrderClause()
      : OMPClause(llvm::omp::OMPC_atomic_default_mem_order, SourceLocation(),
                  SourceLocation()) {}

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the locaiton of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Returns kind of the clause.
  OpenMPAtomicDefaultMemOrderClauseKind getAtomicDefaultMemOrderKind() const {
    return Kind;
  }

  /// Returns location of clause kind.
  SourceLocation getAtomicDefaultMemOrderKindKwLoc() const { return KindKwLoc; }

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_atomic_default_mem_order;
  }
};

/// This represents 'schedule' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp for schedule(static, 3)
/// \endcode
/// In this example directive '#pragma omp for' has 'schedule' clause with
/// arguments 'static' and '3'.
class OMPScheduleClause : public OMPClause, public OMPClauseWithPreInit {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// A kind of the 'schedule' clause.
  OpenMPScheduleClauseKind Kind = OMPC_SCHEDULE_unknown;

  /// Modifiers for 'schedule' clause.
  enum {FIRST, SECOND, NUM_MODIFIERS};
  OpenMPScheduleClauseModifier Modifiers[NUM_MODIFIERS];

  /// Locations of modifiers.
  SourceLocation ModifiersLoc[NUM_MODIFIERS];

  /// Start location of the schedule ind in source code.
  SourceLocation KindLoc;

  /// Location of ',' (if any).
  SourceLocation CommaLoc;

  /// Chunk size.
  Expr *ChunkSize = nullptr;

  /// Set schedule kind.
  ///
  /// \param K Schedule kind.
  void setScheduleKind(OpenMPScheduleClauseKind K) { Kind = K; }

  /// Set the first schedule modifier.
  ///
  /// \param M Schedule modifier.
  void setFirstScheduleModifier(OpenMPScheduleClauseModifier M) {
    Modifiers[FIRST] = M;
  }

  /// Set the second schedule modifier.
  ///
  /// \param M Schedule modifier.
  void setSecondScheduleModifier(OpenMPScheduleClauseModifier M) {
    Modifiers[SECOND] = M;
  }

  /// Set location of the first schedule modifier.
  void setFirstScheduleModifierLoc(SourceLocation Loc) {
    ModifiersLoc[FIRST] = Loc;
  }

  /// Set location of the second schedule modifier.
  void setSecondScheduleModifierLoc(SourceLocation Loc) {
    ModifiersLoc[SECOND] = Loc;
  }

  /// Set schedule modifier location.
  ///
  /// \param M Schedule modifier location.
  void setScheduleModifer(OpenMPScheduleClauseModifier M) {
    if (Modifiers[FIRST] == OMPC_SCHEDULE_MODIFIER_unknown)
      Modifiers[FIRST] = M;
    else {
      assert(Modifiers[SECOND] == OMPC_SCHEDULE_MODIFIER_unknown);
      Modifiers[SECOND] = M;
    }
  }

  /// Sets the location of '('.
  ///
  /// \param Loc Location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Set schedule kind start location.
  ///
  /// \param KLoc Schedule kind location.
  void setScheduleKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }

  /// Set location of ','.
  ///
  /// \param Loc Location of ','.
  void setCommaLoc(SourceLocation Loc) { CommaLoc = Loc; }

  /// Set chunk size.
  ///
  /// \param E Chunk size.
  void setChunkSize(Expr *E) { ChunkSize = E; }

public:
  /// Build 'schedule' clause with schedule kind \a Kind and chunk size
  /// expression \a ChunkSize.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param KLoc Starting location of the argument.
  /// \param CommaLoc Location of ','.
  /// \param EndLoc Ending location of the clause.
  /// \param Kind Schedule kind.
  /// \param ChunkSize Chunk size.
  /// \param HelperChunkSize Helper chunk size for combined directives.
  /// \param M1 The first modifier applied to 'schedule' clause.
  /// \param M1Loc Location of the first modifier
  /// \param M2 The second modifier applied to 'schedule' clause.
  /// \param M2Loc Location of the second modifier
  OMPScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                    SourceLocation KLoc, SourceLocation CommaLoc,
                    SourceLocation EndLoc, OpenMPScheduleClauseKind Kind,
                    Expr *ChunkSize, Stmt *HelperChunkSize,
                    OpenMPScheduleClauseModifier M1, SourceLocation M1Loc,
                    OpenMPScheduleClauseModifier M2, SourceLocation M2Loc)
      : OMPClause(llvm::omp::OMPC_schedule, StartLoc, EndLoc),
        OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind),
        KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) {
    setPreInitStmt(HelperChunkSize);
    Modifiers[FIRST] = M1;
    Modifiers[SECOND] = M2;
    ModifiersLoc[FIRST] = M1Loc;
    ModifiersLoc[SECOND] = M2Loc;
  }

  /// Build an empty clause.
  explicit OMPScheduleClause()
      : OMPClause(llvm::omp::OMPC_schedule, SourceLocation(), SourceLocation()),
        OMPClauseWithPreInit(this) {
    Modifiers[FIRST] = OMPC_SCHEDULE_MODIFIER_unknown;
    Modifiers[SECOND] = OMPC_SCHEDULE_MODIFIER_unknown;
  }

  /// Get kind of the clause.
  OpenMPScheduleClauseKind getScheduleKind() const { return Kind; }

  /// Get the first modifier of the clause.
  OpenMPScheduleClauseModifier getFirstScheduleModifier() const {
    return Modifiers[FIRST];
  }

  /// Get the second modifier of the clause.
  OpenMPScheduleClauseModifier getSecondScheduleModifier() const {
    return Modifiers[SECOND];
  }

  /// Get location of '('.
  SourceLocation getLParenLoc() { return LParenLoc; }

  /// Get kind location.
  SourceLocation getScheduleKindLoc() { return KindLoc; }

  /// Get the first modifier location.
  SourceLocation getFirstScheduleModifierLoc() const {
    return ModifiersLoc[FIRST];
  }

  /// Get the second modifier location.
  SourceLocation getSecondScheduleModifierLoc() const {
    return ModifiersLoc[SECOND];
  }

  /// Get location of ','.
  SourceLocation getCommaLoc() { return CommaLoc; }

  /// Get chunk size.
  Expr *getChunkSize() { return ChunkSize; }

  /// Get chunk size.
  const Expr *getChunkSize() const { return ChunkSize; }

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(&ChunkSize),
                       reinterpret_cast<Stmt **>(&ChunkSize) + 1);
  }

  const_child_range children() const {
    auto Children = const_cast<OMPScheduleClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_schedule;
  }
};

/// This represents 'ordered' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp for ordered (2)
/// \endcode
/// In this example directive '#pragma omp for' has 'ordered' clause with
/// parameter 2.
class OMPOrderedClause final
    : public OMPClause,
      private llvm::TrailingObjects<OMPOrderedClause, Expr *> {
  friend class OMPClauseReader;
  friend TrailingObjects;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Number of for-loops.
  Stmt *NumForLoops = nullptr;

  /// Real number of loops.
  unsigned NumberOfLoops = 0;

  /// Build 'ordered' clause.
  ///
  /// \param Num Expression, possibly associated with this clause.
  /// \param NumLoops Number of loops, associated with this clause.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPOrderedClause(Expr *Num, unsigned NumLoops, SourceLocation StartLoc,
                   SourceLocation LParenLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_ordered, StartLoc, EndLoc),
        LParenLoc(LParenLoc), NumForLoops(Num), NumberOfLoops(NumLoops) {}

  /// Build an empty clause.
  explicit OMPOrderedClause(unsigned NumLoops)
      : OMPClause(llvm::omp::OMPC_ordered, SourceLocation(), SourceLocation()),
        NumberOfLoops(NumLoops) {}

  /// Set the number of associated for-loops.
  void setNumForLoops(Expr *Num) { NumForLoops = Num; }

public:
  /// Build 'ordered' clause.
  ///
  /// \param Num Expression, possibly associated with this clause.
  /// \param NumLoops Number of loops, associated with this clause.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  static OMPOrderedClause *Create(const ASTContext &C, Expr *Num,
                                  unsigned NumLoops, SourceLocation StartLoc,
                                  SourceLocation LParenLoc,
                                  SourceLocation EndLoc);

  /// Build an empty clause.
  static OMPOrderedClause* CreateEmpty(const ASTContext &C, unsigned NumLoops);

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Return the number of associated for-loops.
  Expr *getNumForLoops() const { return cast_or_null<Expr>(NumForLoops); }

  /// Set number of iterations for the specified loop.
  void setLoopNumIterations(unsigned NumLoop, Expr *NumIterations);
  /// Get number of iterations for all the loops.
  ArrayRef<Expr *> getLoopNumIterations() const;

  /// Set loop counter for the specified loop.
  void setLoopCounter(unsigned NumLoop, Expr *Counter);
  /// Get loops counter for the specified loop.
  Expr *getLoopCounter(unsigned NumLoop);
  const Expr *getLoopCounter(unsigned NumLoop) const;

  child_range children() { return child_range(&NumForLoops, &NumForLoops + 1); }

  const_child_range children() const {
    return const_child_range(&NumForLoops, &NumForLoops + 1);
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_ordered;
  }
};

/// This represents 'nowait' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp for nowait
/// \endcode
/// In this example directive '#pragma omp for' has 'nowait' clause.
class OMPNowaitClause : public OMPClause {
public:
  /// Build 'nowait' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_nowait, StartLoc, EndLoc) {}

  /// Build an empty clause.
  OMPNowaitClause()
      : OMPClause(llvm::omp::OMPC_nowait, SourceLocation(), SourceLocation()) {}

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_nowait;
  }
};

/// This represents 'untied' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp task untied
/// \endcode
/// In this example directive '#pragma omp task' has 'untied' clause.
class OMPUntiedClause : public OMPClause {
public:
  /// Build 'untied' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_untied, StartLoc, EndLoc) {}

  /// Build an empty clause.
  OMPUntiedClause()
      : OMPClause(llvm::omp::OMPC_untied, SourceLocation(), SourceLocation()) {}

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_untied;
  }
};

/// This represents 'mergeable' clause in the '#pragma omp ...'
/// directive.
///
/// \code
/// #pragma omp task mergeable
/// \endcode
/// In this example directive '#pragma omp task' has 'mergeable' clause.
class OMPMergeableClause : public OMPClause {
public:
  /// Build 'mergeable' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_mergeable, StartLoc, EndLoc) {}

  /// Build an empty clause.
  OMPMergeableClause()
      : OMPClause(llvm::omp::OMPC_mergeable, SourceLocation(),
                  SourceLocation()) {}

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_mergeable;
  }
};

/// This represents 'read' clause in the '#pragma omp atomic' directive.
///
/// \code
/// #pragma omp atomic read
/// \endcode
/// In this example directive '#pragma omp atomic' has 'read' clause.
class OMPReadClause : public OMPClause {
public:
  /// Build 'read' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_read, StartLoc, EndLoc) {}

  /// Build an empty clause.
  OMPReadClause()
      : OMPClause(llvm::omp::OMPC_read, SourceLocation(), SourceLocation()) {}

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_read;
  }
};

/// This represents 'write' clause in the '#pragma omp atomic' directive.
///
/// \code
/// #pragma omp atomic write
/// \endcode
/// In this example directive '#pragma omp atomic' has 'write' clause.
class OMPWriteClause : public OMPClause {
public:
  /// Build 'write' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_write, StartLoc, EndLoc) {}

  /// Build an empty clause.
  OMPWriteClause()
      : OMPClause(llvm::omp::OMPC_write, SourceLocation(), SourceLocation()) {}

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_write;
  }
};

/// This represents 'update' clause in the '#pragma omp atomic'
/// directive.
///
/// \code
/// #pragma omp atomic update
/// \endcode
/// In this example directive '#pragma omp atomic' has 'update' clause.
/// Also, this class represents 'update' clause in  '#pragma omp depobj'
/// directive.
///
/// \code
/// #pragma omp depobj(a) update(in)
/// \endcode
/// In this example directive '#pragma omp depobj' has 'update' clause with 'in'
/// dependence kind.
class OMPUpdateClause final
    : public OMPClause,
      private llvm::TrailingObjects<OMPUpdateClause, SourceLocation,
                                    OpenMPDependClauseKind> {
  friend class OMPClauseReader;
  friend TrailingObjects;

  /// true if extended version of the clause for 'depobj' directive.
  bool IsExtended = false;

  /// Define the sizes of each trailing object array except the last one. This
  /// is required for TrailingObjects to work properly.
  size_t numTrailingObjects(OverloadToken<SourceLocation>) const {
    // 2 locations: for '(' and argument location.
    return IsExtended ? 2 : 0;
  }

  /// Sets the location of '(' in clause for 'depobj' directive.
  void setLParenLoc(SourceLocation Loc) {
    assert(IsExtended && "Expected extended clause.");
    *getTrailingObjects<SourceLocation>() = Loc;
  }

  /// Sets the location of '(' in clause for 'depobj' directive.
  void setArgumentLoc(SourceLocation Loc) {
    assert(IsExtended && "Expected extended clause.");
    *std::next(getTrailingObjects<SourceLocation>(), 1) = Loc;
  }

  /// Sets the dependence kind for the clause for 'depobj' directive.
  void setDependencyKind(OpenMPDependClauseKind DK) {
    assert(IsExtended && "Expected extended clause.");
    *getTrailingObjects<OpenMPDependClauseKind>() = DK;
  }

  /// Build 'update' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc,
                  bool IsExtended)
      : OMPClause(llvm::omp::OMPC_update, StartLoc, EndLoc),
        IsExtended(IsExtended) {}

  /// Build an empty clause.
  OMPUpdateClause(bool IsExtended)
      : OMPClause(llvm::omp::OMPC_update, SourceLocation(), SourceLocation()),
        IsExtended(IsExtended) {}

public:
  /// Creates clause for 'atomic' directive.
  ///
  /// \param C AST context.
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  static OMPUpdateClause *Create(const ASTContext &C, SourceLocation StartLoc,
                                 SourceLocation EndLoc);

  /// Creates clause for 'depobj' directive.
  ///
  /// \param C AST context.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param ArgumentLoc Location of the argument.
  /// \param DK Dependence kind.
  /// \param EndLoc Ending location of the clause.
  static OMPUpdateClause *Create(const ASTContext &C, SourceLocation StartLoc,
                                 SourceLocation LParenLoc,
                                 SourceLocation ArgumentLoc,
                                 OpenMPDependClauseKind DK,
                                 SourceLocation EndLoc);

  /// Creates an empty clause with the place for \a N variables.
  ///
  /// \param C AST context.
  /// \param IsExtended true if extended clause for 'depobj' directive must be
  /// created.
  static OMPUpdateClause *CreateEmpty(const ASTContext &C, bool IsExtended);

  /// Checks if the clause is the extended clauses for 'depobj' directive.
  bool isExtended() const { return IsExtended; }

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  /// Gets the location of '(' in clause for 'depobj' directive.
  SourceLocation getLParenLoc() const {
    assert(IsExtended && "Expected extended clause.");
    return *getTrailingObjects<SourceLocation>();
  }

  /// Gets the location of argument in clause for 'depobj' directive.
  SourceLocation getArgumentLoc() const {
    assert(IsExtended && "Expected extended clause.");
    return *std::next(getTrailingObjects<SourceLocation>(), 1);
  }

  /// Gets the dependence kind in clause for 'depobj' directive.
  OpenMPDependClauseKind getDependencyKind() const {
    assert(IsExtended && "Expected extended clause.");
    return *getTrailingObjects<OpenMPDependClauseKind>();
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_update;
  }
};

/// This represents 'capture' clause in the '#pragma omp atomic'
/// directive.
///
/// \code
/// #pragma omp atomic capture
/// \endcode
/// In this example directive '#pragma omp atomic' has 'capture' clause.
class OMPCaptureClause : public OMPClause {
public:
  /// Build 'capture' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_capture, StartLoc, EndLoc) {}

  /// Build an empty clause.
  OMPCaptureClause()
      : OMPClause(llvm::omp::OMPC_capture, SourceLocation(), SourceLocation()) {
  }

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_capture;
  }
};

/// This represents 'compare' clause in the '#pragma omp atomic'
/// directive.
///
/// \code
/// #pragma omp atomic compare
/// \endcode
/// In this example directive '#pragma omp atomic' has 'compare' clause.
class OMPCompareClause final : public OMPClause {
public:
  /// Build 'compare' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPCompareClause(SourceLocation StartLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_compare, StartLoc, EndLoc) {}

  /// Build an empty clause.
  OMPCompareClause()
      : OMPClause(llvm::omp::OMPC_compare, SourceLocation(), SourceLocation()) {
  }

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_compare;
  }
};

/// This represents 'seq_cst' clause in the '#pragma omp atomic'
/// directive.
///
/// \code
/// #pragma omp atomic seq_cst
/// \endcode
/// In this example directive '#pragma omp atomic' has 'seq_cst' clause.
class OMPSeqCstClause : public OMPClause {
public:
  /// Build 'seq_cst' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_seq_cst, StartLoc, EndLoc) {}

  /// Build an empty clause.
  OMPSeqCstClause()
      : OMPClause(llvm::omp::OMPC_seq_cst, SourceLocation(), SourceLocation()) {
  }

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_seq_cst;
  }
};

/// This represents 'acq_rel' clause in the '#pragma omp atomic|flush'
/// directives.
///
/// \code
/// #pragma omp flush acq_rel
/// \endcode
/// In this example directive '#pragma omp flush' has 'acq_rel' clause.
class OMPAcqRelClause final : public OMPClause {
public:
  /// Build 'ack_rel' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPAcqRelClause(SourceLocation StartLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_acq_rel, StartLoc, EndLoc) {}

  /// Build an empty clause.
  OMPAcqRelClause()
      : OMPClause(llvm::omp::OMPC_acq_rel, SourceLocation(), SourceLocation()) {
  }

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_acq_rel;
  }
};

/// This represents 'acquire' clause in the '#pragma omp atomic|flush'
/// directives.
///
/// \code
/// #pragma omp flush acquire
/// \endcode
/// In this example directive '#pragma omp flush' has 'acquire' clause.
class OMPAcquireClause final : public OMPClause {
public:
  /// Build 'acquire' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPAcquireClause(SourceLocation StartLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_acquire, StartLoc, EndLoc) {}

  /// Build an empty clause.
  OMPAcquireClause()
      : OMPClause(llvm::omp::OMPC_acquire, SourceLocation(), SourceLocation()) {
  }

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_acquire;
  }
};

/// This represents 'release' clause in the '#pragma omp atomic|flush'
/// directives.
///
/// \code
/// #pragma omp flush release
/// \endcode
/// In this example directive '#pragma omp flush' has 'release' clause.
class OMPReleaseClause final : public OMPClause {
public:
  /// Build 'release' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPReleaseClause(SourceLocation StartLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_release, StartLoc, EndLoc) {}

  /// Build an empty clause.
  OMPReleaseClause()
      : OMPClause(llvm::omp::OMPC_release, SourceLocation(), SourceLocation()) {
  }

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_release;
  }
};

/// This represents 'relaxed' clause in the '#pragma omp atomic'
/// directives.
///
/// \code
/// #pragma omp atomic relaxed
/// \endcode
/// In this example directive '#pragma omp atomic' has 'relaxed' clause.
class OMPRelaxedClause final : public OMPClause {
public:
  /// Build 'relaxed' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPRelaxedClause(SourceLocation StartLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_relaxed, StartLoc, EndLoc) {}

  /// Build an empty clause.
  OMPRelaxedClause()
      : OMPClause(llvm::omp::OMPC_relaxed, SourceLocation(), SourceLocation()) {
  }

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_relaxed;
  }
};

/// This represents clause 'private' in the '#pragma omp ...' directives.
///
/// \code
/// #pragma omp parallel private(a,b)
/// \endcode
/// In this example directive '#pragma omp parallel' has clause 'private'
/// with the variables 'a' and 'b'.
class OMPPrivateClause final
    : public OMPVarListClause<OMPPrivateClause>,
      private llvm::TrailingObjects<OMPPrivateClause, Expr *> {
  friend class OMPClauseReader;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Build clause with number of variables \a N.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param N Number of the variables in the clause.
  OMPPrivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                   SourceLocation EndLoc, unsigned N)
      : OMPVarListClause<OMPPrivateClause>(llvm::omp::OMPC_private, StartLoc,
                                           LParenLoc, EndLoc, N) {}

  /// Build an empty clause.
  ///
  /// \param N Number of variables.
  explicit OMPPrivateClause(unsigned N)
      : OMPVarListClause<OMPPrivateClause>(llvm::omp::OMPC_private,
                                           SourceLocation(), SourceLocation(),
                                           SourceLocation(), N) {}

  /// Sets the list of references to private copies with initializers for
  /// new private variables.
  /// \param VL List of references.
  void setPrivateCopies(ArrayRef<Expr *> VL);

  /// Gets the list of references to private copies with initializers for
  /// new private variables.
  MutableArrayRef<Expr *> getPrivateCopies() {
    return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
  }
  ArrayRef<const Expr *> getPrivateCopies() const {
    return llvm::makeArrayRef(varlist_end(), varlist_size());
  }

public:
  /// Creates clause with a list of variables \a VL.
  ///
  /// \param C AST context.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param VL List of references to the variables.
  /// \param PrivateVL List of references to private copies with initializers.
  static OMPPrivateClause *Create(const ASTContext &C, SourceLocation StartLoc,
                                  SourceLocation LParenLoc,
                                  SourceLocation EndLoc, ArrayRef<Expr *> VL,
                                  ArrayRef<Expr *> PrivateVL);

  /// Creates an empty clause with the place for \a N variables.
  ///
  /// \param C AST context.
  /// \param N The number of variables.
  static OMPPrivateClause *CreateEmpty(const ASTContext &C, unsigned N);

  using private_copies_iterator = MutableArrayRef<Expr *>::iterator;
  using private_copies_const_iterator = ArrayRef<const Expr *>::iterator;
  using private_copies_range = llvm::iterator_range<private_copies_iterator>;
  using private_copies_const_range =
      llvm::iterator_range<private_copies_const_iterator>;

  private_copies_range private_copies() {
    return private_copies_range(getPrivateCopies().begin(),
                                getPrivateCopies().end());
  }

  private_copies_const_range private_copies() const {
    return private_copies_const_range(getPrivateCopies().begin(),
                                      getPrivateCopies().end());
  }

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPPrivateClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_private;
  }
};

/// This represents clause 'firstprivate' in the '#pragma omp ...'
/// directives.
///
/// \code
/// #pragma omp parallel firstprivate(a,b)
/// \endcode
/// In this example directive '#pragma omp parallel' has clause 'firstprivate'
/// with the variables 'a' and 'b'.
class OMPFirstprivateClause final
    : public OMPVarListClause<OMPFirstprivateClause>,
      public OMPClauseWithPreInit,
      private llvm::TrailingObjects<OMPFirstprivateClause, Expr *> {
  friend class OMPClauseReader;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Build clause with number of variables \a N.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param N Number of the variables in the clause.
  OMPFirstprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                        SourceLocation EndLoc, unsigned N)
      : OMPVarListClause<OMPFirstprivateClause>(llvm::omp::OMPC_firstprivate,
                                                StartLoc, LParenLoc, EndLoc, N),
        OMPClauseWithPreInit(this) {}

  /// Build an empty clause.
  ///
  /// \param N Number of variables.
  explicit OMPFirstprivateClause(unsigned N)
      : OMPVarListClause<OMPFirstprivateClause>(
            llvm::omp::OMPC_firstprivate, SourceLocation(), SourceLocation(),
            SourceLocation(), N),
        OMPClauseWithPreInit(this) {}

  /// Sets the list of references to private copies with initializers for
  /// new private variables.
  /// \param VL List of references.
  void setPrivateCopies(ArrayRef<Expr *> VL);

  /// Gets the list of references to private copies with initializers for
  /// new private variables.
  MutableArrayRef<Expr *> getPrivateCopies() {
    return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
  }
  ArrayRef<const Expr *> getPrivateCopies() const {
    return llvm::makeArrayRef(varlist_end(), varlist_size());
  }

  /// Sets the list of references to initializer variables for new
  /// private variables.
  /// \param VL List of references.
  void setInits(ArrayRef<Expr *> VL);

  /// Gets the list of references to initializer variables for new
  /// private variables.
  MutableArrayRef<Expr *> getInits() {
    return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size());
  }
  ArrayRef<const Expr *> getInits() const {
    return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size());
  }

public:
  /// Creates clause with a list of variables \a VL.
  ///
  /// \param C AST context.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param VL List of references to the original variables.
  /// \param PrivateVL List of references to private copies with initializers.
  /// \param InitVL List of references to auto generated variables used for
  /// initialization of a single array element. Used if firstprivate variable is
  /// of array type.
  /// \param PreInit Statement that must be executed before entering the OpenMP
  /// region with this clause.
  static OMPFirstprivateClause *
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
         SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,
         ArrayRef<Expr *> InitVL, Stmt *PreInit);

  /// Creates an empty clause with the place for \a N variables.
  ///
  /// \param C AST context.
  /// \param N The number of variables.
  static OMPFirstprivateClause *CreateEmpty(const ASTContext &C, unsigned N);

  using private_copies_iterator = MutableArrayRef<Expr *>::iterator;
  using private_copies_const_iterator = ArrayRef<const Expr *>::iterator;
  using private_copies_range = llvm::iterator_range<private_copies_iterator>;
  using private_copies_const_range =
      llvm::iterator_range<private_copies_const_iterator>;

  private_copies_range private_copies() {
    return private_copies_range(getPrivateCopies().begin(),
                                getPrivateCopies().end());
  }
  private_copies_const_range private_copies() const {
    return private_copies_const_range(getPrivateCopies().begin(),
                                      getPrivateCopies().end());
  }

  using inits_iterator = MutableArrayRef<Expr *>::iterator;
  using inits_const_iterator = ArrayRef<const Expr *>::iterator;
  using inits_range = llvm::iterator_range<inits_iterator>;
  using inits_const_range = llvm::iterator_range<inits_const_iterator>;

  inits_range inits() {
    return inits_range(getInits().begin(), getInits().end());
  }
  inits_const_range inits() const {
    return inits_const_range(getInits().begin(), getInits().end());
  }

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPFirstprivateClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }
  const_child_range used_children() const {
    auto Children = const_cast<OMPFirstprivateClause *>(this)->used_children();
    return const_child_range(Children.begin(), Children.end());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_firstprivate;
  }
};

/// This represents clause 'lastprivate' in the '#pragma omp ...'
/// directives.
///
/// \code
/// #pragma omp simd lastprivate(a,b)
/// \endcode
/// In this example directive '#pragma omp simd' has clause 'lastprivate'
/// with the variables 'a' and 'b'.
class OMPLastprivateClause final
    : public OMPVarListClause<OMPLastprivateClause>,
      public OMPClauseWithPostUpdate,
      private llvm::TrailingObjects<OMPLastprivateClause, Expr *> {
  // There are 4 additional tail-allocated arrays at the end of the class:
  // 1. Contains list of pseudo variables with the default initialization for
  // each non-firstprivate variables. Used in codegen for initialization of
  // lastprivate copies.
  // 2. List of helper expressions for proper generation of assignment operation
  // required for lastprivate clause. This list represents private variables
  // (for arrays, single array element).
  // 3. List of helper expressions for proper generation of assignment operation
  // required for lastprivate clause. This list represents original variables
  // (for arrays, single array element).
  // 4. List of helper expressions that represents assignment operation:
  // \code
  // DstExprs = SrcExprs;
  // \endcode
  // Required for proper codegen of final assignment performed by the
  // lastprivate clause.
  friend class OMPClauseReader;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Optional lastprivate kind, e.g. 'conditional', if specified by user.
  OpenMPLastprivateModifier LPKind;
  /// Optional location of the lasptrivate kind, if specified by user.
  SourceLocation LPKindLoc;
  /// Optional colon location, if specified by user.
  SourceLocation ColonLoc;

  /// Build clause with number of variables \a N.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param N Number of the variables in the clause.
  OMPLastprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                       SourceLocation EndLoc, OpenMPLastprivateModifier LPKind,
                       SourceLocation LPKindLoc, SourceLocation ColonLoc,
                       unsigned N)
      : OMPVarListClause<OMPLastprivateClause>(llvm::omp::OMPC_lastprivate,
                                               StartLoc, LParenLoc, EndLoc, N),
        OMPClauseWithPostUpdate(this), LPKind(LPKind), LPKindLoc(LPKindLoc),
        ColonLoc(ColonLoc) {}

  /// Build an empty clause.
  ///
  /// \param N Number of variables.
  explicit OMPLastprivateClause(unsigned N)
      : OMPVarListClause<OMPLastprivateClause>(
            llvm::omp::OMPC_lastprivate, SourceLocation(), SourceLocation(),
            SourceLocation(), N),
        OMPClauseWithPostUpdate(this) {}

  /// Get the list of helper expressions for initialization of private
  /// copies for lastprivate variables.
  MutableArrayRef<Expr *> getPrivateCopies() {
    return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
  }
  ArrayRef<const Expr *> getPrivateCopies() const {
    return llvm::makeArrayRef(varlist_end(), varlist_size());
  }

  /// Set list of helper expressions, required for proper codegen of the
  /// clause. These expressions represent private variables (for arrays, single
  /// array element) in the final assignment statement performed by the
  /// lastprivate clause.
  void setSourceExprs(ArrayRef<Expr *> SrcExprs);

  /// Get the list of helper source expressions.
  MutableArrayRef<Expr *> getSourceExprs() {
    return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size());
  }
  ArrayRef<const Expr *> getSourceExprs() const {
    return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size());
  }

  /// Set list of helper expressions, required for proper codegen of the
  /// clause. These expressions represent original variables (for arrays, single
  /// array element) in the final assignment statement performed by the
  /// lastprivate clause.
  void setDestinationExprs(ArrayRef<Expr *> DstExprs);

  /// Get the list of helper destination expressions.
  MutableArrayRef<Expr *> getDestinationExprs() {
    return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size());
  }
  ArrayRef<const Expr *> getDestinationExprs() const {
    return llvm::makeArrayRef(getSourceExprs().end(), varlist_size());
  }

  /// Set list of helper assignment expressions, required for proper
  /// codegen of the clause. These expressions are assignment expressions that
  /// assign private copy of the variable to original variable.
  void setAssignmentOps(ArrayRef<Expr *> AssignmentOps);

  /// Get the list of helper assignment expressions.
  MutableArrayRef<Expr *> getAssignmentOps() {
    return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size());
  }
  ArrayRef<const Expr *> getAssignmentOps() const {
    return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size());
  }

  /// Sets lastprivate kind.
  void setKind(OpenMPLastprivateModifier Kind) { LPKind = Kind; }
  /// Sets location of the lastprivate kind.
  void setKindLoc(SourceLocation Loc) { LPKindLoc = Loc; }
  /// Sets colon symbol location.
  void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }

public:
  /// Creates clause with a list of variables \a VL.
  ///
  /// \param C AST context.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param VL List of references to the variables.
  /// \param SrcExprs List of helper expressions for proper generation of
  /// assignment operation required for lastprivate clause. This list represents
  /// private variables (for arrays, single array element).
  /// \param DstExprs List of helper expressions for proper generation of
  /// assignment operation required for lastprivate clause. This list represents
  /// original variables (for arrays, single array element).
  /// \param AssignmentOps List of helper expressions that represents assignment
  /// operation:
  /// \code
  /// DstExprs = SrcExprs;
  /// \endcode
  /// Required for proper codegen of final assignment performed by the
  /// lastprivate clause.
  /// \param LPKind Lastprivate kind, e.g. 'conditional'.
  /// \param LPKindLoc Location of the lastprivate kind.
  /// \param ColonLoc Location of the ':' symbol if lastprivate kind is used.
  /// \param PreInit Statement that must be executed before entering the OpenMP
  /// region with this clause.
  /// \param PostUpdate Expression that must be executed after exit from the
  /// OpenMP region with this clause.
  static OMPLastprivateClause *
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
         SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
         ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps,
         OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc,
         SourceLocation ColonLoc, Stmt *PreInit, Expr *PostUpdate);

  /// Creates an empty clause with the place for \a N variables.
  ///
  /// \param C AST context.
  /// \param N The number of variables.
  static OMPLastprivateClause *CreateEmpty(const ASTContext &C, unsigned N);

  /// Lastprivate kind.
  OpenMPLastprivateModifier getKind() const { return LPKind; }
  /// Returns the location of the lastprivate kind.
  SourceLocation getKindLoc() const { return LPKindLoc; }
  /// Returns the location of the ':' symbol, if any.
  SourceLocation getColonLoc() const { return ColonLoc; }

  using helper_expr_iterator = MutableArrayRef<Expr *>::iterator;
  using helper_expr_const_iterator = ArrayRef<const Expr *>::iterator;
  using helper_expr_range = llvm::iterator_range<helper_expr_iterator>;
  using helper_expr_const_range =
      llvm::iterator_range<helper_expr_const_iterator>;

  /// Set list of helper expressions, required for generation of private
  /// copies of original lastprivate variables.
  void setPrivateCopies(ArrayRef<Expr *> PrivateCopies);

  helper_expr_const_range private_copies() const {
    return helper_expr_const_range(getPrivateCopies().begin(),
                                   getPrivateCopies().end());
  }

  helper_expr_range private_copies() {
    return helper_expr_range(getPrivateCopies().begin(),
                             getPrivateCopies().end());
  }

  helper_expr_const_range source_exprs() const {
    return helper_expr_const_range(getSourceExprs().begin(),
                                   getSourceExprs().end());
  }

  helper_expr_range source_exprs() {
    return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end());
  }

  helper_expr_const_range destination_exprs() const {
    return helper_expr_const_range(getDestinationExprs().begin(),
                                   getDestinationExprs().end());
  }

  helper_expr_range destination_exprs() {
    return helper_expr_range(getDestinationExprs().begin(),
                             getDestinationExprs().end());
  }

  helper_expr_const_range assignment_ops() const {
    return helper_expr_const_range(getAssignmentOps().begin(),
                                   getAssignmentOps().end());
  }

  helper_expr_range assignment_ops() {
    return helper_expr_range(getAssignmentOps().begin(),
                             getAssignmentOps().end());
  }

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPLastprivateClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_lastprivate;
  }
};

/// This represents clause 'shared' in the '#pragma omp ...' directives.
///
/// \code
/// #pragma omp parallel shared(a,b)
/// \endcode
/// In this example directive '#pragma omp parallel' has clause 'shared'
/// with the variables 'a' and 'b'.
class OMPSharedClause final
    : public OMPVarListClause<OMPSharedClause>,
      private llvm::TrailingObjects<OMPSharedClause, Expr *> {
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Build clause with number of variables \a N.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param N Number of the variables in the clause.
  OMPSharedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                  SourceLocation EndLoc, unsigned N)
      : OMPVarListClause<OMPSharedClause>(llvm::omp::OMPC_shared, StartLoc,
                                          LParenLoc, EndLoc, N) {}

  /// Build an empty clause.
  ///
  /// \param N Number of variables.
  explicit OMPSharedClause(unsigned N)
      : OMPVarListClause<OMPSharedClause>(llvm::omp::OMPC_shared,
                                          SourceLocation(), SourceLocation(),
                                          SourceLocation(), N) {}

public:
  /// Creates clause with a list of variables \a VL.
  ///
  /// \param C AST context.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param VL List of references to the variables.
  static OMPSharedClause *Create(const ASTContext &C, SourceLocation StartLoc,
                                 SourceLocation LParenLoc,
                                 SourceLocation EndLoc, ArrayRef<Expr *> VL);

  /// Creates an empty clause with \a N variables.
  ///
  /// \param C AST context.
  /// \param N The number of variables.
  static OMPSharedClause *CreateEmpty(const ASTContext &C, unsigned N);

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPSharedClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_shared;
  }
};

/// This represents clause 'reduction' in the '#pragma omp ...'
/// directives.
///
/// \code
/// #pragma omp parallel reduction(+:a,b)
/// \endcode
/// In this example directive '#pragma omp parallel' has clause 'reduction'
/// with operator '+' and the variables 'a' and 'b'.
class OMPReductionClause final
    : public OMPVarListClause<OMPReductionClause>,
      public OMPClauseWithPostUpdate,
      private llvm::TrailingObjects<OMPReductionClause, Expr *> {
  friend class OMPClauseReader;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Reduction modifier.
  OpenMPReductionClauseModifier Modifier = OMPC_REDUCTION_unknown;

  /// Reduction modifier location.
  SourceLocation ModifierLoc;

  /// Location of ':'.
  SourceLocation ColonLoc;

  /// Nested name specifier for C++.
  NestedNameSpecifierLoc QualifierLoc;

  /// Name of custom operator.
  DeclarationNameInfo NameInfo;

  /// Build clause with number of variables \a N.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param ModifierLoc Modifier location.
  /// \param ColonLoc Location of ':'.
  /// \param EndLoc Ending location of the clause.
  /// \param N Number of the variables in the clause.
  /// \param QualifierLoc The nested-name qualifier with location information
  /// \param NameInfo The full name info for reduction identifier.
  OMPReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                     SourceLocation ModifierLoc, SourceLocation ColonLoc,
                     SourceLocation EndLoc,
                     OpenMPReductionClauseModifier Modifier, unsigned N,
                     NestedNameSpecifierLoc QualifierLoc,
                     const DeclarationNameInfo &NameInfo)
      : OMPVarListClause<OMPReductionClause>(llvm::omp::OMPC_reduction,
                                             StartLoc, LParenLoc, EndLoc, N),
        OMPClauseWithPostUpdate(this), Modifier(Modifier),
        ModifierLoc(ModifierLoc), ColonLoc(ColonLoc),
        QualifierLoc(QualifierLoc), NameInfo(NameInfo) {}

  /// Build an empty clause.
  ///
  /// \param N Number of variables.
  explicit OMPReductionClause(unsigned N)
      : OMPVarListClause<OMPReductionClause>(llvm::omp::OMPC_reduction,
                                             SourceLocation(), SourceLocation(),
                                             SourceLocation(), N),
        OMPClauseWithPostUpdate(this) {}

  /// Sets reduction modifier.
  void setModifier(OpenMPReductionClauseModifier M) { Modifier = M; }

  /// Sets location of the modifier.
  void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; }

  /// Sets location of ':' symbol in clause.
  void setColonLoc(SourceLocation CL) { ColonLoc = CL; }

  /// Sets the name info for specified reduction identifier.
  void setNameInfo(DeclarationNameInfo DNI) { NameInfo = DNI; }

  /// Sets the nested name specifier.
  void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc = NSL; }

  /// Set list of helper expressions, required for proper codegen of the
  /// clause. These expressions represent private copy of the reduction
  /// variable.
  void setPrivates(ArrayRef<Expr *> Privates);

  /// Get the list of helper privates.
  MutableArrayRef<Expr *> getPrivates() {
    return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
  }
  ArrayRef<const Expr *> getPrivates() const {
    return llvm::makeArrayRef(varlist_end(), varlist_size());
  }

  /// Set list of helper expressions, required for proper codegen of the
  /// clause. These expressions represent LHS expression in the final
  /// reduction expression performed by the reduction clause.
  void setLHSExprs(ArrayRef<Expr *> LHSExprs);

  /// Get the list of helper LHS expressions.
  MutableArrayRef<Expr *> getLHSExprs() {
    return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size());
  }
  ArrayRef<const Expr *> getLHSExprs() const {
    return llvm::makeArrayRef(getPrivates().end(), varlist_size());
  }

  /// Set list of helper expressions, required for proper codegen of the
  /// clause. These expressions represent RHS expression in the final
  /// reduction expression performed by the reduction clause.
  /// Also, variables in these expressions are used for proper initialization of
  /// reduction copies.
  void setRHSExprs(ArrayRef<Expr *> RHSExprs);

  /// Get the list of helper destination expressions.
  MutableArrayRef<Expr *> getRHSExprs() {
    return MutableArrayRef<Expr *>(getLHSExprs().end(), varlist_size());
  }
  ArrayRef<const Expr *> getRHSExprs() const {
    return llvm::makeArrayRef(getLHSExprs().end(), varlist_size());
  }

  /// Set list of helper reduction expressions, required for proper
  /// codegen of the clause. These expressions are binary expressions or
  /// operator/custom reduction call that calculates new value from source
  /// helper expressions to destination helper expressions.
  void setReductionOps(ArrayRef<Expr *> ReductionOps);

  /// Get the list of helper reduction expressions.
  MutableArrayRef<Expr *> getReductionOps() {
    return MutableArrayRef<Expr *>(getRHSExprs().end(), varlist_size());
  }
  ArrayRef<const Expr *> getReductionOps() const {
    return llvm::makeArrayRef(getRHSExprs().end(), varlist_size());
  }

  /// Set list of helper copy operations for inscan reductions.
  /// The form is: Temps[i] = LHS[i];
  void setInscanCopyOps(ArrayRef<Expr *> Ops);

  /// Get the list of helper inscan copy operations.
  MutableArrayRef<Expr *> getInscanCopyOps() {
    return MutableArrayRef<Expr *>(getReductionOps().end(), varlist_size());
  }
  ArrayRef<const Expr *> getInscanCopyOps() const {
    return llvm::makeArrayRef(getReductionOps().end(), varlist_size());
  }

  /// Set list of helper temp vars for inscan copy array operations.
  void setInscanCopyArrayTemps(ArrayRef<Expr *> CopyArrayTemps);

  /// Get the list of helper inscan copy temps.
  MutableArrayRef<Expr *> getInscanCopyArrayTemps() {
    return MutableArrayRef<Expr *>(getInscanCopyOps().end(), varlist_size());
  }
  ArrayRef<const Expr *> getInscanCopyArrayTemps() const {
    return llvm::makeArrayRef(getInscanCopyOps().end(), varlist_size());
  }

  /// Set list of helper temp elements vars for inscan copy array operations.
  void setInscanCopyArrayElems(ArrayRef<Expr *> CopyArrayElems);

  /// Get the list of helper inscan copy temps.
  MutableArrayRef<Expr *> getInscanCopyArrayElems() {
    return MutableArrayRef<Expr *>(getInscanCopyArrayTemps().end(),
                                   varlist_size());
  }
  ArrayRef<const Expr *> getInscanCopyArrayElems() const {
    return llvm::makeArrayRef(getInscanCopyArrayTemps().end(), varlist_size());
  }

public:
  /// Creates clause with a list of variables \a VL.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param ModifierLoc Modifier location.
  /// \param ColonLoc Location of ':'.
  /// \param EndLoc Ending location of the clause.
  /// \param VL The variables in the clause.
  /// \param QualifierLoc The nested-name qualifier with location information
  /// \param NameInfo The full name info for reduction identifier.
  /// \param Privates List of helper expressions for proper generation of
  /// private copies.
  /// \param LHSExprs List of helper expressions for proper generation of
  /// assignment operation required for copyprivate clause. This list represents
  /// LHSs of the reduction expressions.
  /// \param RHSExprs List of helper expressions for proper generation of
  /// assignment operation required for copyprivate clause. This list represents
  /// RHSs of the reduction expressions.
  /// Also, variables in these expressions are used for proper initialization of
  /// reduction copies.
  /// \param ReductionOps List of helper expressions that represents reduction
  /// expressions:
  /// \code
  /// LHSExprs binop RHSExprs;
  /// operator binop(LHSExpr, RHSExpr);
  /// <CutomReduction>(LHSExpr, RHSExpr);
  /// \endcode
  /// Required for proper codegen of final reduction operation performed by the
  /// reduction clause.
  /// \param CopyOps List of copy operations for inscan reductions:
  /// \code
  /// TempExprs = LHSExprs;
  /// \endcode
  /// \param CopyArrayTemps Temp arrays for prefix sums.
  /// \param CopyArrayElems Temp arrays for prefix sums.
  /// \param PreInit Statement that must be executed before entering the OpenMP
  /// region with this clause.
  /// \param PostUpdate Expression that must be executed after exit from the
  /// OpenMP region with this clause.
  static OMPReductionClause *
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
         SourceLocation ModifierLoc, SourceLocation ColonLoc,
         SourceLocation EndLoc, OpenMPReductionClauseModifier Modifier,
         ArrayRef<Expr *> VL, NestedNameSpecifierLoc QualifierLoc,
         const DeclarationNameInfo &NameInfo, ArrayRef<Expr *> Privates,
         ArrayRef<Expr *> LHSExprs, ArrayRef<Expr *> RHSExprs,
         ArrayRef<Expr *> ReductionOps, ArrayRef<Expr *> CopyOps,
         ArrayRef<Expr *> CopyArrayTemps, ArrayRef<Expr *> CopyArrayElems,
         Stmt *PreInit, Expr *PostUpdate);

  /// Creates an empty clause with the place for \a N variables.
  ///
  /// \param C AST context.
  /// \param N The number of variables.
  /// \param Modifier Reduction modifier.
  static OMPReductionClause *
  CreateEmpty(const ASTContext &C, unsigned N,
              OpenMPReductionClauseModifier Modifier);

  /// Returns modifier.
  OpenMPReductionClauseModifier getModifier() const { return Modifier; }

  /// Returns modifier location.
  SourceLocation getModifierLoc() const { return ModifierLoc; }

  /// Gets location of ':' symbol in clause.
  SourceLocation getColonLoc() const { return ColonLoc; }

  /// Gets the name info for specified reduction identifier.
  const DeclarationNameInfo &getNameInfo() const { return NameInfo; }

  /// Gets the nested name specifier.
  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }

  using helper_expr_iterator = MutableArrayRef<Expr *>::iterator;
  using helper_expr_const_iterator = ArrayRef<const Expr *>::iterator;
  using helper_expr_range = llvm::iterator_range<helper_expr_iterator>;
  using helper_expr_const_range =
      llvm::iterator_range<helper_expr_const_iterator>;

  helper_expr_const_range privates() const {
    return helper_expr_const_range(getPrivates().begin(), getPrivates().end());
  }

  helper_expr_range privates() {
    return helper_expr_range(getPrivates().begin(), getPrivates().end());
  }

  helper_expr_const_range lhs_exprs() const {
    return helper_expr_const_range(getLHSExprs().begin(), getLHSExprs().end());
  }

  helper_expr_range lhs_exprs() {
    return helper_expr_range(getLHSExprs().begin(), getLHSExprs().end());
  }

  helper_expr_const_range rhs_exprs() const {
    return helper_expr_const_range(getRHSExprs().begin(), getRHSExprs().end());
  }

  helper_expr_range rhs_exprs() {
    return helper_expr_range(getRHSExprs().begin(), getRHSExprs().end());
  }

  helper_expr_const_range reduction_ops() const {
    return helper_expr_const_range(getReductionOps().begin(),
                                   getReductionOps().end());
  }

  helper_expr_range reduction_ops() {
    return helper_expr_range(getReductionOps().begin(),
                             getReductionOps().end());
  }

  helper_expr_const_range copy_ops() const {
    return helper_expr_const_range(getInscanCopyOps().begin(),
                                   getInscanCopyOps().end());
  }

  helper_expr_range copy_ops() {
    return helper_expr_range(getInscanCopyOps().begin(),
                             getInscanCopyOps().end());
  }

  helper_expr_const_range copy_array_temps() const {
    return helper_expr_const_range(getInscanCopyArrayTemps().begin(),
                                   getInscanCopyArrayTemps().end());
  }

  helper_expr_range copy_array_temps() {
    return helper_expr_range(getInscanCopyArrayTemps().begin(),
                             getInscanCopyArrayTemps().end());
  }

  helper_expr_const_range copy_array_elems() const {
    return helper_expr_const_range(getInscanCopyArrayElems().begin(),
                                   getInscanCopyArrayElems().end());
  }

  helper_expr_range copy_array_elems() {
    return helper_expr_range(getInscanCopyArrayElems().begin(),
                             getInscanCopyArrayElems().end());
  }

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPReductionClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }
  const_child_range used_children() const {
    auto Children = const_cast<OMPReductionClause *>(this)->used_children();
    return const_child_range(Children.begin(), Children.end());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_reduction;
  }
};

/// This represents clause 'task_reduction' in the '#pragma omp taskgroup'
/// directives.
///
/// \code
/// #pragma omp taskgroup task_reduction(+:a,b)
/// \endcode
/// In this example directive '#pragma omp taskgroup' has clause
/// 'task_reduction' with operator '+' and the variables 'a' and 'b'.
class OMPTaskReductionClause final
    : public OMPVarListClause<OMPTaskReductionClause>,
      public OMPClauseWithPostUpdate,
      private llvm::TrailingObjects<OMPTaskReductionClause, Expr *> {
  friend class OMPClauseReader;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Location of ':'.
  SourceLocation ColonLoc;

  /// Nested name specifier for C++.
  NestedNameSpecifierLoc QualifierLoc;

  /// Name of custom operator.
  DeclarationNameInfo NameInfo;

  /// Build clause with number of variables \a N.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param ColonLoc Location of ':'.
  /// \param N Number of the variables in the clause.
  /// \param QualifierLoc The nested-name qualifier with location information
  /// \param NameInfo The full name info for reduction identifier.
  OMPTaskReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                         SourceLocation ColonLoc, SourceLocation EndLoc,
                         unsigned N, NestedNameSpecifierLoc QualifierLoc,
                         const DeclarationNameInfo &NameInfo)
      : OMPVarListClause<OMPTaskReductionClause>(
            llvm::omp::OMPC_task_reduction, StartLoc, LParenLoc, EndLoc, N),
        OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc),
        QualifierLoc(QualifierLoc), NameInfo(NameInfo) {}

  /// Build an empty clause.
  ///
  /// \param N Number of variables.
  explicit OMPTaskReductionClause(unsigned N)
      : OMPVarListClause<OMPTaskReductionClause>(
            llvm::omp::OMPC_task_reduction, SourceLocation(), SourceLocation(),
            SourceLocation(), N),
        OMPClauseWithPostUpdate(this) {}

  /// Sets location of ':' symbol in clause.
  void setColonLoc(SourceLocation CL) { ColonLoc = CL; }

  /// Sets the name info for specified reduction identifier.
  void setNameInfo(DeclarationNameInfo DNI) { NameInfo = DNI; }

  /// Sets the nested name specifier.
  void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc = NSL; }

  /// Set list of helper expressions, required for proper codegen of the clause.
  /// These expressions represent private copy of the reduction variable.
  void setPrivates(ArrayRef<Expr *> Privates);

  /// Get the list of helper privates.
  MutableArrayRef<Expr *> getPrivates() {
    return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
  }
  ArrayRef<const Expr *> getPrivates() const {
    return llvm::makeArrayRef(varlist_end(), varlist_size());
  }

  /// Set list of helper expressions, required for proper codegen of the clause.
  /// These expressions represent LHS expression in the final reduction
  /// expression performed by the reduction clause.
  void setLHSExprs(ArrayRef<Expr *> LHSExprs);

  /// Get the list of helper LHS expressions.
  MutableArrayRef<Expr *> getLHSExprs() {
    return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size());
  }
  ArrayRef<const Expr *> getLHSExprs() const {
    return llvm::makeArrayRef(getPrivates().end(), varlist_size());
  }

  /// Set list of helper expressions, required for proper codegen of the clause.
  /// These expressions represent RHS expression in the final reduction
  /// expression performed by the reduction clause. Also, variables in these
  /// expressions are used for proper initialization of reduction copies.
  void setRHSExprs(ArrayRef<Expr *> RHSExprs);

  ///  Get the list of helper destination expressions.
  MutableArrayRef<Expr *> getRHSExprs() {
    return MutableArrayRef<Expr *>(getLHSExprs().end(), varlist_size());
  }
  ArrayRef<const Expr *> getRHSExprs() const {
    return llvm::makeArrayRef(getLHSExprs().end(), varlist_size());
  }

  /// Set list of helper reduction expressions, required for proper
  /// codegen of the clause. These expressions are binary expressions or
  /// operator/custom reduction call that calculates new value from source
  /// helper expressions to destination helper expressions.
  void setReductionOps(ArrayRef<Expr *> ReductionOps);

  ///  Get the list of helper reduction expressions.
  MutableArrayRef<Expr *> getReductionOps() {
    return MutableArrayRef<Expr *>(getRHSExprs().end(), varlist_size());
  }
  ArrayRef<const Expr *> getReductionOps() const {
    return llvm::makeArrayRef(getRHSExprs().end(), varlist_size());
  }

public:
  /// Creates clause with a list of variables \a VL.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param ColonLoc Location of ':'.
  /// \param EndLoc Ending location of the clause.
  /// \param VL The variables in the clause.
  /// \param QualifierLoc The nested-name qualifier with location information
  /// \param NameInfo The full name info for reduction identifier.
  /// \param Privates List of helper expressions for proper generation of
  /// private copies.
  /// \param LHSExprs List of helper expressions for proper generation of
  /// assignment operation required for copyprivate clause. This list represents
  /// LHSs of the reduction expressions.
  /// \param RHSExprs List of helper expressions for proper generation of
  /// assignment operation required for copyprivate clause. This list represents
  /// RHSs of the reduction expressions.
  /// Also, variables in these expressions are used for proper initialization of
  /// reduction copies.
  /// \param ReductionOps List of helper expressions that represents reduction
  /// expressions:
  /// \code
  /// LHSExprs binop RHSExprs;
  /// operator binop(LHSExpr, RHSExpr);
  /// <CutomReduction>(LHSExpr, RHSExpr);
  /// \endcode
  /// Required for proper codegen of final reduction operation performed by the
  /// reduction clause.
  /// \param PreInit Statement that must be executed before entering the OpenMP
  /// region with this clause.
  /// \param PostUpdate Expression that must be executed after exit from the
  /// OpenMP region with this clause.
  static OMPTaskReductionClause *
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
         SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
         NestedNameSpecifierLoc QualifierLoc,
         const DeclarationNameInfo &NameInfo, ArrayRef<Expr *> Privates,
         ArrayRef<Expr *> LHSExprs, ArrayRef<Expr *> RHSExprs,
         ArrayRef<Expr *> ReductionOps, Stmt *PreInit, Expr *PostUpdate);

  /// Creates an empty clause with the place for \a N variables.
  ///
  /// \param C AST context.
  /// \param N The number of variables.
  static OMPTaskReductionClause *CreateEmpty(const ASTContext &C, unsigned N);

  /// Gets location of ':' symbol in clause.
  SourceLocation getColonLoc() const { return ColonLoc; }

  /// Gets the name info for specified reduction identifier.
  const DeclarationNameInfo &getNameInfo() const { return NameInfo; }

  /// Gets the nested name specifier.
  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }

  using helper_expr_iterator = MutableArrayRef<Expr *>::iterator;
  using helper_expr_const_iterator = ArrayRef<const Expr *>::iterator;
  using helper_expr_range = llvm::iterator_range<helper_expr_iterator>;
  using helper_expr_const_range =
      llvm::iterator_range<helper_expr_const_iterator>;

  helper_expr_const_range privates() const {
    return helper_expr_const_range(getPrivates().begin(), getPrivates().end());
  }

  helper_expr_range privates() {
    return helper_expr_range(getPrivates().begin(), getPrivates().end());
  }

  helper_expr_const_range lhs_exprs() const {
    return helper_expr_const_range(getLHSExprs().begin(), getLHSExprs().end());
  }

  helper_expr_range lhs_exprs() {
    return helper_expr_range(getLHSExprs().begin(), getLHSExprs().end());
  }

  helper_expr_const_range rhs_exprs() const {
    return helper_expr_const_range(getRHSExprs().begin(), getRHSExprs().end());
  }

  helper_expr_range rhs_exprs() {
    return helper_expr_range(getRHSExprs().begin(), getRHSExprs().end());
  }

  helper_expr_const_range reduction_ops() const {
    return helper_expr_const_range(getReductionOps().begin(),
                                   getReductionOps().end());
  }

  helper_expr_range reduction_ops() {
    return helper_expr_range(getReductionOps().begin(),
                             getReductionOps().end());
  }

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPTaskReductionClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_task_reduction;
  }
};

/// This represents clause 'in_reduction' in the '#pragma omp task' directives.
///
/// \code
/// #pragma omp task in_reduction(+:a,b)
/// \endcode
/// In this example directive '#pragma omp task' has clause 'in_reduction' with
/// operator '+' and the variables 'a' and 'b'.
class OMPInReductionClause final
    : public OMPVarListClause<OMPInReductionClause>,
      public OMPClauseWithPostUpdate,
      private llvm::TrailingObjects<OMPInReductionClause, Expr *> {
  friend class OMPClauseReader;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Location of ':'.
  SourceLocation ColonLoc;

  /// Nested name specifier for C++.
  NestedNameSpecifierLoc QualifierLoc;

  /// Name of custom operator.
  DeclarationNameInfo NameInfo;

  /// Build clause with number of variables \a N.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param ColonLoc Location of ':'.
  /// \param N Number of the variables in the clause.
  /// \param QualifierLoc The nested-name qualifier with location information
  /// \param NameInfo The full name info for reduction identifier.
  OMPInReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                       SourceLocation ColonLoc, SourceLocation EndLoc,
                       unsigned N, NestedNameSpecifierLoc QualifierLoc,
                       const DeclarationNameInfo &NameInfo)
      : OMPVarListClause<OMPInReductionClause>(llvm::omp::OMPC_in_reduction,
                                               StartLoc, LParenLoc, EndLoc, N),
        OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc),
        QualifierLoc(QualifierLoc), NameInfo(NameInfo) {}

  /// Build an empty clause.
  ///
  /// \param N Number of variables.
  explicit OMPInReductionClause(unsigned N)
      : OMPVarListClause<OMPInReductionClause>(
            llvm::omp::OMPC_in_reduction, SourceLocation(), SourceLocation(),
            SourceLocation(), N),
        OMPClauseWithPostUpdate(this) {}

  /// Sets location of ':' symbol in clause.
  void setColonLoc(SourceLocation CL) { ColonLoc = CL; }

  /// Sets the name info for specified reduction identifier.
  void setNameInfo(DeclarationNameInfo DNI) { NameInfo = DNI; }

  /// Sets the nested name specifier.
  void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc = NSL; }

  /// Set list of helper expressions, required for proper codegen of the clause.
  /// These expressions represent private copy of the reduction variable.
  void setPrivates(ArrayRef<Expr *> Privates);

  /// Get the list of helper privates.
  MutableArrayRef<Expr *> getPrivates() {
    return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
  }
  ArrayRef<const Expr *> getPrivates() const {
    return llvm::makeArrayRef(varlist_end(), varlist_size());
  }

  /// Set list of helper expressions, required for proper codegen of the clause.
  /// These expressions represent LHS expression in the final reduction
  /// expression performed by the reduction clause.
  void setLHSExprs(ArrayRef<Expr *> LHSExprs);

  /// Get the list of helper LHS expressions.
  MutableArrayRef<Expr *> getLHSExprs() {
    return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size());
  }
  ArrayRef<const Expr *> getLHSExprs() const {
    return llvm::makeArrayRef(getPrivates().end(), varlist_size());
  }

  /// Set list of helper expressions, required for proper codegen of the clause.
  /// These expressions represent RHS expression in the final reduction
  /// expression performed by the reduction clause. Also, variables in these
  /// expressions are used for proper initialization of reduction copies.
  void setRHSExprs(ArrayRef<Expr *> RHSExprs);

  ///  Get the list of helper destination expressions.
  MutableArrayRef<Expr *> getRHSExprs() {
    return MutableArrayRef<Expr *>(getLHSExprs().end(), varlist_size());
  }
  ArrayRef<const Expr *> getRHSExprs() const {
    return llvm::makeArrayRef(getLHSExprs().end(), varlist_size());
  }

  /// Set list of helper reduction expressions, required for proper
  /// codegen of the clause. These expressions are binary expressions or
  /// operator/custom reduction call that calculates new value from source
  /// helper expressions to destination helper expressions.
  void setReductionOps(ArrayRef<Expr *> ReductionOps);

  ///  Get the list of helper reduction expressions.
  MutableArrayRef<Expr *> getReductionOps() {
    return MutableArrayRef<Expr *>(getRHSExprs().end(), varlist_size());
  }
  ArrayRef<const Expr *> getReductionOps() const {
    return llvm::makeArrayRef(getRHSExprs().end(), varlist_size());
  }

  /// Set list of helper reduction taskgroup descriptors.
  void setTaskgroupDescriptors(ArrayRef<Expr *> ReductionOps);

  ///  Get the list of helper reduction taskgroup descriptors.
  MutableArrayRef<Expr *> getTaskgroupDescriptors() {
    return MutableArrayRef<Expr *>(getReductionOps().end(), varlist_size());
  }
  ArrayRef<const Expr *> getTaskgroupDescriptors() const {
    return llvm::makeArrayRef(getReductionOps().end(), varlist_size());
  }

public:
  /// Creates clause with a list of variables \a VL.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param ColonLoc Location of ':'.
  /// \param EndLoc Ending location of the clause.
  /// \param VL The variables in the clause.
  /// \param QualifierLoc The nested-name qualifier with location information
  /// \param NameInfo The full name info for reduction identifier.
  /// \param Privates List of helper expressions for proper generation of
  /// private copies.
  /// \param LHSExprs List of helper expressions for proper generation of
  /// assignment operation required for copyprivate clause. This list represents
  /// LHSs of the reduction expressions.
  /// \param RHSExprs List of helper expressions for proper generation of
  /// assignment operation required for copyprivate clause. This list represents
  /// RHSs of the reduction expressions.
  /// Also, variables in these expressions are used for proper initialization of
  /// reduction copies.
  /// \param ReductionOps List of helper expressions that represents reduction
  /// expressions:
  /// \code
  /// LHSExprs binop RHSExprs;
  /// operator binop(LHSExpr, RHSExpr);
  /// <CutomReduction>(LHSExpr, RHSExpr);
  /// \endcode
  /// Required for proper codegen of final reduction operation performed by the
  /// reduction clause.
  /// \param TaskgroupDescriptors List of helper taskgroup descriptors for
  /// corresponding items in parent taskgroup task_reduction clause.
  /// \param PreInit Statement that must be executed before entering the OpenMP
  /// region with this clause.
  /// \param PostUpdate Expression that must be executed after exit from the
  /// OpenMP region with this clause.
  static OMPInReductionClause *
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
         SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
         NestedNameSpecifierLoc QualifierLoc,
         const DeclarationNameInfo &NameInfo, ArrayRef<Expr *> Privates,
         ArrayRef<Expr *> LHSExprs, ArrayRef<Expr *> RHSExprs,
         ArrayRef<Expr *> ReductionOps, ArrayRef<Expr *> TaskgroupDescriptors,
         Stmt *PreInit, Expr *PostUpdate);

  /// Creates an empty clause with the place for \a N variables.
  ///
  /// \param C AST context.
  /// \param N The number of variables.
  static OMPInReductionClause *CreateEmpty(const ASTContext &C, unsigned N);

  /// Gets location of ':' symbol in clause.
  SourceLocation getColonLoc() const { return ColonLoc; }

  /// Gets the name info for specified reduction identifier.
  const DeclarationNameInfo &getNameInfo() const { return NameInfo; }

  /// Gets the nested name specifier.
  NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }

  using helper_expr_iterator = MutableArrayRef<Expr *>::iterator;
  using helper_expr_const_iterator = ArrayRef<const Expr *>::iterator;
  using helper_expr_range = llvm::iterator_range<helper_expr_iterator>;
  using helper_expr_const_range =
      llvm::iterator_range<helper_expr_const_iterator>;

  helper_expr_const_range privates() const {
    return helper_expr_const_range(getPrivates().begin(), getPrivates().end());
  }

  helper_expr_range privates() {
    return helper_expr_range(getPrivates().begin(), getPrivates().end());
  }

  helper_expr_const_range lhs_exprs() const {
    return helper_expr_const_range(getLHSExprs().begin(), getLHSExprs().end());
  }

  helper_expr_range lhs_exprs() {
    return helper_expr_range(getLHSExprs().begin(), getLHSExprs().end());
  }

  helper_expr_const_range rhs_exprs() const {
    return helper_expr_const_range(getRHSExprs().begin(), getRHSExprs().end());
  }

  helper_expr_range rhs_exprs() {
    return helper_expr_range(getRHSExprs().begin(), getRHSExprs().end());
  }

  helper_expr_const_range reduction_ops() const {
    return helper_expr_const_range(getReductionOps().begin(),
                                   getReductionOps().end());
  }

  helper_expr_range reduction_ops() {
    return helper_expr_range(getReductionOps().begin(),
                             getReductionOps().end());
  }

  helper_expr_const_range taskgroup_descriptors() const {
    return helper_expr_const_range(getTaskgroupDescriptors().begin(),
                                   getTaskgroupDescriptors().end());
  }

  helper_expr_range taskgroup_descriptors() {
    return helper_expr_range(getTaskgroupDescriptors().begin(),
                             getTaskgroupDescriptors().end());
  }

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPInReductionClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_in_reduction;
  }
};

/// This represents clause 'linear' in the '#pragma omp ...'
/// directives.
///
/// \code
/// #pragma omp simd linear(a,b : 2)
/// \endcode
/// In this example directive '#pragma omp simd' has clause 'linear'
/// with variables 'a', 'b' and linear step '2'.
class OMPLinearClause final
    : public OMPVarListClause<OMPLinearClause>,
      public OMPClauseWithPostUpdate,
      private llvm::TrailingObjects<OMPLinearClause, Expr *> {
  friend class OMPClauseReader;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Modifier of 'linear' clause.
  OpenMPLinearClauseKind Modifier = OMPC_LINEAR_val;

  /// Location of linear modifier if any.
  SourceLocation ModifierLoc;

  /// Location of ':'.
  SourceLocation ColonLoc;

  /// Sets the linear step for clause.
  void setStep(Expr *Step) { *(getFinals().end()) = Step; }

  /// Sets the expression to calculate linear step for clause.
  void setCalcStep(Expr *CalcStep) { *(getFinals().end() + 1) = CalcStep; }

  /// Build 'linear' clause with given number of variables \a NumVars.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param ColonLoc Location of ':'.
  /// \param EndLoc Ending location of the clause.
  /// \param NumVars Number of variables.
  OMPLinearClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                  OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
                  SourceLocation ColonLoc, SourceLocation EndLoc,
                  unsigned NumVars)
      : OMPVarListClause<OMPLinearClause>(llvm::omp::OMPC_linear, StartLoc,
                                          LParenLoc, EndLoc, NumVars),
        OMPClauseWithPostUpdate(this), Modifier(Modifier),
        ModifierLoc(ModifierLoc), ColonLoc(ColonLoc) {}

  /// Build an empty clause.
  ///
  /// \param NumVars Number of variables.
  explicit OMPLinearClause(unsigned NumVars)
      : OMPVarListClause<OMPLinearClause>(llvm::omp::OMPC_linear,
                                          SourceLocation(), SourceLocation(),
                                          SourceLocation(), NumVars),
        OMPClauseWithPostUpdate(this) {}

  /// Gets the list of initial values for linear variables.
  ///
  /// There are NumVars expressions with initial values allocated after the
  /// varlist, they are followed by NumVars update expressions (used to update
  /// the linear variable's value on current iteration) and they are followed by
  /// NumVars final expressions (used to calculate the linear variable's
  /// value after the loop body). After these lists, there are 2 helper
  /// expressions - linear step and a helper to calculate it before the
  /// loop body (used when the linear step is not constant):
  ///
  /// { Vars[] /* in OMPVarListClause */; Privates[]; Inits[]; Updates[];
  /// Finals[]; Step; CalcStep; }
  MutableArrayRef<Expr *> getPrivates() {
    return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
  }
  ArrayRef<const Expr *> getPrivates() const {
    return llvm::makeArrayRef(varlist_end(), varlist_size());
  }

  MutableArrayRef<Expr *> getInits() {
    return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size());
  }
  ArrayRef<const Expr *> getInits() const {
    return llvm::makeArrayRef(getPrivates().end(), varlist_size());
  }

  /// Sets the list of update expressions for linear variables.
  MutableArrayRef<Expr *> getUpdates() {
    return MutableArrayRef<Expr *>(getInits().end(), varlist_size());
  }
  ArrayRef<const Expr *> getUpdates() const {
    return llvm::makeArrayRef(getInits().end(), varlist_size());
  }

  /// Sets the list of final update expressions for linear variables.
  MutableArrayRef<Expr *> getFinals() {
    return MutableArrayRef<Expr *>(getUpdates().end(), varlist_size());
  }
  ArrayRef<const Expr *> getFinals() const {
    return llvm::makeArrayRef(getUpdates().end(), varlist_size());
  }

  /// Gets the list of used expressions for linear variables.
  MutableArrayRef<Expr *> getUsedExprs() {
    return MutableArrayRef<Expr *>(getFinals().end() + 2, varlist_size() + 1);
  }
  ArrayRef<const Expr *> getUsedExprs() const {
    return llvm::makeArrayRef(getFinals().end() + 2, varlist_size() + 1);
  }

  /// Sets the list of the copies of original linear variables.
  /// \param PL List of expressions.
  void setPrivates(ArrayRef<Expr *> PL);

  /// Sets the list of the initial values for linear variables.
  /// \param IL List of expressions.
  void setInits(ArrayRef<Expr *> IL);

public:
  /// Creates clause with a list of variables \a VL and a linear step
  /// \a Step.
  ///
  /// \param C AST Context.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param Modifier Modifier of 'linear' clause.
  /// \param ModifierLoc Modifier location.
  /// \param ColonLoc Location of ':'.
  /// \param EndLoc Ending location of the clause.
  /// \param VL List of references to the variables.
  /// \param PL List of private copies of original variables.
  /// \param IL List of initial values for the variables.
  /// \param Step Linear step.
  /// \param CalcStep Calculation of the linear step.
  /// \param PreInit Statement that must be executed before entering the OpenMP
  /// region with this clause.
  /// \param PostUpdate Expression that must be executed after exit from the
  /// OpenMP region with this clause.
  static OMPLinearClause *
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
         OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
         SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
         ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep,
         Stmt *PreInit, Expr *PostUpdate);

  /// Creates an empty clause with the place for \a NumVars variables.
  ///
  /// \param C AST context.
  /// \param NumVars Number of variables.
  static OMPLinearClause *CreateEmpty(const ASTContext &C, unsigned NumVars);

  /// Set modifier.
  void setModifier(OpenMPLinearClauseKind Kind) { Modifier = Kind; }

  /// Return modifier.
  OpenMPLinearClauseKind getModifier() const { return Modifier; }

  /// Set modifier location.
  void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; }

  /// Return modifier location.
  SourceLocation getModifierLoc() const { return ModifierLoc; }

  /// Sets the location of ':'.
  void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }

  /// Returns the location of ':'.
  SourceLocation getColonLoc() const { return ColonLoc; }

  /// Returns linear step.
  Expr *getStep() { return *(getFinals().end()); }

  /// Returns linear step.
  const Expr *getStep() const { return *(getFinals().end()); }

  /// Returns expression to calculate linear step.
  Expr *getCalcStep() { return *(getFinals().end() + 1); }

  /// Returns expression to calculate linear step.
  const Expr *getCalcStep() const { return *(getFinals().end() + 1); }

  /// Sets the list of update expressions for linear variables.
  /// \param UL List of expressions.
  void setUpdates(ArrayRef<Expr *> UL);

  /// Sets the list of final update expressions for linear variables.
  /// \param FL List of expressions.
  void setFinals(ArrayRef<Expr *> FL);

  /// Sets the list of used expressions for the linear clause.
  void setUsedExprs(ArrayRef<Expr *> UE);

  using privates_iterator = MutableArrayRef<Expr *>::iterator;
  using privates_const_iterator = ArrayRef<const Expr *>::iterator;
  using privates_range = llvm::iterator_range<privates_iterator>;
  using privates_const_range = llvm::iterator_range<privates_const_iterator>;

  privates_range privates() {
    return privates_range(getPrivates().begin(), getPrivates().end());
  }

  privates_const_range privates() const {
    return privates_const_range(getPrivates().begin(), getPrivates().end());
  }

  using inits_iterator = MutableArrayRef<Expr *>::iterator;
  using inits_const_iterator = ArrayRef<const Expr *>::iterator;
  using inits_range = llvm::iterator_range<inits_iterator>;
  using inits_const_range = llvm::iterator_range<inits_const_iterator>;

  inits_range inits() {
    return inits_range(getInits().begin(), getInits().end());
  }

  inits_const_range inits() const {
    return inits_const_range(getInits().begin(), getInits().end());
  }

  using updates_iterator = MutableArrayRef<Expr *>::iterator;
  using updates_const_iterator = ArrayRef<const Expr *>::iterator;
  using updates_range = llvm::iterator_range<updates_iterator>;
  using updates_const_range = llvm::iterator_range<updates_const_iterator>;

  updates_range updates() {
    return updates_range(getUpdates().begin(), getUpdates().end());
  }

  updates_const_range updates() const {
    return updates_const_range(getUpdates().begin(), getUpdates().end());
  }

  using finals_iterator = MutableArrayRef<Expr *>::iterator;
  using finals_const_iterator = ArrayRef<const Expr *>::iterator;
  using finals_range = llvm::iterator_range<finals_iterator>;
  using finals_const_range = llvm::iterator_range<finals_const_iterator>;

  finals_range finals() {
    return finals_range(getFinals().begin(), getFinals().end());
  }

  finals_const_range finals() const {
    return finals_const_range(getFinals().begin(), getFinals().end());
  }

  using used_expressions_iterator = MutableArrayRef<Expr *>::iterator;
  using used_expressions_const_iterator = ArrayRef<const Expr *>::iterator;
  using used_expressions_range =
      llvm::iterator_range<used_expressions_iterator>;
  using used_expressions_const_range =
      llvm::iterator_range<used_expressions_const_iterator>;

  used_expressions_range used_expressions() {
    return finals_range(getUsedExprs().begin(), getUsedExprs().end());
  }

  used_expressions_const_range used_expressions() const {
    return finals_const_range(getUsedExprs().begin(), getUsedExprs().end());
  }

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPLinearClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children();

  const_child_range used_children() const {
    auto Children = const_cast<OMPLinearClause *>(this)->used_children();
    return const_child_range(Children.begin(), Children.end());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_linear;
  }
};

/// This represents clause 'aligned' in the '#pragma omp ...'
/// directives.
///
/// \code
/// #pragma omp simd aligned(a,b : 8)
/// \endcode
/// In this example directive '#pragma omp simd' has clause 'aligned'
/// with variables 'a', 'b' and alignment '8'.
class OMPAlignedClause final
    : public OMPVarListClause<OMPAlignedClause>,
      private llvm::TrailingObjects<OMPAlignedClause, Expr *> {
  friend class OMPClauseReader;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Location of ':'.
  SourceLocation ColonLoc;

  /// Sets the alignment for clause.
  void setAlignment(Expr *A) { *varlist_end() = A; }

  /// Build 'aligned' clause with given number of variables \a NumVars.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param ColonLoc Location of ':'.
  /// \param EndLoc Ending location of the clause.
  /// \param NumVars Number of variables.
  OMPAlignedClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                   SourceLocation ColonLoc, SourceLocation EndLoc,
                   unsigned NumVars)
      : OMPVarListClause<OMPAlignedClause>(llvm::omp::OMPC_aligned, StartLoc,
                                           LParenLoc, EndLoc, NumVars),
        ColonLoc(ColonLoc) {}

  /// Build an empty clause.
  ///
  /// \param NumVars Number of variables.
  explicit OMPAlignedClause(unsigned NumVars)
      : OMPVarListClause<OMPAlignedClause>(llvm::omp::OMPC_aligned,
                                           SourceLocation(), SourceLocation(),
                                           SourceLocation(), NumVars) {}

public:
  /// Creates clause with a list of variables \a VL and alignment \a A.
  ///
  /// \param C AST Context.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param ColonLoc Location of ':'.
  /// \param EndLoc Ending location of the clause.
  /// \param VL List of references to the variables.
  /// \param A Alignment.
  static OMPAlignedClause *Create(const ASTContext &C, SourceLocation StartLoc,
                                  SourceLocation LParenLoc,
                                  SourceLocation ColonLoc,
                                  SourceLocation EndLoc, ArrayRef<Expr *> VL,
                                  Expr *A);

  /// Creates an empty clause with the place for \a NumVars variables.
  ///
  /// \param C AST context.
  /// \param NumVars Number of variables.
  static OMPAlignedClause *CreateEmpty(const ASTContext &C, unsigned NumVars);

  /// Sets the location of ':'.
  void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }

  /// Returns the location of ':'.
  SourceLocation getColonLoc() const { return ColonLoc; }

  /// Returns alignment.
  Expr *getAlignment() { return *varlist_end(); }

  /// Returns alignment.
  const Expr *getAlignment() const { return *varlist_end(); }

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPAlignedClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_aligned;
  }
};

/// This represents clause 'copyin' in the '#pragma omp ...' directives.
///
/// \code
/// #pragma omp parallel copyin(a,b)
/// \endcode
/// In this example directive '#pragma omp parallel' has clause 'copyin'
/// with the variables 'a' and 'b'.
class OMPCopyinClause final
    : public OMPVarListClause<OMPCopyinClause>,
      private llvm::TrailingObjects<OMPCopyinClause, Expr *> {
  // Class has 3 additional tail allocated arrays:
  // 1. List of helper expressions for proper generation of assignment operation
  // required for copyin clause. This list represents sources.
  // 2. List of helper expressions for proper generation of assignment operation
  // required for copyin clause. This list represents destinations.
  // 3. List of helper expressions that represents assignment operation:
  // \code
  // DstExprs = SrcExprs;
  // \endcode
  // Required for proper codegen of propagation of master's thread values of
  // threadprivate variables to local instances of that variables in other
  // implicit threads.

  friend class OMPClauseReader;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Build clause with number of variables \a N.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param N Number of the variables in the clause.
  OMPCopyinClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                  SourceLocation EndLoc, unsigned N)
      : OMPVarListClause<OMPCopyinClause>(llvm::omp::OMPC_copyin, StartLoc,
                                          LParenLoc, EndLoc, N) {}

  /// Build an empty clause.
  ///
  /// \param N Number of variables.
  explicit OMPCopyinClause(unsigned N)
      : OMPVarListClause<OMPCopyinClause>(llvm::omp::OMPC_copyin,
                                          SourceLocation(), SourceLocation(),
                                          SourceLocation(), N) {}

  /// Set list of helper expressions, required for proper codegen of the
  /// clause. These expressions represent source expression in the final
  /// assignment statement performed by the copyin clause.
  void setSourceExprs(ArrayRef<Expr *> SrcExprs);

  /// Get the list of helper source expressions.
  MutableArrayRef<Expr *> getSourceExprs() {
    return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
  }
  ArrayRef<const Expr *> getSourceExprs() const {
    return llvm::makeArrayRef(varlist_end(), varlist_size());
  }

  /// Set list of helper expressions, required for proper codegen of the
  /// clause. These expressions represent destination expression in the final
  /// assignment statement performed by the copyin clause.
  void setDestinationExprs(ArrayRef<Expr *> DstExprs);

  /// Get the list of helper destination expressions.
  MutableArrayRef<Expr *> getDestinationExprs() {
    return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size());
  }
  ArrayRef<const Expr *> getDestinationExprs() const {
    return llvm::makeArrayRef(getSourceExprs().end(), varlist_size());
  }

  /// Set list of helper assignment expressions, required for proper
  /// codegen of the clause. These expressions are assignment expressions that
  /// assign source helper expressions to destination helper expressions
  /// correspondingly.
  void setAssignmentOps(ArrayRef<Expr *> AssignmentOps);

  /// Get the list of helper assignment expressions.
  MutableArrayRef<Expr *> getAssignmentOps() {
    return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size());
  }
  ArrayRef<const Expr *> getAssignmentOps() const {
    return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size());
  }

public:
  /// Creates clause with a list of variables \a VL.
  ///
  /// \param C AST context.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param VL List of references to the variables.
  /// \param SrcExprs List of helper expressions for proper generation of
  /// assignment operation required for copyin clause. This list represents
  /// sources.
  /// \param DstExprs List of helper expressions for proper generation of
  /// assignment operation required for copyin clause. This list represents
  /// destinations.
  /// \param AssignmentOps List of helper expressions that represents assignment
  /// operation:
  /// \code
  /// DstExprs = SrcExprs;
  /// \endcode
  /// Required for proper codegen of propagation of master's thread values of
  /// threadprivate variables to local instances of that variables in other
  /// implicit threads.
  static OMPCopyinClause *
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
         SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
         ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps);

  /// Creates an empty clause with \a N variables.
  ///
  /// \param C AST context.
  /// \param N The number of variables.
  static OMPCopyinClause *CreateEmpty(const ASTContext &C, unsigned N);

  using helper_expr_iterator = MutableArrayRef<Expr *>::iterator;
  using helper_expr_const_iterator = ArrayRef<const Expr *>::iterator;
  using helper_expr_range = llvm::iterator_range<helper_expr_iterator>;
  using helper_expr_const_range =
      llvm::iterator_range<helper_expr_const_iterator>;

  helper_expr_const_range source_exprs() const {
    return helper_expr_const_range(getSourceExprs().begin(),
                                   getSourceExprs().end());
  }

  helper_expr_range source_exprs() {
    return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end());
  }

  helper_expr_const_range destination_exprs() const {
    return helper_expr_const_range(getDestinationExprs().begin(),
                                   getDestinationExprs().end());
  }

  helper_expr_range destination_exprs() {
    return helper_expr_range(getDestinationExprs().begin(),
                             getDestinationExprs().end());
  }

  helper_expr_const_range assignment_ops() const {
    return helper_expr_const_range(getAssignmentOps().begin(),
                                   getAssignmentOps().end());
  }

  helper_expr_range assignment_ops() {
    return helper_expr_range(getAssignmentOps().begin(),
                             getAssignmentOps().end());
  }

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPCopyinClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_copyin;
  }
};

/// This represents clause 'copyprivate' in the '#pragma omp ...'
/// directives.
///
/// \code
/// #pragma omp single copyprivate(a,b)
/// \endcode
/// In this example directive '#pragma omp single' has clause 'copyprivate'
/// with the variables 'a' and 'b'.
class OMPCopyprivateClause final
    : public OMPVarListClause<OMPCopyprivateClause>,
      private llvm::TrailingObjects<OMPCopyprivateClause, Expr *> {
  friend class OMPClauseReader;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Build clause with number of variables \a N.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param N Number of the variables in the clause.
  OMPCopyprivateClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                       SourceLocation EndLoc, unsigned N)
      : OMPVarListClause<OMPCopyprivateClause>(llvm::omp::OMPC_copyprivate,
                                               StartLoc, LParenLoc, EndLoc, N) {
  }

  /// Build an empty clause.
  ///
  /// \param N Number of variables.
  explicit OMPCopyprivateClause(unsigned N)
      : OMPVarListClause<OMPCopyprivateClause>(
            llvm::omp::OMPC_copyprivate, SourceLocation(), SourceLocation(),
            SourceLocation(), N) {}

  /// Set list of helper expressions, required for proper codegen of the
  /// clause. These expressions represent source expression in the final
  /// assignment statement performed by the copyprivate clause.
  void setSourceExprs(ArrayRef<Expr *> SrcExprs);

  /// Get the list of helper source expressions.
  MutableArrayRef<Expr *> getSourceExprs() {
    return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
  }
  ArrayRef<const Expr *> getSourceExprs() const {
    return llvm::makeArrayRef(varlist_end(), varlist_size());
  }

  /// Set list of helper expressions, required for proper codegen of the
  /// clause. These expressions represent destination expression in the final
  /// assignment statement performed by the copyprivate clause.
  void setDestinationExprs(ArrayRef<Expr *> DstExprs);

  /// Get the list of helper destination expressions.
  MutableArrayRef<Expr *> getDestinationExprs() {
    return MutableArrayRef<Expr *>(getSourceExprs().end(), varlist_size());
  }
  ArrayRef<const Expr *> getDestinationExprs() const {
    return llvm::makeArrayRef(getSourceExprs().end(), varlist_size());
  }

  /// Set list of helper assignment expressions, required for proper
  /// codegen of the clause. These expressions are assignment expressions that
  /// assign source helper expressions to destination helper expressions
  /// correspondingly.
  void setAssignmentOps(ArrayRef<Expr *> AssignmentOps);

  /// Get the list of helper assignment expressions.
  MutableArrayRef<Expr *> getAssignmentOps() {
    return MutableArrayRef<Expr *>(getDestinationExprs().end(), varlist_size());
  }
  ArrayRef<const Expr *> getAssignmentOps() const {
    return llvm::makeArrayRef(getDestinationExprs().end(), varlist_size());
  }

public:
  /// Creates clause with a list of variables \a VL.
  ///
  /// \param C AST context.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param VL List of references to the variables.
  /// \param SrcExprs List of helper expressions for proper generation of
  /// assignment operation required for copyprivate clause. This list represents
  /// sources.
  /// \param DstExprs List of helper expressions for proper generation of
  /// assignment operation required for copyprivate clause. This list represents
  /// destinations.
  /// \param AssignmentOps List of helper expressions that represents assignment
  /// operation:
  /// \code
  /// DstExprs = SrcExprs;
  /// \endcode
  /// Required for proper codegen of final assignment performed by the
  /// copyprivate clause.
  static OMPCopyprivateClause *
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
         SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
         ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps);

  /// Creates an empty clause with \a N variables.
  ///
  /// \param C AST context.
  /// \param N The number of variables.
  static OMPCopyprivateClause *CreateEmpty(const ASTContext &C, unsigned N);

  using helper_expr_iterator = MutableArrayRef<Expr *>::iterator;
  using helper_expr_const_iterator = ArrayRef<const Expr *>::iterator;
  using helper_expr_range = llvm::iterator_range<helper_expr_iterator>;
  using helper_expr_const_range =
      llvm::iterator_range<helper_expr_const_iterator>;

  helper_expr_const_range source_exprs() const {
    return helper_expr_const_range(getSourceExprs().begin(),
                                   getSourceExprs().end());
  }

  helper_expr_range source_exprs() {
    return helper_expr_range(getSourceExprs().begin(), getSourceExprs().end());
  }

  helper_expr_const_range destination_exprs() const {
    return helper_expr_const_range(getDestinationExprs().begin(),
                                   getDestinationExprs().end());
  }

  helper_expr_range destination_exprs() {
    return helper_expr_range(getDestinationExprs().begin(),
                             getDestinationExprs().end());
  }

  helper_expr_const_range assignment_ops() const {
    return helper_expr_const_range(getAssignmentOps().begin(),
                                   getAssignmentOps().end());
  }

  helper_expr_range assignment_ops() {
    return helper_expr_range(getAssignmentOps().begin(),
                             getAssignmentOps().end());
  }

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPCopyprivateClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_copyprivate;
  }
};

/// This represents implicit clause 'flush' for the '#pragma omp flush'
/// directive.
/// This clause does not exist by itself, it can be only as a part of 'omp
/// flush' directive. This clause is introduced to keep the original structure
/// of \a OMPExecutableDirective class and its derivatives and to use the
/// existing infrastructure of clauses with the list of variables.
///
/// \code
/// #pragma omp flush(a,b)
/// \endcode
/// In this example directive '#pragma omp flush' has implicit clause 'flush'
/// with the variables 'a' and 'b'.
class OMPFlushClause final
    : public OMPVarListClause<OMPFlushClause>,
      private llvm::TrailingObjects<OMPFlushClause, Expr *> {
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Build clause with number of variables \a N.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param N Number of the variables in the clause.
  OMPFlushClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                 SourceLocation EndLoc, unsigned N)
      : OMPVarListClause<OMPFlushClause>(llvm::omp::OMPC_flush, StartLoc,
                                         LParenLoc, EndLoc, N) {}

  /// Build an empty clause.
  ///
  /// \param N Number of variables.
  explicit OMPFlushClause(unsigned N)
      : OMPVarListClause<OMPFlushClause>(llvm::omp::OMPC_flush,
                                         SourceLocation(), SourceLocation(),
                                         SourceLocation(), N) {}

public:
  /// Creates clause with a list of variables \a VL.
  ///
  /// \param C AST context.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param VL List of references to the variables.
  static OMPFlushClause *Create(const ASTContext &C, SourceLocation StartLoc,
                                SourceLocation LParenLoc, SourceLocation EndLoc,
                                ArrayRef<Expr *> VL);

  /// Creates an empty clause with \a N variables.
  ///
  /// \param C AST context.
  /// \param N The number of variables.
  static OMPFlushClause *CreateEmpty(const ASTContext &C, unsigned N);

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPFlushClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_flush;
  }
};

/// This represents implicit clause 'depobj' for the '#pragma omp depobj'
/// directive.
/// This clause does not exist by itself, it can be only as a part of 'omp
/// depobj' directive. This clause is introduced to keep the original structure
/// of \a OMPExecutableDirective class and its derivatives and to use the
/// existing infrastructure of clauses with the list of variables.
///
/// \code
/// #pragma omp depobj(a) destroy
/// \endcode
/// In this example directive '#pragma omp depobj' has implicit clause 'depobj'
/// with the depobj 'a'.
class OMPDepobjClause final : public OMPClause {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Chunk size.
  Expr *Depobj = nullptr;

  /// Build clause with number of variables \a N.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPDepobjClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                  SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_depobj, StartLoc, EndLoc),
        LParenLoc(LParenLoc) {}

  /// Build an empty clause.
  ///
  explicit OMPDepobjClause()
      : OMPClause(llvm::omp::OMPC_depobj, SourceLocation(), SourceLocation()) {}

  void setDepobj(Expr *E) { Depobj = E; }

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

public:
  /// Creates clause.
  ///
  /// \param C AST context.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param Depobj depobj expression associated with the 'depobj' directive.
  static OMPDepobjClause *Create(const ASTContext &C, SourceLocation StartLoc,
                                 SourceLocation LParenLoc,
                                 SourceLocation EndLoc, Expr *Depobj);

  /// Creates an empty clause.
  ///
  /// \param C AST context.
  static OMPDepobjClause *CreateEmpty(const ASTContext &C);

  /// Returns depobj expression associated with the clause.
  Expr *getDepobj() { return Depobj; }
  const Expr *getDepobj() const { return Depobj; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(&Depobj),
                       reinterpret_cast<Stmt **>(&Depobj) + 1);
  }

  const_child_range children() const {
    auto Children = const_cast<OMPDepobjClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_depobj;
  }
};

/// This represents implicit clause 'depend' for the '#pragma omp task'
/// directive.
///
/// \code
/// #pragma omp task depend(in:a,b)
/// \endcode
/// In this example directive '#pragma omp task' with clause 'depend' with the
/// variables 'a' and 'b' with dependency 'in'.
class OMPDependClause final
    : public OMPVarListClause<OMPDependClause>,
      private llvm::TrailingObjects<OMPDependClause, Expr *> {
  friend class OMPClauseReader;
  friend OMPVarListClause;
  friend TrailingObjects;

public:
  struct DependDataTy final {
    /// Dependency type (one of in, out, inout).
    OpenMPDependClauseKind DepKind = OMPC_DEPEND_unknown;

    /// Dependency type location.
    SourceLocation DepLoc;

    /// Colon location.
    SourceLocation ColonLoc;

    /// Location of 'omp_all_memory'.
    SourceLocation OmpAllMemoryLoc;
  };

private:
  /// Dependency type and source locations.
  DependDataTy Data;

  /// Number of loops, associated with the depend clause.
  unsigned NumLoops = 0;

  /// Build clause with number of variables \a N.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param N Number of the variables in the clause.
  /// \param NumLoops Number of loops that is associated with this depend
  /// clause.
  OMPDependClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                  SourceLocation EndLoc, unsigned N, unsigned NumLoops)
      : OMPVarListClause<OMPDependClause>(llvm::omp::OMPC_depend, StartLoc,
                                          LParenLoc, EndLoc, N),
        NumLoops(NumLoops) {}

  /// Build an empty clause.
  ///
  /// \param N Number of variables.
  /// \param NumLoops Number of loops that is associated with this depend
  /// clause.
  explicit OMPDependClause(unsigned N, unsigned NumLoops)
      : OMPVarListClause<OMPDependClause>(llvm::omp::OMPC_depend,
                                          SourceLocation(), SourceLocation(),
                                          SourceLocation(), N),
        NumLoops(NumLoops) {}

  /// Set dependency kind.
  void setDependencyKind(OpenMPDependClauseKind K) { Data.DepKind = K; }

  /// Set dependency kind and its location.
  void setDependencyLoc(SourceLocation Loc) { Data.DepLoc = Loc; }

  /// Set colon location.
  void setColonLoc(SourceLocation Loc) { Data.ColonLoc = Loc; }

  /// Set the 'omp_all_memory' location.
  void setOmpAllMemoryLoc(SourceLocation Loc) { Data.OmpAllMemoryLoc = Loc; }

  /// Sets optional dependency modifier.
  void setModifier(Expr *DepModifier);

public:
  /// Creates clause with a list of variables \a VL.
  ///
  /// \param C AST context.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param Data Dependency type and source locations.
  /// \param VL List of references to the variables.
  /// \param NumLoops Number of loops that is associated with this depend
  /// clause.
  static OMPDependClause *Create(const ASTContext &C, SourceLocation StartLoc,
                                 SourceLocation LParenLoc,
                                 SourceLocation EndLoc, DependDataTy Data,
                                 Expr *DepModifier, ArrayRef<Expr *> VL,
                                 unsigned NumLoops);

  /// Creates an empty clause with \a N variables.
  ///
  /// \param C AST context.
  /// \param N The number of variables.
  /// \param NumLoops Number of loops that is associated with this depend
  /// clause.
  static OMPDependClause *CreateEmpty(const ASTContext &C, unsigned N,
                                      unsigned NumLoops);

  /// Get dependency type.
  OpenMPDependClauseKind getDependencyKind() const { return Data.DepKind; }

  /// Get dependency type location.
  SourceLocation getDependencyLoc() const { return Data.DepLoc; }

  /// Get colon location.
  SourceLocation getColonLoc() const { return Data.ColonLoc; }

  /// Get 'omp_all_memory' location.
  SourceLocation getOmpAllMemoryLoc() const { return Data.OmpAllMemoryLoc; }

  /// Return optional depend modifier.
  Expr *getModifier();
  const Expr *getModifier() const {
    return const_cast<OMPDependClause *>(this)->getModifier();
  }

  /// Get number of loops associated with the clause.
  unsigned getNumLoops() const { return NumLoops; }

  /// Set the loop data for the depend clauses with 'sink|source' kind of
  /// dependency.
  void setLoopData(unsigned NumLoop, Expr *Cnt);

  /// Get the loop data.
  Expr *getLoopData(unsigned NumLoop);
  const Expr *getLoopData(unsigned NumLoop) const;

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPDependClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_depend;
  }
};

/// This represents 'device' clause in the '#pragma omp ...'
/// directive.
///
/// \code
/// #pragma omp target device(a)
/// \endcode
/// In this example directive '#pragma omp target' has clause 'device'
/// with single expression 'a'.
class OMPDeviceClause : public OMPClause, public OMPClauseWithPreInit {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Device clause modifier.
  OpenMPDeviceClauseModifier Modifier = OMPC_DEVICE_unknown;

  /// Location of the modifier.
  SourceLocation ModifierLoc;

  /// Device number.
  Stmt *Device = nullptr;

  /// Set the device number.
  ///
  /// \param E Device number.
  void setDevice(Expr *E) { Device = E; }

  /// Sets modifier.
  void setModifier(OpenMPDeviceClauseModifier M) { Modifier = M; }

  /// Setst modifier location.
  void setModifierLoc(SourceLocation Loc) { ModifierLoc = Loc; }

public:
  /// Build 'device' clause.
  ///
  /// \param Modifier Clause modifier.
  /// \param E Expression associated with this clause.
  /// \param CaptureRegion Innermost OpenMP region where expressions in this
  /// clause must be captured.
  /// \param StartLoc Starting location of the clause.
  /// \param ModifierLoc Modifier location.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPDeviceClause(OpenMPDeviceClauseModifier Modifier, Expr *E, Stmt *HelperE,
                  OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
                  SourceLocation LParenLoc, SourceLocation ModifierLoc,
                  SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_device, StartLoc, EndLoc),
        OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Modifier(Modifier),
        ModifierLoc(ModifierLoc), Device(E) {
    setPreInitStmt(HelperE, CaptureRegion);
  }

  /// Build an empty clause.
  OMPDeviceClause()
      : OMPClause(llvm::omp::OMPC_device, SourceLocation(), SourceLocation()),
        OMPClauseWithPreInit(this) {}

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Return device number.
  Expr *getDevice() { return cast<Expr>(Device); }

  /// Return device number.
  Expr *getDevice() const { return cast<Expr>(Device); }

  /// Gets modifier.
  OpenMPDeviceClauseModifier getModifier() const { return Modifier; }

  /// Gets modifier location.
  SourceLocation getModifierLoc() const { return ModifierLoc; }

  child_range children() { return child_range(&Device, &Device + 1); }

  const_child_range children() const {
    return const_child_range(&Device, &Device + 1);
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_device;
  }
};

/// This represents 'threads' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp ordered threads
/// \endcode
/// In this example directive '#pragma omp ordered' has simple 'threads' clause.
class OMPThreadsClause : public OMPClause {
public:
  /// Build 'threads' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_threads, StartLoc, EndLoc) {}

  /// Build an empty clause.
  OMPThreadsClause()
      : OMPClause(llvm::omp::OMPC_threads, SourceLocation(), SourceLocation()) {
  }

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_threads;
  }
};

/// This represents 'simd' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp ordered simd
/// \endcode
/// In this example directive '#pragma omp ordered' has simple 'simd' clause.
class OMPSIMDClause : public OMPClause {
public:
  /// Build 'simd' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_simd, StartLoc, EndLoc) {}

  /// Build an empty clause.
  OMPSIMDClause()
      : OMPClause(llvm::omp::OMPC_simd, SourceLocation(), SourceLocation()) {}

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_simd;
  }
};

/// Struct that defines common infrastructure to handle mappable
/// expressions used in OpenMP clauses.
class OMPClauseMappableExprCommon {
public:
  /// Class that represents a component of a mappable expression. E.g.
  /// for an expression S.a, the first component is a declaration reference
  /// expression associated with 'S' and the second is a member expression
  /// associated with the field declaration 'a'. If the expression is an array
  /// subscript it may not have any associated declaration. In that case the
  /// associated declaration is set to nullptr.
  class MappableComponent {
    /// Pair of Expression and Non-contiguous pair  associated with the
    /// component.
    llvm::PointerIntPair<Expr *, 1, bool> AssociatedExpressionNonContiguousPr;

    /// Declaration associated with the declaration. If the component does
    /// not have a declaration (e.g. array subscripts or section), this is set
    /// to nullptr.
    ValueDecl *AssociatedDeclaration = nullptr;

  public:
    explicit MappableComponent() = default;
    explicit MappableComponent(Expr *AssociatedExpression,
                               ValueDecl *AssociatedDeclaration,
                               bool IsNonContiguous)
        : AssociatedExpressionNonContiguousPr(AssociatedExpression,
                                              IsNonContiguous),
          AssociatedDeclaration(
              AssociatedDeclaration
                  ? cast<ValueDecl>(AssociatedDeclaration->getCanonicalDecl())
                  : nullptr) {}

    Expr *getAssociatedExpression() const {
      return AssociatedExpressionNonContiguousPr.getPointer();
    }

    bool isNonContiguous() const {
      return AssociatedExpressionNonContiguousPr.getInt();
    }

    ValueDecl *getAssociatedDeclaration() const {
      return AssociatedDeclaration;
    }
  };

  // List of components of an expression. This first one is the whole
  // expression and the last one is the base expression.
  using MappableExprComponentList = SmallVector<MappableComponent, 8>;
  using MappableExprComponentListRef = ArrayRef<MappableComponent>;

  // List of all component lists associated to the same base declaration.
  // E.g. if both 'S.a' and 'S.b' are a mappable expressions, each will have
  // their component list but the same base declaration 'S'.
  using MappableExprComponentLists = SmallVector<MappableExprComponentList, 8>;
  using MappableExprComponentListsRef = ArrayRef<MappableExprComponentList>;

protected:
  // Return the total number of elements in a list of component lists.
  static unsigned
  getComponentsTotalNumber(MappableExprComponentListsRef ComponentLists);

  // Return the total number of elements in a list of declarations. All
  // declarations are expected to be canonical.
  static unsigned
  getUniqueDeclarationsTotalNumber(ArrayRef<const ValueDecl *> Declarations);
};

/// This structure contains all sizes needed for by an
/// OMPMappableExprListClause.
struct OMPMappableExprListSizeTy {
  /// Number of expressions listed.
  unsigned NumVars;
  /// Number of unique base declarations.
  unsigned NumUniqueDeclarations;
  /// Number of component lists.
  unsigned NumComponentLists;
  /// Total number of expression components.
  unsigned NumComponents;
  OMPMappableExprListSizeTy() = default;
  OMPMappableExprListSizeTy(unsigned NumVars, unsigned NumUniqueDeclarations,
                            unsigned NumComponentLists, unsigned NumComponents)
      : NumVars(NumVars), NumUniqueDeclarations(NumUniqueDeclarations),
        NumComponentLists(NumComponentLists), NumComponents(NumComponents) {}
};

/// This represents clauses with a list of expressions that are mappable.
/// Examples of these clauses are 'map' in
/// '#pragma omp target [enter|exit] [data]...' directives, and  'to' and 'from
/// in '#pragma omp target update...' directives.
template <class T>
class OMPMappableExprListClause : public OMPVarListClause<T>,
                                  public OMPClauseMappableExprCommon {
  friend class OMPClauseReader;

  /// Number of unique declarations in this clause.
  unsigned NumUniqueDeclarations;

  /// Number of component lists in this clause.
  unsigned NumComponentLists;

  /// Total number of components in this clause.
  unsigned NumComponents;

  /// Whether this clause is possible to have user-defined mappers associated.
  /// It should be true for map, to, and from clauses, and false for
  /// use_device_ptr and is_device_ptr.
  const bool SupportsMapper;

  /// C++ nested name specifier for the associated user-defined mapper.
  NestedNameSpecifierLoc MapperQualifierLoc;

  /// The associated user-defined mapper identifier information.
  DeclarationNameInfo MapperIdInfo;

protected:
  /// Build a clause for \a NumUniqueDeclarations declarations, \a
  /// NumComponentLists total component lists, and \a NumComponents total
  /// components.
  ///
  /// \param K Kind of the clause.
  /// \param Locs Locations needed to build a mappable clause. It includes 1)
  /// StartLoc: starting location of the clause (the clause keyword); 2)
  /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  /// \param SupportsMapper Indicates whether this clause is possible to have
  /// user-defined mappers associated.
  /// \param MapperQualifierLocPtr C++ nested name specifier for the associated
  /// user-defined mapper.
  /// \param MapperIdInfoPtr The identifier of associated user-defined mapper.
  OMPMappableExprListClause(
      OpenMPClauseKind K, const OMPVarListLocTy &Locs,
      const OMPMappableExprListSizeTy &Sizes, bool SupportsMapper = false,
      NestedNameSpecifierLoc *MapperQualifierLocPtr = nullptr,
      DeclarationNameInfo *MapperIdInfoPtr = nullptr)
      : OMPVarListClause<T>(K, Locs.StartLoc, Locs.LParenLoc, Locs.EndLoc,
                            Sizes.NumVars),
        NumUniqueDeclarations(Sizes.NumUniqueDeclarations),
        NumComponentLists(Sizes.NumComponentLists),
        NumComponents(Sizes.NumComponents), SupportsMapper(SupportsMapper) {
    if (MapperQualifierLocPtr)
      MapperQualifierLoc = *MapperQualifierLocPtr;
    if (MapperIdInfoPtr)
      MapperIdInfo = *MapperIdInfoPtr;
  }

  /// Get the unique declarations that are in the trailing objects of the
  /// class.
  MutableArrayRef<ValueDecl *> getUniqueDeclsRef() {
    return MutableArrayRef<ValueDecl *>(
        static_cast<T *>(this)->template getTrailingObjects<ValueDecl *>(),
        NumUniqueDeclarations);
  }

  /// Get the unique declarations that are in the trailing objects of the
  /// class.
  ArrayRef<ValueDecl *> getUniqueDeclsRef() const {
    return ArrayRef<ValueDecl *>(
        static_cast<const T *>(this)
            ->template getTrailingObjects<ValueDecl *>(),
        NumUniqueDeclarations);
  }

  /// Set the unique declarations that are in the trailing objects of the
  /// class.
  void setUniqueDecls(ArrayRef<ValueDecl *> UDs) {
    assert(UDs.size() == NumUniqueDeclarations &&
           "Unexpected amount of unique declarations.");
    std::copy(UDs.begin(), UDs.end(), getUniqueDeclsRef().begin());
  }

  /// Get the number of lists per declaration that are in the trailing
  /// objects of the class.
  MutableArrayRef<unsigned> getDeclNumListsRef() {
    return MutableArrayRef<unsigned>(
        static_cast<T *>(this)->template getTrailingObjects<unsigned>(),
        NumUniqueDeclarations);
  }

  /// Get the number of lists per declaration that are in the trailing
  /// objects of the class.
  ArrayRef<unsigned> getDeclNumListsRef() const {
    return ArrayRef<unsigned>(
        static_cast<const T *>(this)->template getTrailingObjects<unsigned>(),
        NumUniqueDeclarations);
  }

  /// Set the number of lists per declaration that are in the trailing
  /// objects of the class.
  void setDeclNumLists(ArrayRef<unsigned> DNLs) {
    assert(DNLs.size() == NumUniqueDeclarations &&
           "Unexpected amount of list numbers.");
    std::copy(DNLs.begin(), DNLs.end(), getDeclNumListsRef().begin());
  }

  /// Get the cumulative component lists sizes that are in the trailing
  /// objects of the class. They are appended after the number of lists.
  MutableArrayRef<unsigned> getComponentListSizesRef() {
    return MutableArrayRef<unsigned>(
        static_cast<T *>(this)->template getTrailingObjects<unsigned>() +
            NumUniqueDeclarations,
        NumComponentLists);
  }

  /// Get the cumulative component lists sizes that are in the trailing
  /// objects of the class. They are appended after the number of lists.
  ArrayRef<unsigned> getComponentListSizesRef() const {
    return ArrayRef<unsigned>(
        static_cast<const T *>(this)->template getTrailingObjects<unsigned>() +
            NumUniqueDeclarations,
        NumComponentLists);
  }

  /// Set the cumulative component lists sizes that are in the trailing
  /// objects of the class.
  void setComponentListSizes(ArrayRef<unsigned> CLSs) {
    assert(CLSs.size() == NumComponentLists &&
           "Unexpected amount of component lists.");
    std::copy(CLSs.begin(), CLSs.end(), getComponentListSizesRef().begin());
  }

  /// Get the components that are in the trailing objects of the class.
  MutableArrayRef<MappableComponent> getComponentsRef() {
    return MutableArrayRef<MappableComponent>(
        static_cast<T *>(this)
            ->template getTrailingObjects<MappableComponent>(),
        NumComponents);
  }

  /// Get the components that are in the trailing objects of the class.
  ArrayRef<MappableComponent> getComponentsRef() const {
    return ArrayRef<MappableComponent>(
        static_cast<const T *>(this)
            ->template getTrailingObjects<MappableComponent>(),
        NumComponents);
  }

  /// Set the components that are in the trailing objects of the class.
  /// This requires the list sizes so that it can also fill the original
  /// expressions, which are the first component of each list.
  void setComponents(ArrayRef<MappableComponent> Components,
                     ArrayRef<unsigned> CLSs) {
    assert(Components.size() == NumComponents &&
           "Unexpected amount of component lists.");
    assert(CLSs.size() == NumComponentLists &&
           "Unexpected amount of list sizes.");
    std::copy(Components.begin(), Components.end(), getComponentsRef().begin());
  }

  /// Fill the clause information from the list of declarations and
  /// associated component lists.
  void setClauseInfo(ArrayRef<ValueDecl *> Declarations,
                     MappableExprComponentListsRef ComponentLists) {
    // Perform some checks to make sure the data sizes are consistent with the
    // information available when the clause was created.
    assert(getUniqueDeclarationsTotalNumber(Declarations) ==
               NumUniqueDeclarations &&
           "Unexpected number of mappable expression info entries!");
    assert(getComponentsTotalNumber(ComponentLists) == NumComponents &&
           "Unexpected total number of components!");
    assert(Declarations.size() == ComponentLists.size() &&
           "Declaration and component lists size is not consistent!");
    assert(Declarations.size() == NumComponentLists &&
           "Unexpected declaration and component lists size!");

    // Organize the components by declaration and retrieve the original
    // expression. Original expressions are always the first component of the
    // mappable component list.
    llvm::MapVector<ValueDecl *, SmallVector<MappableExprComponentListRef, 8>>
        ComponentListMap;
    {
      auto CI = ComponentLists.begin();
      for (auto DI = Declarations.begin(), DE = Declarations.end(); DI != DE;
           ++DI, ++CI) {
        assert(!CI->empty() && "Invalid component list!");
        ComponentListMap[*DI].push_back(*CI);
      }
    }

    // Iterators of the target storage.
    auto UniqueDeclarations = getUniqueDeclsRef();
    auto UDI = UniqueDeclarations.begin();

    auto DeclNumLists = getDeclNumListsRef();
    auto DNLI = DeclNumLists.begin();

    auto ComponentListSizes = getComponentListSizesRef();
    auto CLSI = ComponentListSizes.begin();

    auto Components = getComponentsRef();
    auto CI = Components.begin();

    // Variable to compute the accumulation of the number of components.
    unsigned PrevSize = 0u;

    // Scan all the declarations and associated component lists.
    for (auto &M : ComponentListMap) {
      // The declaration.
      auto *D = M.first;
      // The component lists.
      auto CL = M.second;

      // Initialize the entry.
      *UDI = D;
      ++UDI;

      *DNLI = CL.size();
      ++DNLI;

      // Obtain the cumulative sizes and concatenate all the components in the
      // reserved storage.
      for (auto C : CL) {
        // Accumulate with the previous size.
        PrevSize += C.size();

        // Save the size.
        *CLSI = PrevSize;
        ++CLSI;

        // Append components after the current components iterator.
        CI = std::copy(C.begin(), C.end(), CI);
      }
    }
  }

  /// Set the nested name specifier of associated user-defined mapper.
  void setMapperQualifierLoc(NestedNameSpecifierLoc NNSL) {
    MapperQualifierLoc = NNSL;
  }

  /// Set the name of associated user-defined mapper.
  void setMapperIdInfo(DeclarationNameInfo MapperId) {
    MapperIdInfo = MapperId;
  }

  /// Get the user-defined mapper references that are in the trailing objects of
  /// the class.
  MutableArrayRef<Expr *> getUDMapperRefs() {
    assert(SupportsMapper &&
           "Must be a clause that is possible to have user-defined mappers");
    return llvm::makeMutableArrayRef<Expr *>(
        static_cast<T *>(this)->template getTrailingObjects<Expr *>() +
            OMPVarListClause<T>::varlist_size(),
        OMPVarListClause<T>::varlist_size());
  }

  /// Get the user-defined mappers references that are in the trailing objects
  /// of the class.
  ArrayRef<Expr *> getUDMapperRefs() const {
    assert(SupportsMapper &&
           "Must be a clause that is possible to have user-defined mappers");
    return llvm::makeArrayRef<Expr *>(
        static_cast<const T *>(this)->template getTrailingObjects<Expr *>() +
            OMPVarListClause<T>::varlist_size(),
        OMPVarListClause<T>::varlist_size());
  }

  /// Set the user-defined mappers that are in the trailing objects of the
  /// class.
  void setUDMapperRefs(ArrayRef<Expr *> DMDs) {
    assert(DMDs.size() == OMPVarListClause<T>::varlist_size() &&
           "Unexpected number of user-defined mappers.");
    assert(SupportsMapper &&
           "Must be a clause that is possible to have user-defined mappers");
    std::copy(DMDs.begin(), DMDs.end(), getUDMapperRefs().begin());
  }

public:
  /// Return the number of unique base declarations in this clause.
  unsigned getUniqueDeclarationsNum() const { return NumUniqueDeclarations; }

  /// Return the number of lists derived from the clause expressions.
  unsigned getTotalComponentListNum() const { return NumComponentLists; }

  /// Return the total number of components in all lists derived from the
  /// clause.
  unsigned getTotalComponentsNum() const { return NumComponents; }

  /// Gets the nested name specifier for associated user-defined mapper.
  NestedNameSpecifierLoc getMapperQualifierLoc() const {
    return MapperQualifierLoc;
  }

  /// Gets the name info for associated user-defined mapper.
  const DeclarationNameInfo &getMapperIdInfo() const { return MapperIdInfo; }

  /// Iterator that browse the components by lists. It also allows
  /// browsing components of a single declaration.
  class const_component_lists_iterator
      : public llvm::iterator_adaptor_base<
            const_component_lists_iterator,
            MappableExprComponentListRef::const_iterator,
            std::forward_iterator_tag, MappableComponent, ptrdiff_t,
            MappableComponent, MappableComponent> {
    // The declaration the iterator currently refers to.
    ArrayRef<ValueDecl *>::iterator DeclCur;

    // The list number associated with the current declaration.
    ArrayRef<unsigned>::iterator NumListsCur;

    // Whether this clause is possible to have user-defined mappers associated.
    const bool SupportsMapper;

    // The user-defined mapper associated with the current declaration.
    ArrayRef<Expr *>::iterator MapperCur;

    // Remaining lists for the current declaration.
    unsigned RemainingLists = 0;

    // The cumulative size of the previous list, or zero if there is no previous
    // list.
    unsigned PrevListSize = 0;

    // The cumulative sizes of the current list - it will delimit the remaining
    // range of interest.
    ArrayRef<unsigned>::const_iterator ListSizeCur;
    ArrayRef<unsigned>::const_iterator ListSizeEnd;

    // Iterator to the end of the components storage.
    MappableExprComponentListRef::const_iterator End;

  public:
    /// Construct an iterator that scans all lists.
    explicit const_component_lists_iterator(
        ArrayRef<ValueDecl *> UniqueDecls, ArrayRef<unsigned> DeclsListNum,
        ArrayRef<unsigned> CumulativeListSizes,
        MappableExprComponentListRef Components, bool SupportsMapper,
        ArrayRef<Expr *> Mappers)
        : const_component_lists_iterator::iterator_adaptor_base(
              Components.begin()),
          DeclCur(UniqueDecls.begin()), NumListsCur(DeclsListNum.begin()),
          SupportsMapper(SupportsMapper),
          ListSizeCur(CumulativeListSizes.begin()),
          ListSizeEnd(CumulativeListSizes.end()), End(Components.end()) {
      assert(UniqueDecls.size() == DeclsListNum.size() &&
             "Inconsistent number of declarations and list sizes!");
      if (!DeclsListNum.empty())
        RemainingLists = *NumListsCur;
      if (SupportsMapper)
        MapperCur = Mappers.begin();
    }

    /// Construct an iterator that scan lists for a given declaration \a
    /// Declaration.
    explicit const_component_lists_iterator(
        const ValueDecl *Declaration, ArrayRef<ValueDecl *> UniqueDecls,
        ArrayRef<unsigned> DeclsListNum, ArrayRef<unsigned> CumulativeListSizes,
        MappableExprComponentListRef Components, bool SupportsMapper,
        ArrayRef<Expr *> Mappers)
        : const_component_lists_iterator(UniqueDecls, DeclsListNum,
                                         CumulativeListSizes, Components,
                                         SupportsMapper, Mappers) {
      // Look for the desired declaration. While we are looking for it, we
      // update the state so that we know the component where a given list
      // starts.
      for (; DeclCur != UniqueDecls.end(); ++DeclCur, ++NumListsCur) {
        if (*DeclCur == Declaration)
          break;

        assert(*NumListsCur > 0 && "No lists associated with declaration??");

        // Skip the lists associated with the current declaration, but save the
        // last list size that was skipped.
        std::advance(ListSizeCur, *NumListsCur - 1);
        PrevListSize = *ListSizeCur;
        ++ListSizeCur;

        if (SupportsMapper)
          ++MapperCur;
      }

      // If we didn't find any declaration, advance the iterator to after the
      // last component and set remaining lists to zero.
      if (ListSizeCur == CumulativeListSizes.end()) {
        this->I = End;
        RemainingLists = 0u;
        return;
      }

      // Set the remaining lists with the total number of lists of the current
      // declaration.
      RemainingLists = *NumListsCur;

      // Adjust the list size end iterator to the end of the relevant range.
      ListSizeEnd = ListSizeCur;
      std::advance(ListSizeEnd, RemainingLists);

      // Given that the list sizes are cumulative, the index of the component
      // that start the list is the size of the previous list.
      std::advance(this->I, PrevListSize);
    }

    // Return the array with the current list. The sizes are cumulative, so the
    // array size is the difference between the current size and previous one.
    std::tuple<const ValueDecl *, MappableExprComponentListRef,
               const ValueDecl *>
    operator*() const {
      assert(ListSizeCur != ListSizeEnd && "Invalid iterator!");
      const ValueDecl *Mapper = nullptr;
      if (SupportsMapper && *MapperCur)
        Mapper = cast<ValueDecl>(cast<DeclRefExpr>(*MapperCur)->getDecl());
      return std::make_tuple(
          *DeclCur,
          MappableExprComponentListRef(&*this->I, *ListSizeCur - PrevListSize),
          Mapper);
    }
    std::tuple<const ValueDecl *, MappableExprComponentListRef,
               const ValueDecl *>
    operator->() const {
      return **this;
    }

    // Skip the components of the current list.
    const_component_lists_iterator &operator++() {
      assert(ListSizeCur != ListSizeEnd && RemainingLists &&
             "Invalid iterator!");

      // If we don't have more lists just skip all the components. Otherwise,
      // advance the iterator by the number of components in the current list.
      if (std::next(ListSizeCur) == ListSizeEnd) {
        this->I = End;
        RemainingLists = 0;
      } else {
        std::advance(this->I, *ListSizeCur - PrevListSize);
        PrevListSize = *ListSizeCur;

        // We are done with a declaration, move to the next one.
        if (!(--RemainingLists)) {
          ++DeclCur;
          ++NumListsCur;
          RemainingLists = *NumListsCur;
          assert(RemainingLists && "No lists in the following declaration??");
        }
      }

      ++ListSizeCur;
      if (SupportsMapper)
        ++MapperCur;
      return *this;
    }
  };

  using const_component_lists_range =
      llvm::iterator_range<const_component_lists_iterator>;

  /// Iterators for all component lists.
  const_component_lists_iterator component_lists_begin() const {
    return const_component_lists_iterator(
        getUniqueDeclsRef(), getDeclNumListsRef(), getComponentListSizesRef(),
        getComponentsRef(), SupportsMapper,
        SupportsMapper ? getUDMapperRefs() : llvm::None);
  }
  const_component_lists_iterator component_lists_end() const {
    return const_component_lists_iterator(
        ArrayRef<ValueDecl *>(), ArrayRef<unsigned>(), ArrayRef<unsigned>(),
        MappableExprComponentListRef(getComponentsRef().end(),
                                     getComponentsRef().end()),
        SupportsMapper, llvm::None);
  }
  const_component_lists_range component_lists() const {
    return {component_lists_begin(), component_lists_end()};
  }

  /// Iterators for component lists associated with the provided
  /// declaration.
  const_component_lists_iterator
  decl_component_lists_begin(const ValueDecl *VD) const {
    return const_component_lists_iterator(
        VD, getUniqueDeclsRef(), getDeclNumListsRef(),
        getComponentListSizesRef(), getComponentsRef(), SupportsMapper,
        SupportsMapper ? getUDMapperRefs() : llvm::None);
  }
  const_component_lists_iterator decl_component_lists_end() const {
    return component_lists_end();
  }
  const_component_lists_range decl_component_lists(const ValueDecl *VD) const {
    return {decl_component_lists_begin(VD), decl_component_lists_end()};
  }

  /// Iterators to access all the declarations, number of lists, list sizes, and
  /// components.
  using const_all_decls_iterator = ArrayRef<ValueDecl *>::iterator;
  using const_all_decls_range = llvm::iterator_range<const_all_decls_iterator>;

  const_all_decls_range all_decls() const {
    auto A = getUniqueDeclsRef();
    return const_all_decls_range(A.begin(), A.end());
  }

  using const_all_num_lists_iterator = ArrayRef<unsigned>::iterator;
  using const_all_num_lists_range =
      llvm::iterator_range<const_all_num_lists_iterator>;

  const_all_num_lists_range all_num_lists() const {
    auto A = getDeclNumListsRef();
    return const_all_num_lists_range(A.begin(), A.end());
  }

  using const_all_lists_sizes_iterator = ArrayRef<unsigned>::iterator;
  using const_all_lists_sizes_range =
      llvm::iterator_range<const_all_lists_sizes_iterator>;

  const_all_lists_sizes_range all_lists_sizes() const {
    auto A = getComponentListSizesRef();
    return const_all_lists_sizes_range(A.begin(), A.end());
  }

  using const_all_components_iterator = ArrayRef<MappableComponent>::iterator;
  using const_all_components_range =
      llvm::iterator_range<const_all_components_iterator>;

  const_all_components_range all_components() const {
    auto A = getComponentsRef();
    return const_all_components_range(A.begin(), A.end());
  }

  using mapperlist_iterator = MutableArrayRef<Expr *>::iterator;
  using mapperlist_const_iterator = ArrayRef<const Expr *>::iterator;
  using mapperlist_range = llvm::iterator_range<mapperlist_iterator>;
  using mapperlist_const_range =
      llvm::iterator_range<mapperlist_const_iterator>;

  mapperlist_iterator mapperlist_begin() { return getUDMapperRefs().begin(); }
  mapperlist_iterator mapperlist_end() { return getUDMapperRefs().end(); }
  mapperlist_const_iterator mapperlist_begin() const {
    return getUDMapperRefs().begin();
  }
  mapperlist_const_iterator mapperlist_end() const {
    return getUDMapperRefs().end();
  }
  mapperlist_range mapperlists() {
    return mapperlist_range(mapperlist_begin(), mapperlist_end());
  }
  mapperlist_const_range mapperlists() const {
    return mapperlist_const_range(mapperlist_begin(), mapperlist_end());
  }
};

/// This represents clause 'map' in the '#pragma omp ...'
/// directives.
///
/// \code
/// #pragma omp target map(a,b)
/// \endcode
/// In this example directive '#pragma omp target' has clause 'map'
/// with the variables 'a' and 'b'.
class OMPMapClause final : public OMPMappableExprListClause<OMPMapClause>,
                           private llvm::TrailingObjects<
                               OMPMapClause, Expr *, ValueDecl *, unsigned,
                               OMPClauseMappableExprCommon::MappableComponent> {
  friend class OMPClauseReader;
  friend OMPMappableExprListClause;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Define the sizes of each trailing object array except the last one. This
  /// is required for TrailingObjects to work properly.
  size_t numTrailingObjects(OverloadToken<Expr *>) const {
    // There are varlist_size() of expressions, and varlist_size() of
    // user-defined mappers.
    return 2 * varlist_size();
  }
  size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
    return getUniqueDeclarationsNum();
  }
  size_t numTrailingObjects(OverloadToken<unsigned>) const {
    return getUniqueDeclarationsNum() + getTotalComponentListNum();
  }

private:
  /// Map-type-modifiers for the 'map' clause.
  OpenMPMapModifierKind MapTypeModifiers[NumberOfOMPMapClauseModifiers] = {
      OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
      OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
      OMPC_MAP_MODIFIER_unknown};

  /// Location of map-type-modifiers for the 'map' clause.
  SourceLocation MapTypeModifiersLoc[NumberOfOMPMapClauseModifiers];

  /// Map type for the 'map' clause.
  OpenMPMapClauseKind MapType = OMPC_MAP_unknown;

  /// Is this an implicit map type or not.
  bool MapTypeIsImplicit = false;

  /// Location of the map type.
  SourceLocation MapLoc;

  /// Colon location.
  SourceLocation ColonLoc;

  /// Build a clause for \a NumVars listed expressions, \a
  /// NumUniqueDeclarations declarations, \a NumComponentLists total component
  /// lists, and \a NumComponents total expression components.
  ///
  /// \param MapModifiers Map-type-modifiers.
  /// \param MapModifiersLoc Locations of map-type-modifiers.
  /// \param MapperQualifierLoc C++ nested name specifier for the associated
  /// user-defined mapper.
  /// \param MapperIdInfo The identifier of associated user-defined mapper.
  /// \param MapType Map type.
  /// \param MapTypeIsImplicit Map type is inferred implicitly.
  /// \param MapLoc Location of the map type.
  /// \param Locs Locations needed to build a mappable clause. It includes 1)
  /// StartLoc: starting location of the clause (the clause keyword); 2)
  /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  explicit OMPMapClause(ArrayRef<OpenMPMapModifierKind> MapModifiers,
                        ArrayRef<SourceLocation> MapModifiersLoc,
                        NestedNameSpecifierLoc MapperQualifierLoc,
                        DeclarationNameInfo MapperIdInfo,
                        OpenMPMapClauseKind MapType, bool MapTypeIsImplicit,
                        SourceLocation MapLoc, const OMPVarListLocTy &Locs,
                        const OMPMappableExprListSizeTy &Sizes)
      : OMPMappableExprListClause(llvm::omp::OMPC_map, Locs, Sizes,
                                  /*SupportsMapper=*/true, &MapperQualifierLoc,
                                  &MapperIdInfo),
        MapType(MapType), MapTypeIsImplicit(MapTypeIsImplicit), MapLoc(MapLoc) {
    assert(std::size(MapTypeModifiers) == MapModifiers.size() &&
           "Unexpected number of map type modifiers.");
    llvm::copy(MapModifiers, std::begin(MapTypeModifiers));

    assert(std::size(MapTypeModifiersLoc) == MapModifiersLoc.size() &&
           "Unexpected number of map type modifier locations.");
    llvm::copy(MapModifiersLoc, std::begin(MapTypeModifiersLoc));
  }

  /// Build an empty clause.
  ///
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  explicit OMPMapClause(const OMPMappableExprListSizeTy &Sizes)
      : OMPMappableExprListClause(llvm::omp::OMPC_map, OMPVarListLocTy(), Sizes,
                                  /*SupportsMapper=*/true) {}

  /// Set map-type-modifier for the clause.
  ///
  /// \param I index for map-type-modifier.
  /// \param T map-type-modifier for the clause.
  void setMapTypeModifier(unsigned I, OpenMPMapModifierKind T) {
    assert(I < NumberOfOMPMapClauseModifiers &&
           "Unexpected index to store map type modifier, exceeds array size.");
    MapTypeModifiers[I] = T;
  }

  /// Set location for the map-type-modifier.
  ///
  /// \param I index for map-type-modifier location.
  /// \param TLoc map-type-modifier location.
  void setMapTypeModifierLoc(unsigned I, SourceLocation TLoc) {
    assert(I < NumberOfOMPMapClauseModifiers &&
           "Index to store map type modifier location exceeds array size.");
    MapTypeModifiersLoc[I] = TLoc;
  }

  /// Set type for the clause.
  ///
  /// \param T Type for the clause.
  void setMapType(OpenMPMapClauseKind T) { MapType = T; }

  /// Set type location.
  ///
  /// \param TLoc Type location.
  void setMapLoc(SourceLocation TLoc) { MapLoc = TLoc; }

  /// Set colon location.
  void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }

public:
  /// Creates clause with a list of variables \a VL.
  ///
  /// \param C AST context.
  /// \param Locs Locations needed to build a mappable clause. It includes 1)
  /// StartLoc: starting location of the clause (the clause keyword); 2)
  /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
  /// \param Vars The original expression used in the clause.
  /// \param Declarations Declarations used in the clause.
  /// \param ComponentLists Component lists used in the clause.
  /// \param UDMapperRefs References to user-defined mappers associated with
  /// expressions used in the clause.
  /// \param MapModifiers Map-type-modifiers.
  /// \param MapModifiersLoc Location of map-type-modifiers.
  /// \param UDMQualifierLoc C++ nested name specifier for the associated
  /// user-defined mapper.
  /// \param MapperId The identifier of associated user-defined mapper.
  /// \param Type Map type.
  /// \param TypeIsImplicit Map type is inferred implicitly.
  /// \param TypeLoc Location of the map type.
  static OMPMapClause *
  Create(const ASTContext &C, const OMPVarListLocTy &Locs,
         ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations,
         MappableExprComponentListsRef ComponentLists,
         ArrayRef<Expr *> UDMapperRefs,
         ArrayRef<OpenMPMapModifierKind> MapModifiers,
         ArrayRef<SourceLocation> MapModifiersLoc,
         NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId,
         OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc);

  /// Creates an empty clause with the place for \a NumVars original
  /// expressions, \a NumUniqueDeclarations declarations, \NumComponentLists
  /// lists, and \a NumComponents expression components.
  ///
  /// \param C AST context.
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  static OMPMapClause *CreateEmpty(const ASTContext &C,
                                   const OMPMappableExprListSizeTy &Sizes);

  /// Fetches mapping kind for the clause.
  OpenMPMapClauseKind getMapType() const LLVM_READONLY { return MapType; }

  /// Is this an implicit map type?
  /// We have to capture 'IsMapTypeImplicit' from the parser for more
  /// informative error messages.  It helps distinguish map(r) from
  /// map(tofrom: r), which is important to print more helpful error
  /// messages for some target directives.
  bool isImplicitMapType() const LLVM_READONLY { return MapTypeIsImplicit; }

  /// Fetches the map-type-modifier at 'Cnt' index of array of modifiers.
  ///
  /// \param Cnt index for map-type-modifier.
  OpenMPMapModifierKind getMapTypeModifier(unsigned Cnt) const LLVM_READONLY {
    assert(Cnt < NumberOfOMPMapClauseModifiers &&
           "Requested modifier exceeds the total number of modifiers.");
    return MapTypeModifiers[Cnt];
  }

  /// Fetches the map-type-modifier location at 'Cnt' index of array of
  /// modifiers' locations.
  ///
  /// \param Cnt index for map-type-modifier location.
  SourceLocation getMapTypeModifierLoc(unsigned Cnt) const LLVM_READONLY {
    assert(Cnt < NumberOfOMPMapClauseModifiers &&
           "Requested modifier location exceeds total number of modifiers.");
    return MapTypeModifiersLoc[Cnt];
  }

  /// Fetches ArrayRef of map-type-modifiers.
  ArrayRef<OpenMPMapModifierKind> getMapTypeModifiers() const LLVM_READONLY {
    return llvm::makeArrayRef(MapTypeModifiers);
  }

  /// Fetches ArrayRef of location of map-type-modifiers.
  ArrayRef<SourceLocation> getMapTypeModifiersLoc() const LLVM_READONLY {
    return llvm::makeArrayRef(MapTypeModifiersLoc);
  }

  /// Fetches location of clause mapping kind.
  SourceLocation getMapLoc() const LLVM_READONLY { return MapLoc; }

  /// Get colon location.
  SourceLocation getColonLoc() const { return ColonLoc; }

  child_range children() {
    return child_range(
        reinterpret_cast<Stmt **>(varlist_begin()),
        reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPMapClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    if (MapType == OMPC_MAP_to || MapType == OMPC_MAP_tofrom)
      return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                         reinterpret_cast<Stmt **>(varlist_end()));
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    auto Children = const_cast<OMPMapClause *>(this)->used_children();
    return const_child_range(Children.begin(), Children.end());
  }


  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_map;
  }
};

/// This represents 'num_teams' clause in the '#pragma omp ...'
/// directive.
///
/// \code
/// #pragma omp teams num_teams(n)
/// \endcode
/// In this example directive '#pragma omp teams' has clause 'num_teams'
/// with single expression 'n'.
class OMPNumTeamsClause : public OMPClause, public OMPClauseWithPreInit {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// NumTeams number.
  Stmt *NumTeams = nullptr;

  /// Set the NumTeams number.
  ///
  /// \param E NumTeams number.
  void setNumTeams(Expr *E) { NumTeams = E; }

public:
  /// Build 'num_teams' clause.
  ///
  /// \param E Expression associated with this clause.
  /// \param HelperE Helper Expression associated with this clause.
  /// \param CaptureRegion Innermost OpenMP region where expressions in this
  /// clause must be captured.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPNumTeamsClause(Expr *E, Stmt *HelperE, OpenMPDirectiveKind CaptureRegion,
                    SourceLocation StartLoc, SourceLocation LParenLoc,
                    SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_num_teams, StartLoc, EndLoc),
        OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTeams(E) {
    setPreInitStmt(HelperE, CaptureRegion);
  }

  /// Build an empty clause.
  OMPNumTeamsClause()
      : OMPClause(llvm::omp::OMPC_num_teams, SourceLocation(),
                  SourceLocation()),
        OMPClauseWithPreInit(this) {}

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Return NumTeams number.
  Expr *getNumTeams() { return cast<Expr>(NumTeams); }

  /// Return NumTeams number.
  Expr *getNumTeams() const { return cast<Expr>(NumTeams); }

  child_range children() { return child_range(&NumTeams, &NumTeams + 1); }

  const_child_range children() const {
    return const_child_range(&NumTeams, &NumTeams + 1);
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_num_teams;
  }
};

/// This represents 'thread_limit' clause in the '#pragma omp ...'
/// directive.
///
/// \code
/// #pragma omp teams thread_limit(n)
/// \endcode
/// In this example directive '#pragma omp teams' has clause 'thread_limit'
/// with single expression 'n'.
class OMPThreadLimitClause : public OMPClause, public OMPClauseWithPreInit {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// ThreadLimit number.
  Stmt *ThreadLimit = nullptr;

  /// Set the ThreadLimit number.
  ///
  /// \param E ThreadLimit number.
  void setThreadLimit(Expr *E) { ThreadLimit = E; }

public:
  /// Build 'thread_limit' clause.
  ///
  /// \param E Expression associated with this clause.
  /// \param HelperE Helper Expression associated with this clause.
  /// \param CaptureRegion Innermost OpenMP region where expressions in this
  /// clause must be captured.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPThreadLimitClause(Expr *E, Stmt *HelperE,
                       OpenMPDirectiveKind CaptureRegion,
                       SourceLocation StartLoc, SourceLocation LParenLoc,
                       SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_thread_limit, StartLoc, EndLoc),
        OMPClauseWithPreInit(this), LParenLoc(LParenLoc), ThreadLimit(E) {
    setPreInitStmt(HelperE, CaptureRegion);
  }

  /// Build an empty clause.
  OMPThreadLimitClause()
      : OMPClause(llvm::omp::OMPC_thread_limit, SourceLocation(),
                  SourceLocation()),
        OMPClauseWithPreInit(this) {}

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Return ThreadLimit number.
  Expr *getThreadLimit() { return cast<Expr>(ThreadLimit); }

  /// Return ThreadLimit number.
  Expr *getThreadLimit() const { return cast<Expr>(ThreadLimit); }

  child_range children() { return child_range(&ThreadLimit, &ThreadLimit + 1); }

  const_child_range children() const {
    return const_child_range(&ThreadLimit, &ThreadLimit + 1);
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_thread_limit;
  }
};

/// This represents 'priority' clause in the '#pragma omp ...'
/// directive.
///
/// \code
/// #pragma omp task priority(n)
/// \endcode
/// In this example directive '#pragma omp teams' has clause 'priority' with
/// single expression 'n'.
class OMPPriorityClause : public OMPClause, public OMPClauseWithPreInit {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Priority number.
  Stmt *Priority = nullptr;

  /// Set the Priority number.
  ///
  /// \param E Priority number.
  void setPriority(Expr *E) { Priority = E; }

public:
  /// Build 'priority' clause.
  ///
  /// \param Priority Expression associated with this clause.
  /// \param HelperPriority Helper priority for the construct.
  /// \param CaptureRegion Innermost OpenMP region where expressions in this
  /// clause must be captured.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPPriorityClause(Expr *Priority, Stmt *HelperPriority,
                    OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
                    SourceLocation LParenLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_priority, StartLoc, EndLoc),
        OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Priority(Priority) {
    setPreInitStmt(HelperPriority, CaptureRegion);
  }

  /// Build an empty clause.
  OMPPriorityClause()
      : OMPClause(llvm::omp::OMPC_priority, SourceLocation(), SourceLocation()),
        OMPClauseWithPreInit(this) {}

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Return Priority number.
  Expr *getPriority() { return cast<Expr>(Priority); }

  /// Return Priority number.
  Expr *getPriority() const { return cast<Expr>(Priority); }

  child_range children() { return child_range(&Priority, &Priority + 1); }

  const_child_range children() const {
    return const_child_range(&Priority, &Priority + 1);
  }

  child_range used_children();
  const_child_range used_children() const {
    auto Children = const_cast<OMPPriorityClause *>(this)->used_children();
    return const_child_range(Children.begin(), Children.end());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_priority;
  }
};

/// This represents 'grainsize' clause in the '#pragma omp ...'
/// directive.
///
/// \code
/// #pragma omp taskloop grainsize(4)
/// \endcode
/// In this example directive '#pragma omp taskloop' has clause 'grainsize'
/// with single expression '4'.
class OMPGrainsizeClause : public OMPClause, public OMPClauseWithPreInit {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Safe iteration space distance.
  Stmt *Grainsize = nullptr;

  /// Set safelen.
  void setGrainsize(Expr *Size) { Grainsize = Size; }

public:
  /// Build 'grainsize' clause.
  ///
  /// \param Size Expression associated with this clause.
  /// \param HelperSize Helper grainsize for the construct.
  /// \param CaptureRegion Innermost OpenMP region where expressions in this
  /// clause must be captured.
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPGrainsizeClause(Expr *Size, Stmt *HelperSize,
                     OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
                     SourceLocation LParenLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_grainsize, StartLoc, EndLoc),
        OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Grainsize(Size) {
    setPreInitStmt(HelperSize, CaptureRegion);
  }

  /// Build an empty clause.
  explicit OMPGrainsizeClause()
      : OMPClause(llvm::omp::OMPC_grainsize, SourceLocation(),
                  SourceLocation()),
        OMPClauseWithPreInit(this) {}

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Return safe iteration space distance.
  Expr *getGrainsize() const { return cast_or_null<Expr>(Grainsize); }

  child_range children() { return child_range(&Grainsize, &Grainsize + 1); }

  const_child_range children() const {
    return const_child_range(&Grainsize, &Grainsize + 1);
  }

  child_range used_children();
  const_child_range used_children() const {
    auto Children = const_cast<OMPGrainsizeClause *>(this)->used_children();
    return const_child_range(Children.begin(), Children.end());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_grainsize;
  }
};

/// This represents 'nogroup' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp taskloop nogroup
/// \endcode
/// In this example directive '#pragma omp taskloop' has 'nogroup' clause.
class OMPNogroupClause : public OMPClause {
public:
  /// Build 'nogroup' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_nogroup, StartLoc, EndLoc) {}

  /// Build an empty clause.
  OMPNogroupClause()
      : OMPClause(llvm::omp::OMPC_nogroup, SourceLocation(), SourceLocation()) {
  }

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_nogroup;
  }
};

/// This represents 'num_tasks' clause in the '#pragma omp ...'
/// directive.
///
/// \code
/// #pragma omp taskloop num_tasks(4)
/// \endcode
/// In this example directive '#pragma omp taskloop' has clause 'num_tasks'
/// with single expression '4'.
class OMPNumTasksClause : public OMPClause, public OMPClauseWithPreInit {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Safe iteration space distance.
  Stmt *NumTasks = nullptr;

  /// Set safelen.
  void setNumTasks(Expr *Size) { NumTasks = Size; }

public:
  /// Build 'num_tasks' clause.
  ///
  /// \param Size Expression associated with this clause.
  /// \param HelperSize Helper grainsize for the construct.
  /// \param CaptureRegion Innermost OpenMP region where expressions in this
  /// clause must be captured.
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPNumTasksClause(Expr *Size, Stmt *HelperSize,
                    OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
                    SourceLocation LParenLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_num_tasks, StartLoc, EndLoc),
        OMPClauseWithPreInit(this), LParenLoc(LParenLoc), NumTasks(Size) {
    setPreInitStmt(HelperSize, CaptureRegion);
  }

  /// Build an empty clause.
  explicit OMPNumTasksClause()
      : OMPClause(llvm::omp::OMPC_num_tasks, SourceLocation(),
                  SourceLocation()),
        OMPClauseWithPreInit(this) {}

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Return safe iteration space distance.
  Expr *getNumTasks() const { return cast_or_null<Expr>(NumTasks); }

  child_range children() { return child_range(&NumTasks, &NumTasks + 1); }

  const_child_range children() const {
    return const_child_range(&NumTasks, &NumTasks + 1);
  }

  child_range used_children();
  const_child_range used_children() const {
    auto Children = const_cast<OMPNumTasksClause *>(this)->used_children();
    return const_child_range(Children.begin(), Children.end());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_num_tasks;
  }
};

/// This represents 'hint' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp critical (name) hint(6)
/// \endcode
/// In this example directive '#pragma omp critical' has name 'name' and clause
/// 'hint' with argument '6'.
class OMPHintClause : public OMPClause {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Hint expression of the 'hint' clause.
  Stmt *Hint = nullptr;

  /// Set hint expression.
  void setHint(Expr *H) { Hint = H; }

public:
  /// Build 'hint' clause with expression \a Hint.
  ///
  /// \param Hint Hint expression.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc,
                SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_hint, StartLoc, EndLoc), LParenLoc(LParenLoc),
        Hint(Hint) {}

  /// Build an empty clause.
  OMPHintClause()
      : OMPClause(llvm::omp::OMPC_hint, SourceLocation(), SourceLocation()) {}

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Returns number of threads.
  Expr *getHint() const { return cast_or_null<Expr>(Hint); }

  child_range children() { return child_range(&Hint, &Hint + 1); }

  const_child_range children() const {
    return const_child_range(&Hint, &Hint + 1);
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_hint;
  }
};

/// This represents 'dist_schedule' clause in the '#pragma omp ...'
/// directive.
///
/// \code
/// #pragma omp distribute dist_schedule(static, 3)
/// \endcode
/// In this example directive '#pragma omp distribute' has 'dist_schedule'
/// clause with arguments 'static' and '3'.
class OMPDistScheduleClause : public OMPClause, public OMPClauseWithPreInit {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// A kind of the 'schedule' clause.
  OpenMPDistScheduleClauseKind Kind = OMPC_DIST_SCHEDULE_unknown;

  /// Start location of the schedule kind in source code.
  SourceLocation KindLoc;

  /// Location of ',' (if any).
  SourceLocation CommaLoc;

  /// Chunk size.
  Expr *ChunkSize = nullptr;

  /// Set schedule kind.
  ///
  /// \param K Schedule kind.
  void setDistScheduleKind(OpenMPDistScheduleClauseKind K) { Kind = K; }

  /// Sets the location of '('.
  ///
  /// \param Loc Location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Set schedule kind start location.
  ///
  /// \param KLoc Schedule kind location.
  void setDistScheduleKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }

  /// Set location of ','.
  ///
  /// \param Loc Location of ','.
  void setCommaLoc(SourceLocation Loc) { CommaLoc = Loc; }

  /// Set chunk size.
  ///
  /// \param E Chunk size.
  void setChunkSize(Expr *E) { ChunkSize = E; }

public:
  /// Build 'dist_schedule' clause with schedule kind \a Kind and chunk
  /// size expression \a ChunkSize.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param KLoc Starting location of the argument.
  /// \param CommaLoc Location of ','.
  /// \param EndLoc Ending location of the clause.
  /// \param Kind DistSchedule kind.
  /// \param ChunkSize Chunk size.
  /// \param HelperChunkSize Helper chunk size for combined directives.
  OMPDistScheduleClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                        SourceLocation KLoc, SourceLocation CommaLoc,
                        SourceLocation EndLoc,
                        OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize,
                        Stmt *HelperChunkSize)
      : OMPClause(llvm::omp::OMPC_dist_schedule, StartLoc, EndLoc),
        OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Kind(Kind),
        KindLoc(KLoc), CommaLoc(CommaLoc), ChunkSize(ChunkSize) {
    setPreInitStmt(HelperChunkSize);
  }

  /// Build an empty clause.
  explicit OMPDistScheduleClause()
      : OMPClause(llvm::omp::OMPC_dist_schedule, SourceLocation(),
                  SourceLocation()),
        OMPClauseWithPreInit(this) {}

  /// Get kind of the clause.
  OpenMPDistScheduleClauseKind getDistScheduleKind() const { return Kind; }

  /// Get location of '('.
  SourceLocation getLParenLoc() { return LParenLoc; }

  /// Get kind location.
  SourceLocation getDistScheduleKindLoc() { return KindLoc; }

  /// Get location of ','.
  SourceLocation getCommaLoc() { return CommaLoc; }

  /// Get chunk size.
  Expr *getChunkSize() { return ChunkSize; }

  /// Get chunk size.
  const Expr *getChunkSize() const { return ChunkSize; }

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(&ChunkSize),
                       reinterpret_cast<Stmt **>(&ChunkSize) + 1);
  }

  const_child_range children() const {
    auto Children = const_cast<OMPDistScheduleClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_dist_schedule;
  }
};

/// This represents 'defaultmap' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp target defaultmap(tofrom: scalar)
/// \endcode
/// In this example directive '#pragma omp target' has 'defaultmap' clause of kind
/// 'scalar' with modifier 'tofrom'.
class OMPDefaultmapClause : public OMPClause {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Modifiers for 'defaultmap' clause.
  OpenMPDefaultmapClauseModifier Modifier = OMPC_DEFAULTMAP_MODIFIER_unknown;

  /// Locations of modifiers.
  SourceLocation ModifierLoc;

  /// A kind of the 'defaultmap' clause.
  OpenMPDefaultmapClauseKind Kind = OMPC_DEFAULTMAP_unknown;

  /// Start location of the defaultmap kind in source code.
  SourceLocation KindLoc;

  /// Set defaultmap kind.
  ///
  /// \param K Defaultmap kind.
  void setDefaultmapKind(OpenMPDefaultmapClauseKind K) { Kind = K; }

  /// Set the defaultmap modifier.
  ///
  /// \param M Defaultmap modifier.
  void setDefaultmapModifier(OpenMPDefaultmapClauseModifier M) {
    Modifier = M;
  }

  /// Set location of the defaultmap modifier.
  void setDefaultmapModifierLoc(SourceLocation Loc) {
    ModifierLoc = Loc;
  }

  /// Sets the location of '('.
  ///
  /// \param Loc Location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Set defaultmap kind start location.
  ///
  /// \param KLoc Defaultmap kind location.
  void setDefaultmapKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }

public:
  /// Build 'defaultmap' clause with defaultmap kind \a Kind
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param KLoc Starting location of the argument.
  /// \param EndLoc Ending location of the clause.
  /// \param Kind Defaultmap kind.
  /// \param M The modifier applied to 'defaultmap' clause.
  /// \param MLoc Location of the modifier
  OMPDefaultmapClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                      SourceLocation MLoc, SourceLocation KLoc,
                      SourceLocation EndLoc, OpenMPDefaultmapClauseKind Kind,
                      OpenMPDefaultmapClauseModifier M)
      : OMPClause(llvm::omp::OMPC_defaultmap, StartLoc, EndLoc),
        LParenLoc(LParenLoc), Modifier(M), ModifierLoc(MLoc), Kind(Kind),
        KindLoc(KLoc) {}

  /// Build an empty clause.
  explicit OMPDefaultmapClause()
      : OMPClause(llvm::omp::OMPC_defaultmap, SourceLocation(),
                  SourceLocation()) {}

  /// Get kind of the clause.
  OpenMPDefaultmapClauseKind getDefaultmapKind() const { return Kind; }

  /// Get the modifier of the clause.
  OpenMPDefaultmapClauseModifier getDefaultmapModifier() const {
    return Modifier;
  }

  /// Get location of '('.
  SourceLocation getLParenLoc() { return LParenLoc; }

  /// Get kind location.
  SourceLocation getDefaultmapKindLoc() { return KindLoc; }

  /// Get the modifier location.
  SourceLocation getDefaultmapModifierLoc() const {
    return ModifierLoc;
  }

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_defaultmap;
  }
};

/// This represents clause 'to' in the '#pragma omp ...'
/// directives.
///
/// \code
/// #pragma omp target update to(a,b)
/// \endcode
/// In this example directive '#pragma omp target update' has clause 'to'
/// with the variables 'a' and 'b'.
class OMPToClause final : public OMPMappableExprListClause<OMPToClause>,
                          private llvm::TrailingObjects<
                              OMPToClause, Expr *, ValueDecl *, unsigned,
                              OMPClauseMappableExprCommon::MappableComponent> {
  friend class OMPClauseReader;
  friend OMPMappableExprListClause;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Motion-modifiers for the 'to' clause.
  OpenMPMotionModifierKind MotionModifiers[NumberOfOMPMotionModifiers] = {
      OMPC_MOTION_MODIFIER_unknown, OMPC_MOTION_MODIFIER_unknown};

  /// Location of motion-modifiers for the 'to' clause.
  SourceLocation MotionModifiersLoc[NumberOfOMPMotionModifiers];

  /// Colon location.
  SourceLocation ColonLoc;

  /// Build clause with number of variables \a NumVars.
  ///
  /// \param TheMotionModifiers Motion-modifiers.
  /// \param TheMotionModifiersLoc Locations of motion-modifiers.
  /// \param MapperQualifierLoc C++ nested name specifier for the associated
  /// user-defined mapper.
  /// \param MapperIdInfo The identifier of associated user-defined mapper.
  /// \param Locs Locations needed to build a mappable clause. It includes 1)
  /// StartLoc: starting location of the clause (the clause keyword); 2)
  /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  explicit OMPToClause(ArrayRef<OpenMPMotionModifierKind> TheMotionModifiers,
                       ArrayRef<SourceLocation> TheMotionModifiersLoc,
                       NestedNameSpecifierLoc MapperQualifierLoc,
                       DeclarationNameInfo MapperIdInfo,
                       const OMPVarListLocTy &Locs,
                       const OMPMappableExprListSizeTy &Sizes)
      : OMPMappableExprListClause(llvm::omp::OMPC_to, Locs, Sizes,
                                  /*SupportsMapper=*/true, &MapperQualifierLoc,
                                  &MapperIdInfo) {
    assert(std::size(MotionModifiers) == TheMotionModifiers.size() &&
           "Unexpected number of motion modifiers.");
    llvm::copy(TheMotionModifiers, std::begin(MotionModifiers));

    assert(std::size(MotionModifiersLoc) == TheMotionModifiersLoc.size() &&
           "Unexpected number of motion modifier locations.");
    llvm::copy(TheMotionModifiersLoc, std::begin(MotionModifiersLoc));
  }

  /// Build an empty clause.
  ///
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  explicit OMPToClause(const OMPMappableExprListSizeTy &Sizes)
      : OMPMappableExprListClause(llvm::omp::OMPC_to, OMPVarListLocTy(), Sizes,
                                  /*SupportsMapper=*/true) {}

  /// Set motion-modifier for the clause.
  ///
  /// \param I index for motion-modifier.
  /// \param T motion-modifier for the clause.
  void setMotionModifier(unsigned I, OpenMPMotionModifierKind T) {
    assert(I < NumberOfOMPMotionModifiers &&
           "Unexpected index to store motion modifier, exceeds array size.");
    MotionModifiers[I] = T;
  }

  /// Set location for the motion-modifier.
  ///
  /// \param I index for motion-modifier location.
  /// \param TLoc motion-modifier location.
  void setMotionModifierLoc(unsigned I, SourceLocation TLoc) {
    assert(I < NumberOfOMPMotionModifiers &&
           "Index to store motion modifier location exceeds array size.");
    MotionModifiersLoc[I] = TLoc;
  }

  /// Set colon location.
  void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }

  /// Define the sizes of each trailing object array except the last one. This
  /// is required for TrailingObjects to work properly.
  size_t numTrailingObjects(OverloadToken<Expr *>) const {
    // There are varlist_size() of expressions, and varlist_size() of
    // user-defined mappers.
    return 2 * varlist_size();
  }
  size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
    return getUniqueDeclarationsNum();
  }
  size_t numTrailingObjects(OverloadToken<unsigned>) const {
    return getUniqueDeclarationsNum() + getTotalComponentListNum();
  }

public:
  /// Creates clause with a list of variables \a Vars.
  ///
  /// \param C AST context.
  /// \param Locs Locations needed to build a mappable clause. It includes 1)
  /// StartLoc: starting location of the clause (the clause keyword); 2)
  /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
  /// \param Vars The original expression used in the clause.
  /// \param Declarations Declarations used in the clause.
  /// \param ComponentLists Component lists used in the clause.
  /// \param MotionModifiers Motion-modifiers.
  /// \param MotionModifiersLoc Location of motion-modifiers.
  /// \param UDMapperRefs References to user-defined mappers associated with
  /// expressions used in the clause.
  /// \param UDMQualifierLoc C++ nested name specifier for the associated
  /// user-defined mapper.
  /// \param MapperId The identifier of associated user-defined mapper.
  static OMPToClause *Create(const ASTContext &C, const OMPVarListLocTy &Locs,
                             ArrayRef<Expr *> Vars,
                             ArrayRef<ValueDecl *> Declarations,
                             MappableExprComponentListsRef ComponentLists,
                             ArrayRef<Expr *> UDMapperRefs,
                             ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
                             ArrayRef<SourceLocation> MotionModifiersLoc,
                             NestedNameSpecifierLoc UDMQualifierLoc,
                             DeclarationNameInfo MapperId);

  /// Creates an empty clause with the place for \a NumVars variables.
  ///
  /// \param C AST context.
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  static OMPToClause *CreateEmpty(const ASTContext &C,
                                  const OMPMappableExprListSizeTy &Sizes);

  /// Fetches the motion-modifier at 'Cnt' index of array of modifiers.
  ///
  /// \param Cnt index for motion-modifier.
  OpenMPMotionModifierKind getMotionModifier(unsigned Cnt) const LLVM_READONLY {
    assert(Cnt < NumberOfOMPMotionModifiers &&
           "Requested modifier exceeds the total number of modifiers.");
    return MotionModifiers[Cnt];
  }

  /// Fetches the motion-modifier location at 'Cnt' index of array of modifiers'
  /// locations.
  ///
  /// \param Cnt index for motion-modifier location.
  SourceLocation getMotionModifierLoc(unsigned Cnt) const LLVM_READONLY {
    assert(Cnt < NumberOfOMPMotionModifiers &&
           "Requested modifier location exceeds total number of modifiers.");
    return MotionModifiersLoc[Cnt];
  }

  /// Fetches ArrayRef of motion-modifiers.
  ArrayRef<OpenMPMotionModifierKind> getMotionModifiers() const LLVM_READONLY {
    return llvm::makeArrayRef(MotionModifiers);
  }

  /// Fetches ArrayRef of location of motion-modifiers.
  ArrayRef<SourceLocation> getMotionModifiersLoc() const LLVM_READONLY {
    return llvm::makeArrayRef(MotionModifiersLoc);
  }

  /// Get colon location.
  SourceLocation getColonLoc() const { return ColonLoc; }

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPToClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_to;
  }
};

/// This represents clause 'from' in the '#pragma omp ...'
/// directives.
///
/// \code
/// #pragma omp target update from(a,b)
/// \endcode
/// In this example directive '#pragma omp target update' has clause 'from'
/// with the variables 'a' and 'b'.
class OMPFromClause final
    : public OMPMappableExprListClause<OMPFromClause>,
      private llvm::TrailingObjects<
          OMPFromClause, Expr *, ValueDecl *, unsigned,
          OMPClauseMappableExprCommon::MappableComponent> {
  friend class OMPClauseReader;
  friend OMPMappableExprListClause;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Motion-modifiers for the 'from' clause.
  OpenMPMotionModifierKind MotionModifiers[NumberOfOMPMotionModifiers] = {
      OMPC_MOTION_MODIFIER_unknown, OMPC_MOTION_MODIFIER_unknown};

  /// Location of motion-modifiers for the 'from' clause.
  SourceLocation MotionModifiersLoc[NumberOfOMPMotionModifiers];

  /// Colon location.
  SourceLocation ColonLoc;

  /// Build clause with number of variables \a NumVars.
  ///
  /// \param TheMotionModifiers Motion-modifiers.
  /// \param TheMotionModifiersLoc Locations of motion-modifiers.
  /// \param MapperQualifierLoc C++ nested name specifier for the associated
  /// user-defined mapper.
  /// \param MapperIdInfo The identifier of associated user-defined mapper.
  /// \param Locs Locations needed to build a mappable clause. It includes 1)
  /// StartLoc: starting location of the clause (the clause keyword); 2)
  /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  explicit OMPFromClause(ArrayRef<OpenMPMotionModifierKind> TheMotionModifiers,
                         ArrayRef<SourceLocation> TheMotionModifiersLoc,
                         NestedNameSpecifierLoc MapperQualifierLoc,
                         DeclarationNameInfo MapperIdInfo,
                         const OMPVarListLocTy &Locs,
                         const OMPMappableExprListSizeTy &Sizes)
      : OMPMappableExprListClause(llvm::omp::OMPC_from, Locs, Sizes,
                                  /*SupportsMapper=*/true, &MapperQualifierLoc,
                                  &MapperIdInfo) {
    assert(std::size(MotionModifiers) == TheMotionModifiers.size() &&
           "Unexpected number of motion modifiers.");
    llvm::copy(TheMotionModifiers, std::begin(MotionModifiers));

    assert(std::size(MotionModifiersLoc) == TheMotionModifiersLoc.size() &&
           "Unexpected number of motion modifier locations.");
    llvm::copy(TheMotionModifiersLoc, std::begin(MotionModifiersLoc));
  }

  /// Build an empty clause.
  ///
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  explicit OMPFromClause(const OMPMappableExprListSizeTy &Sizes)
      : OMPMappableExprListClause(llvm::omp::OMPC_from, OMPVarListLocTy(),
                                  Sizes, /*SupportsMapper=*/true) {}

  /// Set motion-modifier for the clause.
  ///
  /// \param I index for motion-modifier.
  /// \param T motion-modifier for the clause.
  void setMotionModifier(unsigned I, OpenMPMotionModifierKind T) {
    assert(I < NumberOfOMPMotionModifiers &&
           "Unexpected index to store motion modifier, exceeds array size.");
    MotionModifiers[I] = T;
  }

  /// Set location for the motion-modifier.
  ///
  /// \param I index for motion-modifier location.
  /// \param TLoc motion-modifier location.
  void setMotionModifierLoc(unsigned I, SourceLocation TLoc) {
    assert(I < NumberOfOMPMotionModifiers &&
           "Index to store motion modifier location exceeds array size.");
    MotionModifiersLoc[I] = TLoc;
  }

  /// Set colon location.
  void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }

  /// Define the sizes of each trailing object array except the last one. This
  /// is required for TrailingObjects to work properly.
  size_t numTrailingObjects(OverloadToken<Expr *>) const {
    // There are varlist_size() of expressions, and varlist_size() of
    // user-defined mappers.
    return 2 * varlist_size();
  }
  size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
    return getUniqueDeclarationsNum();
  }
  size_t numTrailingObjects(OverloadToken<unsigned>) const {
    return getUniqueDeclarationsNum() + getTotalComponentListNum();
  }

public:
  /// Creates clause with a list of variables \a Vars.
  ///
  /// \param C AST context.
  /// \param Locs Locations needed to build a mappable clause. It includes 1)
  /// StartLoc: starting location of the clause (the clause keyword); 2)
  /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
  /// \param Vars The original expression used in the clause.
  /// \param Declarations Declarations used in the clause.
  /// \param ComponentLists Component lists used in the clause.
  /// \param MotionModifiers Motion-modifiers.
  /// \param MotionModifiersLoc Location of motion-modifiers.
  /// \param UDMapperRefs References to user-defined mappers associated with
  /// expressions used in the clause.
  /// \param UDMQualifierLoc C++ nested name specifier for the associated
  /// user-defined mapper.
  /// \param MapperId The identifier of associated user-defined mapper.
  static OMPFromClause *
  Create(const ASTContext &C, const OMPVarListLocTy &Locs,
         ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations,
         MappableExprComponentListsRef ComponentLists,
         ArrayRef<Expr *> UDMapperRefs,
         ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
         ArrayRef<SourceLocation> MotionModifiersLoc,
         NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId);

  /// Creates an empty clause with the place for \a NumVars variables.
  ///
  /// \param C AST context.
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  static OMPFromClause *CreateEmpty(const ASTContext &C,
                                    const OMPMappableExprListSizeTy &Sizes);

  /// Fetches the motion-modifier at 'Cnt' index of array of modifiers.
  ///
  /// \param Cnt index for motion-modifier.
  OpenMPMotionModifierKind getMotionModifier(unsigned Cnt) const LLVM_READONLY {
    assert(Cnt < NumberOfOMPMotionModifiers &&
           "Requested modifier exceeds the total number of modifiers.");
    return MotionModifiers[Cnt];
  }

  /// Fetches the motion-modifier location at 'Cnt' index of array of modifiers'
  /// locations.
  ///
  /// \param Cnt index for motion-modifier location.
  SourceLocation getMotionModifierLoc(unsigned Cnt) const LLVM_READONLY {
    assert(Cnt < NumberOfOMPMotionModifiers &&
           "Requested modifier location exceeds total number of modifiers.");
    return MotionModifiersLoc[Cnt];
  }

  /// Fetches ArrayRef of motion-modifiers.
  ArrayRef<OpenMPMotionModifierKind> getMotionModifiers() const LLVM_READONLY {
    return llvm::makeArrayRef(MotionModifiers);
  }

  /// Fetches ArrayRef of location of motion-modifiers.
  ArrayRef<SourceLocation> getMotionModifiersLoc() const LLVM_READONLY {
    return llvm::makeArrayRef(MotionModifiersLoc);
  }

  /// Get colon location.
  SourceLocation getColonLoc() const { return ColonLoc; }

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPFromClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_from;
  }
};

/// This represents clause 'use_device_ptr' in the '#pragma omp ...'
/// directives.
///
/// \code
/// #pragma omp target data use_device_ptr(a,b)
/// \endcode
/// In this example directive '#pragma omp target data' has clause
/// 'use_device_ptr' with the variables 'a' and 'b'.
class OMPUseDevicePtrClause final
    : public OMPMappableExprListClause<OMPUseDevicePtrClause>,
      private llvm::TrailingObjects<
          OMPUseDevicePtrClause, Expr *, ValueDecl *, unsigned,
          OMPClauseMappableExprCommon::MappableComponent> {
  friend class OMPClauseReader;
  friend OMPMappableExprListClause;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Build clause with number of variables \a NumVars.
  ///
  /// \param Locs Locations needed to build a mappable clause. It includes 1)
  /// StartLoc: starting location of the clause (the clause keyword); 2)
  /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  explicit OMPUseDevicePtrClause(const OMPVarListLocTy &Locs,
                                 const OMPMappableExprListSizeTy &Sizes)
      : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr, Locs, Sizes) {
  }

  /// Build an empty clause.
  ///
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  explicit OMPUseDevicePtrClause(const OMPMappableExprListSizeTy &Sizes)
      : OMPMappableExprListClause(llvm::omp::OMPC_use_device_ptr,
                                  OMPVarListLocTy(), Sizes) {}

  /// Define the sizes of each trailing object array except the last one. This
  /// is required for TrailingObjects to work properly.
  size_t numTrailingObjects(OverloadToken<Expr *>) const {
    return 3 * varlist_size();
  }
  size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
    return getUniqueDeclarationsNum();
  }
  size_t numTrailingObjects(OverloadToken<unsigned>) const {
    return getUniqueDeclarationsNum() + getTotalComponentListNum();
  }

  /// Sets the list of references to private copies with initializers for new
  /// private variables.
  /// \param VL List of references.
  void setPrivateCopies(ArrayRef<Expr *> VL);

  /// Gets the list of references to private copies with initializers for new
  /// private variables.
  MutableArrayRef<Expr *> getPrivateCopies() {
    return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
  }
  ArrayRef<const Expr *> getPrivateCopies() const {
    return llvm::makeArrayRef(varlist_end(), varlist_size());
  }

  /// Sets the list of references to initializer variables for new private
  /// variables.
  /// \param VL List of references.
  void setInits(ArrayRef<Expr *> VL);

  /// Gets the list of references to initializer variables for new private
  /// variables.
  MutableArrayRef<Expr *> getInits() {
    return MutableArrayRef<Expr *>(getPrivateCopies().end(), varlist_size());
  }
  ArrayRef<const Expr *> getInits() const {
    return llvm::makeArrayRef(getPrivateCopies().end(), varlist_size());
  }

public:
  /// Creates clause with a list of variables \a Vars.
  ///
  /// \param C AST context.
  /// \param Locs Locations needed to build a mappable clause. It includes 1)
  /// StartLoc: starting location of the clause (the clause keyword); 2)
  /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
  /// \param Vars The original expression used in the clause.
  /// \param PrivateVars Expressions referring to private copies.
  /// \param Inits Expressions referring to private copy initializers.
  /// \param Declarations Declarations used in the clause.
  /// \param ComponentLists Component lists used in the clause.
  static OMPUseDevicePtrClause *
  Create(const ASTContext &C, const OMPVarListLocTy &Locs,
         ArrayRef<Expr *> Vars, ArrayRef<Expr *> PrivateVars,
         ArrayRef<Expr *> Inits, ArrayRef<ValueDecl *> Declarations,
         MappableExprComponentListsRef ComponentLists);

  /// Creates an empty clause with the place for \a NumVars variables.
  ///
  /// \param C AST context.
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  static OMPUseDevicePtrClause *
  CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes);

  using private_copies_iterator = MutableArrayRef<Expr *>::iterator;
  using private_copies_const_iterator = ArrayRef<const Expr *>::iterator;
  using private_copies_range = llvm::iterator_range<private_copies_iterator>;
  using private_copies_const_range =
      llvm::iterator_range<private_copies_const_iterator>;

  private_copies_range private_copies() {
    return private_copies_range(getPrivateCopies().begin(),
                                getPrivateCopies().end());
  }

  private_copies_const_range private_copies() const {
    return private_copies_const_range(getPrivateCopies().begin(),
                                      getPrivateCopies().end());
  }

  using inits_iterator = MutableArrayRef<Expr *>::iterator;
  using inits_const_iterator = ArrayRef<const Expr *>::iterator;
  using inits_range = llvm::iterator_range<inits_iterator>;
  using inits_const_range = llvm::iterator_range<inits_const_iterator>;

  inits_range inits() {
    return inits_range(getInits().begin(), getInits().end());
  }

  inits_const_range inits() const {
    return inits_const_range(getInits().begin(), getInits().end());
  }

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPUseDevicePtrClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_use_device_ptr;
  }
};

/// This represents clause 'use_device_addr' in the '#pragma omp ...'
/// directives.
///
/// \code
/// #pragma omp target data use_device_addr(a,b)
/// \endcode
/// In this example directive '#pragma omp target data' has clause
/// 'use_device_addr' with the variables 'a' and 'b'.
class OMPUseDeviceAddrClause final
    : public OMPMappableExprListClause<OMPUseDeviceAddrClause>,
      private llvm::TrailingObjects<
          OMPUseDeviceAddrClause, Expr *, ValueDecl *, unsigned,
          OMPClauseMappableExprCommon::MappableComponent> {
  friend class OMPClauseReader;
  friend OMPMappableExprListClause;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Build clause with number of variables \a NumVars.
  ///
  /// \param Locs Locations needed to build a mappable clause. It includes 1)
  /// StartLoc: starting location of the clause (the clause keyword); 2)
  /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  explicit OMPUseDeviceAddrClause(const OMPVarListLocTy &Locs,
                                  const OMPMappableExprListSizeTy &Sizes)
      : OMPMappableExprListClause(llvm::omp::OMPC_use_device_addr, Locs,
                                  Sizes) {}

  /// Build an empty clause.
  ///
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  explicit OMPUseDeviceAddrClause(const OMPMappableExprListSizeTy &Sizes)
      : OMPMappableExprListClause(llvm::omp::OMPC_use_device_addr,
                                  OMPVarListLocTy(), Sizes) {}

  /// Define the sizes of each trailing object array except the last one. This
  /// is required for TrailingObjects to work properly.
  size_t numTrailingObjects(OverloadToken<Expr *>) const {
    return varlist_size();
  }
  size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
    return getUniqueDeclarationsNum();
  }
  size_t numTrailingObjects(OverloadToken<unsigned>) const {
    return getUniqueDeclarationsNum() + getTotalComponentListNum();
  }

public:
  /// Creates clause with a list of variables \a Vars.
  ///
  /// \param C AST context.
  /// \param Locs Locations needed to build a mappable clause. It includes 1)
  /// StartLoc: starting location of the clause (the clause keyword); 2)
  /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
  /// \param Vars The original expression used in the clause.
  /// \param Declarations Declarations used in the clause.
  /// \param ComponentLists Component lists used in the clause.
  static OMPUseDeviceAddrClause *
  Create(const ASTContext &C, const OMPVarListLocTy &Locs,
         ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations,
         MappableExprComponentListsRef ComponentLists);

  /// Creates an empty clause with the place for \a NumVars variables.
  ///
  /// \param C AST context.
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  static OMPUseDeviceAddrClause *
  CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes);

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPUseDeviceAddrClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_use_device_addr;
  }
};

/// This represents clause 'is_device_ptr' in the '#pragma omp ...'
/// directives.
///
/// \code
/// #pragma omp target is_device_ptr(a,b)
/// \endcode
/// In this example directive '#pragma omp target' has clause
/// 'is_device_ptr' with the variables 'a' and 'b'.
class OMPIsDevicePtrClause final
    : public OMPMappableExprListClause<OMPIsDevicePtrClause>,
      private llvm::TrailingObjects<
          OMPIsDevicePtrClause, Expr *, ValueDecl *, unsigned,
          OMPClauseMappableExprCommon::MappableComponent> {
  friend class OMPClauseReader;
  friend OMPMappableExprListClause;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Build clause with number of variables \a NumVars.
  ///
  /// \param Locs Locations needed to build a mappable clause. It includes 1)
  /// StartLoc: starting location of the clause (the clause keyword); 2)
  /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  explicit OMPIsDevicePtrClause(const OMPVarListLocTy &Locs,
                                const OMPMappableExprListSizeTy &Sizes)
      : OMPMappableExprListClause(llvm::omp::OMPC_is_device_ptr, Locs, Sizes) {}

  /// Build an empty clause.
  ///
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  explicit OMPIsDevicePtrClause(const OMPMappableExprListSizeTy &Sizes)
      : OMPMappableExprListClause(llvm::omp::OMPC_is_device_ptr,
                                  OMPVarListLocTy(), Sizes) {}

  /// Define the sizes of each trailing object array except the last one. This
  /// is required for TrailingObjects to work properly.
  size_t numTrailingObjects(OverloadToken<Expr *>) const {
    return varlist_size();
  }
  size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
    return getUniqueDeclarationsNum();
  }
  size_t numTrailingObjects(OverloadToken<unsigned>) const {
    return getUniqueDeclarationsNum() + getTotalComponentListNum();
  }

public:
  /// Creates clause with a list of variables \a Vars.
  ///
  /// \param C AST context.
  /// \param Locs Locations needed to build a mappable clause. It includes 1)
  /// StartLoc: starting location of the clause (the clause keyword); 2)
  /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
  /// \param Vars The original expression used in the clause.
  /// \param Declarations Declarations used in the clause.
  /// \param ComponentLists Component lists used in the clause.
  static OMPIsDevicePtrClause *
  Create(const ASTContext &C, const OMPVarListLocTy &Locs,
         ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations,
         MappableExprComponentListsRef ComponentLists);

  /// Creates an empty clause with the place for \a NumVars variables.
  ///
  /// \param C AST context.
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  static OMPIsDevicePtrClause *
  CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes);

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPIsDevicePtrClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_is_device_ptr;
  }
};

/// This represents clause 'has_device_ptr' in the '#pragma omp ...'
/// directives.
///
/// \code
/// #pragma omp target has_device_addr(a,b)
/// \endcode
/// In this example directive '#pragma omp target' has clause
/// 'has_device_ptr' with the variables 'a' and 'b'.
class OMPHasDeviceAddrClause final
    : public OMPMappableExprListClause<OMPHasDeviceAddrClause>,
      private llvm::TrailingObjects<
          OMPHasDeviceAddrClause, Expr *, ValueDecl *, unsigned,
          OMPClauseMappableExprCommon::MappableComponent> {
  friend class OMPClauseReader;
  friend OMPMappableExprListClause;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Build clause with number of variables \a NumVars.
  ///
  /// \param Locs Locations needed to build a mappable clause. It includes 1)
  /// StartLoc: starting location of the clause (the clause keyword); 2)
  /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  explicit OMPHasDeviceAddrClause(const OMPVarListLocTy &Locs,
                                  const OMPMappableExprListSizeTy &Sizes)
      : OMPMappableExprListClause(llvm::omp::OMPC_has_device_addr, Locs,
                                  Sizes) {}

  /// Build an empty clause.
  ///
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  explicit OMPHasDeviceAddrClause(const OMPMappableExprListSizeTy &Sizes)
      : OMPMappableExprListClause(llvm::omp::OMPC_has_device_addr,
                                  OMPVarListLocTy(), Sizes) {}

  /// Define the sizes of each trailing object array except the last one. This
  /// is required for TrailingObjects to work properly.
  size_t numTrailingObjects(OverloadToken<Expr *>) const {
    return varlist_size();
  }
  size_t numTrailingObjects(OverloadToken<ValueDecl *>) const {
    return getUniqueDeclarationsNum();
  }
  size_t numTrailingObjects(OverloadToken<unsigned>) const {
    return getUniqueDeclarationsNum() + getTotalComponentListNum();
  }

public:
  /// Creates clause with a list of variables \a Vars.
  ///
  /// \param C AST context.
  /// \param Locs Locations needed to build a mappable clause. It includes 1)
  /// StartLoc: starting location of the clause (the clause keyword); 2)
  /// LParenLoc: location of '('; 3) EndLoc: ending location of the clause.
  /// \param Vars The original expression used in the clause.
  /// \param Declarations Declarations used in the clause.
  /// \param ComponentLists Component lists used in the clause.
  static OMPHasDeviceAddrClause *
  Create(const ASTContext &C, const OMPVarListLocTy &Locs,
         ArrayRef<Expr *> Vars, ArrayRef<ValueDecl *> Declarations,
         MappableExprComponentListsRef ComponentLists);

  /// Creates an empty clause with the place for \a NumVars variables.
  ///
  /// \param C AST context.
  /// \param Sizes All required sizes to build a mappable clause. It includes 1)
  /// NumVars: number of expressions listed in this clause; 2)
  /// NumUniqueDeclarations: number of unique base declarations in this clause;
  /// 3) NumComponentLists: number of component lists in this clause; and 4)
  /// NumComponents: total number of expression components in the clause.
  static OMPHasDeviceAddrClause *
  CreateEmpty(const ASTContext &C, const OMPMappableExprListSizeTy &Sizes);

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPHasDeviceAddrClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_has_device_addr;
  }
};

/// This represents clause 'nontemporal' in the '#pragma omp ...' directives.
///
/// \code
/// #pragma omp simd nontemporal(a)
/// \endcode
/// In this example directive '#pragma omp simd' has clause 'nontemporal' for
/// the variable 'a'.
class OMPNontemporalClause final
    : public OMPVarListClause<OMPNontemporalClause>,
      private llvm::TrailingObjects<OMPNontemporalClause, Expr *> {
  friend class OMPClauseReader;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Build clause with number of variables \a N.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param N Number of the variables in the clause.
  OMPNontemporalClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                       SourceLocation EndLoc, unsigned N)
      : OMPVarListClause<OMPNontemporalClause>(llvm::omp::OMPC_nontemporal,
                                               StartLoc, LParenLoc, EndLoc, N) {
  }

  /// Build an empty clause.
  ///
  /// \param N Number of variables.
  explicit OMPNontemporalClause(unsigned N)
      : OMPVarListClause<OMPNontemporalClause>(
            llvm::omp::OMPC_nontemporal, SourceLocation(), SourceLocation(),
            SourceLocation(), N) {}

  /// Get the list of privatied copies if the member expression was captured by
  /// one of the privatization clauses.
  MutableArrayRef<Expr *> getPrivateRefs() {
    return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
  }
  ArrayRef<const Expr *> getPrivateRefs() const {
    return llvm::makeArrayRef(varlist_end(), varlist_size());
  }

public:
  /// Creates clause with a list of variables \a VL.
  ///
  /// \param C AST context.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param VL List of references to the variables.
  static OMPNontemporalClause *
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
         SourceLocation EndLoc, ArrayRef<Expr *> VL);

  /// Creates an empty clause with the place for \a N variables.
  ///
  /// \param C AST context.
  /// \param N The number of variables.
  static OMPNontemporalClause *CreateEmpty(const ASTContext &C, unsigned N);

  /// Sets the list of references to private copies created in private clauses.
  /// \param VL List of references.
  void setPrivateRefs(ArrayRef<Expr *> VL);

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPNontemporalClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range private_refs() {
    return child_range(reinterpret_cast<Stmt **>(getPrivateRefs().begin()),
                       reinterpret_cast<Stmt **>(getPrivateRefs().end()));
  }

  const_child_range private_refs() const {
    auto Children = const_cast<OMPNontemporalClause *>(this)->private_refs();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_nontemporal;
  }
};

/// This represents 'order' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp simd order(concurrent)
/// \endcode
/// In this example directive '#pragma omp parallel' has simple 'order'
/// clause with kind 'concurrent'.
class OMPOrderClause final : public OMPClause {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// A kind of the 'default' clause.
  OpenMPOrderClauseKind Kind = OMPC_ORDER_unknown;

  /// Start location of the kind in source code.
  SourceLocation KindKwLoc;

  /// Set kind of the clause.
  ///
  /// \param K Argument of clause.
  void setKind(OpenMPOrderClauseKind K) { Kind = K; }

  /// Set argument location.
  ///
  /// \param KLoc Argument location.
  void setKindKwLoc(SourceLocation KLoc) { KindKwLoc = KLoc; }

public:
  /// Build 'order' clause with argument \p A ('concurrent').
  ///
  /// \param A Argument of the clause ('concurrent').
  /// \param ALoc Starting location of the argument.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPOrderClause(OpenMPOrderClauseKind A, SourceLocation ALoc,
                 SourceLocation StartLoc, SourceLocation LParenLoc,
                 SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_order, StartLoc, EndLoc),
        LParenLoc(LParenLoc), Kind(A), KindKwLoc(ALoc) {}

  /// Build an empty clause.
  OMPOrderClause()
      : OMPClause(llvm::omp::OMPC_order, SourceLocation(), SourceLocation()) {}

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Returns kind of the clause.
  OpenMPOrderClauseKind getKind() const { return Kind; }

  /// Returns location of clause kind.
  SourceLocation getKindKwLoc() const { return KindKwLoc; }

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_order;
  }
};

/// This represents the 'init' clause in '#pragma omp ...' directives.
///
/// \code
/// #pragma omp interop init(target:obj)
/// \endcode
class OMPInitClause final
    : public OMPVarListClause<OMPInitClause>,
      private llvm::TrailingObjects<OMPInitClause, Expr *> {
  friend class OMPClauseReader;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Location of interop variable.
  SourceLocation VarLoc;

  bool IsTarget = false;
  bool IsTargetSync = false;

  void setInteropVar(Expr *E) { varlist_begin()[0] = E; }

  void setIsTarget(bool V) { IsTarget = V; }

  void setIsTargetSync(bool V) { IsTargetSync = V; }

  /// Sets the location of the interop variable.
  void setVarLoc(SourceLocation Loc) { VarLoc = Loc; }

  /// Build 'init' clause.
  ///
  /// \param IsTarget Uses the 'target' interop-type.
  /// \param IsTargetSync Uses the 'targetsync' interop-type.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param VarLoc Location of the interop variable.
  /// \param EndLoc Ending location of the clause.
  /// \param N Number of expressions.
  OMPInitClause(bool IsTarget, bool IsTargetSync, SourceLocation StartLoc,
                SourceLocation LParenLoc, SourceLocation VarLoc,
                SourceLocation EndLoc, unsigned N)
      : OMPVarListClause<OMPInitClause>(llvm::omp::OMPC_init, StartLoc,
                                        LParenLoc, EndLoc, N),
        VarLoc(VarLoc), IsTarget(IsTarget), IsTargetSync(IsTargetSync) {}

  /// Build an empty clause.
  OMPInitClause(unsigned N)
      : OMPVarListClause<OMPInitClause>(llvm::omp::OMPC_init, SourceLocation(),
                                        SourceLocation(), SourceLocation(), N) {
  }

public:
  /// Creates a fully specified clause.
  ///
  /// \param C AST context.
  /// \param InteropVar The interop variable.
  /// \param InteropInfo The interop-type and prefer_type list.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param VarLoc Location of the interop variable.
  /// \param EndLoc Ending location of the clause.
  static OMPInitClause *Create(const ASTContext &C, Expr *InteropVar,
                               OMPInteropInfo &InteropInfo,
                               SourceLocation StartLoc,
                               SourceLocation LParenLoc, SourceLocation VarLoc,
                               SourceLocation EndLoc);

  /// Creates an empty clause with \a N expressions.
  ///
  /// \param C AST context.
  /// \param N Number of expression items.
  static OMPInitClause *CreateEmpty(const ASTContext &C, unsigned N);

  /// Returns the location of the interop variable.
  SourceLocation getVarLoc() const { return VarLoc; }

  /// Returns the interop variable.
  Expr *getInteropVar() { return varlist_begin()[0]; }
  const Expr *getInteropVar() const { return varlist_begin()[0]; }

  /// Returns true is interop-type 'target' is used.
  bool getIsTarget() const { return IsTarget; }

  /// Returns true is interop-type 'targetsync' is used.
  bool getIsTargetSync() const { return IsTargetSync; }

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPInitClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  using prefs_iterator = MutableArrayRef<Expr *>::iterator;
  using const_prefs_iterator = ArrayRef<const Expr *>::iterator;
  using prefs_range = llvm::iterator_range<prefs_iterator>;
  using const_prefs_range = llvm::iterator_range<const_prefs_iterator>;

  prefs_range prefs() {
    return prefs_range(reinterpret_cast<Expr **>(std::next(varlist_begin())),
                       reinterpret_cast<Expr **>(varlist_end()));
  }

  const_prefs_range prefs() const {
    auto Prefs = const_cast<OMPInitClause *>(this)->prefs();
    return const_prefs_range(Prefs.begin(), Prefs.end());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_init;
  }
};

/// This represents the 'use' clause in '#pragma omp ...' directives.
///
/// \code
/// #pragma omp interop use(obj)
/// \endcode
class OMPUseClause final : public OMPClause {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Location of interop variable.
  SourceLocation VarLoc;

  /// The interop variable.
  Stmt *InteropVar = nullptr;

  /// Set the interop variable.
  void setInteropVar(Expr *E) { InteropVar = E; }

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Sets the location of the interop variable.
  void setVarLoc(SourceLocation Loc) { VarLoc = Loc; }

public:
  /// Build 'use' clause with and interop variable expression \a InteropVar.
  ///
  /// \param InteropVar The interop variable.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param VarLoc Location of the interop variable.
  /// \param EndLoc Ending location of the clause.
  OMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
               SourceLocation LParenLoc, SourceLocation VarLoc,
               SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_use, StartLoc, EndLoc), LParenLoc(LParenLoc),
        VarLoc(VarLoc), InteropVar(InteropVar) {}

  /// Build an empty clause.
  OMPUseClause()
      : OMPClause(llvm::omp::OMPC_use, SourceLocation(), SourceLocation()) {}

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Returns the location of the interop variable.
  SourceLocation getVarLoc() const { return VarLoc; }

  /// Returns the interop variable.
  Expr *getInteropVar() const { return cast<Expr>(InteropVar); }

  child_range children() { return child_range(&InteropVar, &InteropVar + 1); }

  const_child_range children() const {
    return const_child_range(&InteropVar, &InteropVar + 1);
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_use;
  }
};

/// This represents 'destroy' clause in the '#pragma omp depobj'
/// directive or the '#pragma omp interop' directive..
///
/// \code
/// #pragma omp depobj(a) destroy
/// #pragma omp interop destroy(obj)
/// \endcode
/// In these examples directive '#pragma omp depobj' and '#pragma omp interop'
/// have a 'destroy' clause. The 'interop' directive includes an object.
class OMPDestroyClause final : public OMPClause {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Location of interop variable.
  SourceLocation VarLoc;

  /// The interop variable.
  Stmt *InteropVar = nullptr;

  /// Set the interop variable.
  void setInteropVar(Expr *E) { InteropVar = E; }

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Sets the location of the interop variable.
  void setVarLoc(SourceLocation Loc) { VarLoc = Loc; }

public:
  /// Build 'destroy' clause with an interop variable expression \a InteropVar.
  ///
  /// \param InteropVar The interop variable.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param VarLoc Location of the interop variable.
  /// \param EndLoc Ending location of the clause.
  OMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,
                   SourceLocation LParenLoc, SourceLocation VarLoc,
                   SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_destroy, StartLoc, EndLoc),
        LParenLoc(LParenLoc), VarLoc(VarLoc), InteropVar(InteropVar) {}

  /// Build 'destroy' clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param EndLoc Ending location of the clause.
  OMPDestroyClause(SourceLocation StartLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_destroy, StartLoc, EndLoc) {}

  /// Build an empty clause.
  OMPDestroyClause()
      : OMPClause(llvm::omp::OMPC_destroy, SourceLocation(), SourceLocation()) {
  }

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Returns the location of the interop variable.
  SourceLocation getVarLoc() const { return VarLoc; }

  /// Returns the interop variable.
  Expr *getInteropVar() const { return cast_or_null<Expr>(InteropVar); }

  child_range children() {
    if (InteropVar)
      return child_range(&InteropVar, &InteropVar + 1);
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    if (InteropVar)
      return const_child_range(&InteropVar, &InteropVar + 1);
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_destroy;
  }
};

/// This represents 'novariants' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp dispatch novariants(a > 5)
/// \endcode
/// In this example directive '#pragma omp dispatch' has simple 'novariants'
/// clause with condition 'a > 5'.
class OMPNovariantsClause final : public OMPClause,
                                  public OMPClauseWithPreInit {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Condition of the 'if' clause.
  Stmt *Condition = nullptr;

  /// Set condition.
  void setCondition(Expr *Cond) { Condition = Cond; }

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

public:
  /// Build 'novariants' clause with condition \a Cond.
  ///
  /// \param Cond Condition of the clause.
  /// \param HelperCond Helper condition for the construct.
  /// \param CaptureRegion Innermost OpenMP region where expressions in this
  /// clause must be captured.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPNovariantsClause(Expr *Cond, Stmt *HelperCond,
                      OpenMPDirectiveKind CaptureRegion,
                      SourceLocation StartLoc, SourceLocation LParenLoc,
                      SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_novariants, StartLoc, EndLoc),
        OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond) {
    setPreInitStmt(HelperCond, CaptureRegion);
  }

  /// Build an empty clause.
  OMPNovariantsClause()
      : OMPClause(llvm::omp::OMPC_novariants, SourceLocation(),
                  SourceLocation()),
        OMPClauseWithPreInit(this) {}

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Returns condition.
  Expr *getCondition() const { return cast_or_null<Expr>(Condition); }

  child_range children() { return child_range(&Condition, &Condition + 1); }

  const_child_range children() const {
    return const_child_range(&Condition, &Condition + 1);
  }

  child_range used_children();
  const_child_range used_children() const {
    auto Children = const_cast<OMPNovariantsClause *>(this)->used_children();
    return const_child_range(Children.begin(), Children.end());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_novariants;
  }
};

/// This represents 'nocontext' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp dispatch nocontext(a > 5)
/// \endcode
/// In this example directive '#pragma omp dispatch' has simple 'nocontext'
/// clause with condition 'a > 5'.
class OMPNocontextClause final : public OMPClause, public OMPClauseWithPreInit {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Condition of the 'if' clause.
  Stmt *Condition = nullptr;

  /// Set condition.
  void setCondition(Expr *Cond) { Condition = Cond; }

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

public:
  /// Build 'nocontext' clause with condition \a Cond.
  ///
  /// \param Cond Condition of the clause.
  /// \param HelperCond Helper condition for the construct.
  /// \param CaptureRegion Innermost OpenMP region where expressions in this
  /// clause must be captured.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPNocontextClause(Expr *Cond, Stmt *HelperCond,
                     OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
                     SourceLocation LParenLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_nocontext, StartLoc, EndLoc),
        OMPClauseWithPreInit(this), LParenLoc(LParenLoc), Condition(Cond) {
    setPreInitStmt(HelperCond, CaptureRegion);
  }

  /// Build an empty clause.
  OMPNocontextClause()
      : OMPClause(llvm::omp::OMPC_nocontext, SourceLocation(),
                  SourceLocation()),
        OMPClauseWithPreInit(this) {}

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Returns condition.
  Expr *getCondition() const { return cast_or_null<Expr>(Condition); }

  child_range children() { return child_range(&Condition, &Condition + 1); }

  const_child_range children() const {
    return const_child_range(&Condition, &Condition + 1);
  }

  child_range used_children();
  const_child_range used_children() const {
    auto Children = const_cast<OMPNocontextClause *>(this)->used_children();
    return const_child_range(Children.begin(), Children.end());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_nocontext;
  }
};

/// This represents 'detach' clause in the '#pragma omp task' directive.
///
/// \code
/// #pragma omp task detach(evt)
/// \endcode
/// In this example directive '#pragma omp detach' has simple 'detach' clause
/// with the variable 'evt'.
class OMPDetachClause final : public OMPClause {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Expression of the 'detach' clause.
  Stmt *Evt = nullptr;

  /// Set condition.
  void setEventHandler(Expr *E) { Evt = E; }

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

public:
  /// Build 'detach' clause with event-handler \a Evt.
  ///
  /// \param Evt Event handler expression.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPDetachClause(Expr *Evt, SourceLocation StartLoc, SourceLocation LParenLoc,
                  SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_detach, StartLoc, EndLoc),
        LParenLoc(LParenLoc), Evt(Evt) {}

  /// Build an empty clause.
  OMPDetachClause()
      : OMPClause(llvm::omp::OMPC_detach, SourceLocation(), SourceLocation()) {}

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Returns event-handler expression.
  Expr *getEventHandler() const { return cast_or_null<Expr>(Evt); }

  child_range children() { return child_range(&Evt, &Evt + 1); }

  const_child_range children() const {
    return const_child_range(&Evt, &Evt + 1);
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_detach;
  }
};

/// This represents clause 'inclusive' in the '#pragma omp scan' directive.
///
/// \code
/// #pragma omp scan inclusive(a,b)
/// \endcode
/// In this example directive '#pragma omp scan' has clause 'inclusive'
/// with the variables 'a' and 'b'.
class OMPInclusiveClause final
    : public OMPVarListClause<OMPInclusiveClause>,
      private llvm::TrailingObjects<OMPInclusiveClause, Expr *> {
  friend class OMPClauseReader;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Build clause with number of variables \a N.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param N Number of the variables in the clause.
  OMPInclusiveClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                     SourceLocation EndLoc, unsigned N)
      : OMPVarListClause<OMPInclusiveClause>(llvm::omp::OMPC_inclusive,
                                             StartLoc, LParenLoc, EndLoc, N) {}

  /// Build an empty clause.
  ///
  /// \param N Number of variables.
  explicit OMPInclusiveClause(unsigned N)
      : OMPVarListClause<OMPInclusiveClause>(llvm::omp::OMPC_inclusive,
                                             SourceLocation(), SourceLocation(),
                                             SourceLocation(), N) {}

public:
  /// Creates clause with a list of variables \a VL.
  ///
  /// \param C AST context.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param VL List of references to the original variables.
  static OMPInclusiveClause *Create(const ASTContext &C,
                                    SourceLocation StartLoc,
                                    SourceLocation LParenLoc,
                                    SourceLocation EndLoc, ArrayRef<Expr *> VL);

  /// Creates an empty clause with the place for \a N variables.
  ///
  /// \param C AST context.
  /// \param N The number of variables.
  static OMPInclusiveClause *CreateEmpty(const ASTContext &C, unsigned N);

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPInclusiveClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_inclusive;
  }
};

/// This represents clause 'exclusive' in the '#pragma omp scan' directive.
///
/// \code
/// #pragma omp scan exclusive(a,b)
/// \endcode
/// In this example directive '#pragma omp scan' has clause 'exclusive'
/// with the variables 'a' and 'b'.
class OMPExclusiveClause final
    : public OMPVarListClause<OMPExclusiveClause>,
      private llvm::TrailingObjects<OMPExclusiveClause, Expr *> {
  friend class OMPClauseReader;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Build clause with number of variables \a N.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param N Number of the variables in the clause.
  OMPExclusiveClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                     SourceLocation EndLoc, unsigned N)
      : OMPVarListClause<OMPExclusiveClause>(llvm::omp::OMPC_exclusive,
                                             StartLoc, LParenLoc, EndLoc, N) {}

  /// Build an empty clause.
  ///
  /// \param N Number of variables.
  explicit OMPExclusiveClause(unsigned N)
      : OMPVarListClause<OMPExclusiveClause>(llvm::omp::OMPC_exclusive,
                                             SourceLocation(), SourceLocation(),
                                             SourceLocation(), N) {}

public:
  /// Creates clause with a list of variables \a VL.
  ///
  /// \param C AST context.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param VL List of references to the original variables.
  static OMPExclusiveClause *Create(const ASTContext &C,
                                    SourceLocation StartLoc,
                                    SourceLocation LParenLoc,
                                    SourceLocation EndLoc, ArrayRef<Expr *> VL);

  /// Creates an empty clause with the place for \a N variables.
  ///
  /// \param C AST context.
  /// \param N The number of variables.
  static OMPExclusiveClause *CreateEmpty(const ASTContext &C, unsigned N);

  child_range children() {
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end()));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPExclusiveClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_exclusive;
  }
};

/// This represents clause 'uses_allocators' in the '#pragma omp target'-based
/// directives.
///
/// \code
/// #pragma omp target uses_allocators(default_allocator, my_allocator(traits))
/// \endcode
/// In this example directive '#pragma omp target' has clause 'uses_allocators'
/// with the allocators 'default_allocator' and user-defined 'my_allocator'.
class OMPUsesAllocatorsClause final
    : public OMPClause,
      private llvm::TrailingObjects<OMPUsesAllocatorsClause, Expr *,
                                    SourceLocation> {
public:
  /// Data for list of allocators.
  struct Data {
    /// Allocator.
    Expr *Allocator = nullptr;
    /// Allocator traits.
    Expr *AllocatorTraits = nullptr;
    /// Locations of '(' and ')' symbols.
    SourceLocation LParenLoc, RParenLoc;
  };

private:
  friend class OMPClauseReader;
  friend TrailingObjects;

  enum class ExprOffsets {
    Allocator,
    AllocatorTraits,
    Total,
  };

  enum class ParenLocsOffsets {
    LParen,
    RParen,
    Total,
  };

  /// Location of '('.
  SourceLocation LParenLoc;
  /// Total number of allocators in the clause.
  unsigned NumOfAllocators = 0;

  /// Build clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param N Number of allocators associated with the clause.
  OMPUsesAllocatorsClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                          SourceLocation EndLoc, unsigned N)
      : OMPClause(llvm::omp::OMPC_uses_allocators, StartLoc, EndLoc),
        LParenLoc(LParenLoc), NumOfAllocators(N) {}

  /// Build an empty clause.
  /// \param N Number of allocators associated with the clause.
  ///
  explicit OMPUsesAllocatorsClause(unsigned N)
      : OMPClause(llvm::omp::OMPC_uses_allocators, SourceLocation(),
                  SourceLocation()),
        NumOfAllocators(N) {}

  unsigned numTrailingObjects(OverloadToken<Expr *>) const {
    return NumOfAllocators * static_cast<int>(ExprOffsets::Total);
  }

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Sets the allocators data for the clause.
  void setAllocatorsData(ArrayRef<OMPUsesAllocatorsClause::Data> Data);

public:
  /// Creates clause with a list of allocators \p Data.
  ///
  /// \param C AST context.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  /// \param Data List of allocators.
  static OMPUsesAllocatorsClause *
  Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
         SourceLocation EndLoc, ArrayRef<OMPUsesAllocatorsClause::Data> Data);

  /// Creates an empty clause with the place for \p N allocators.
  ///
  /// \param C AST context.
  /// \param N The number of allocators.
  static OMPUsesAllocatorsClause *CreateEmpty(const ASTContext &C, unsigned N);

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Returns number of allocators associated with the clause.
  unsigned getNumberOfAllocators() const { return NumOfAllocators; }

  /// Returns data for the specified allocator.
  OMPUsesAllocatorsClause::Data getAllocatorData(unsigned I) const;

  // Iterators
  child_range children() {
    Stmt **Begin = reinterpret_cast<Stmt **>(getTrailingObjects<Expr *>());
    return child_range(Begin, Begin + NumOfAllocators *
                                          static_cast<int>(ExprOffsets::Total));
  }
  const_child_range children() const {
    Stmt *const *Begin =
        reinterpret_cast<Stmt *const *>(getTrailingObjects<Expr *>());
    return const_child_range(
        Begin, Begin + NumOfAllocators * static_cast<int>(ExprOffsets::Total));
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_uses_allocators;
  }
};

/// This represents clause 'affinity' in the '#pragma omp task'-based
/// directives.
///
/// \code
/// #pragma omp task affinity(iterator(i = 0:n) : ([3][n])a, b[:n], c[i])
/// \endcode
/// In this example directive '#pragma omp task' has clause 'affinity' with the
/// affinity modifer 'iterator(i = 0:n)' and locator items '([3][n])a', 'b[:n]'
/// and 'c[i]'.
class OMPAffinityClause final
    : public OMPVarListClause<OMPAffinityClause>,
      private llvm::TrailingObjects<OMPAffinityClause, Expr *> {
  friend class OMPClauseReader;
  friend OMPVarListClause;
  friend TrailingObjects;

  /// Location of ':' symbol.
  SourceLocation ColonLoc;

  /// Build clause.
  ///
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param ColonLoc Location of ':'.
  /// \param EndLoc Ending location of the clause.
  /// \param N Number of locators associated with the clause.
  OMPAffinityClause(SourceLocation StartLoc, SourceLocation LParenLoc,
                    SourceLocation ColonLoc, SourceLocation EndLoc, unsigned N)
      : OMPVarListClause<OMPAffinityClause>(llvm::omp::OMPC_affinity, StartLoc,
                                            LParenLoc, EndLoc, N) {}

  /// Build an empty clause.
  /// \param N Number of locators associated with the clause.
  ///
  explicit OMPAffinityClause(unsigned N)
      : OMPVarListClause<OMPAffinityClause>(llvm::omp::OMPC_affinity,
                                            SourceLocation(), SourceLocation(),
                                            SourceLocation(), N) {}

  /// Sets the affinity modifier for the clause, if any.
  void setModifier(Expr *E) {
    getTrailingObjects<Expr *>()[varlist_size()] = E;
  }

  /// Sets the location of ':' symbol.
  void setColonLoc(SourceLocation Loc) { ColonLoc = Loc; }

public:
  /// Creates clause with a modifier a list of locator items.
  ///
  /// \param C AST context.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param ColonLoc Location of ':'.
  /// \param EndLoc Ending location of the clause.
  /// \param Locators List of locator items.
  static OMPAffinityClause *Create(const ASTContext &C, SourceLocation StartLoc,
                                   SourceLocation LParenLoc,
                                   SourceLocation ColonLoc,
                                   SourceLocation EndLoc, Expr *Modifier,
                                   ArrayRef<Expr *> Locators);

  /// Creates an empty clause with the place for \p N locator items.
  ///
  /// \param C AST context.
  /// \param N The number of locator items.
  static OMPAffinityClause *CreateEmpty(const ASTContext &C, unsigned N);

  /// Gets affinity modifier.
  Expr *getModifier() { return getTrailingObjects<Expr *>()[varlist_size()]; }
  Expr *getModifier() const {
    return getTrailingObjects<Expr *>()[varlist_size()];
  }

  /// Gets the location of ':' symbol.
  SourceLocation getColonLoc() const { return ColonLoc; }

  // Iterators
  child_range children() {
    int Offset = getModifier() ? 1 : 0;
    return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
                       reinterpret_cast<Stmt **>(varlist_end() + Offset));
  }

  const_child_range children() const {
    auto Children = const_cast<OMPAffinityClause *>(this)->children();
    return const_child_range(Children.begin(), Children.end());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_affinity;
  }
};

/// This represents 'filter' clause in the '#pragma omp ...' directive.
///
/// \code
/// #pragma omp masked filter(tid)
/// \endcode
/// In this example directive '#pragma omp masked' has 'filter' clause with
/// thread id.
class OMPFilterClause final : public OMPClause, public OMPClauseWithPreInit {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// Express of the 'filter' clause.
  Stmt *ThreadID = nullptr;

  /// Sets the thread identifier.
  void setThreadID(Expr *TID) { ThreadID = TID; }

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

public:
  /// Build 'filter' clause with thread-id \a ThreadID.
  ///
  /// \param ThreadID Thread identifier.
  /// \param HelperE Helper expression associated with this clause.
  /// \param CaptureRegion Innermost OpenMP region where expressions in this
  /// clause must be captured.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPFilterClause(Expr *ThreadID, Stmt *HelperE,
                  OpenMPDirectiveKind CaptureRegion, SourceLocation StartLoc,
                  SourceLocation LParenLoc, SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_filter, StartLoc, EndLoc),
        OMPClauseWithPreInit(this), LParenLoc(LParenLoc), ThreadID(ThreadID) {
    setPreInitStmt(HelperE, CaptureRegion);
  }

  /// Build an empty clause.
  OMPFilterClause()
      : OMPClause(llvm::omp::OMPC_filter, SourceLocation(), SourceLocation()),
        OMPClauseWithPreInit(this) {}
  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Return thread identifier.
  Expr *getThreadID() { return cast<Expr>(ThreadID); }

  /// Return thread identifier.
  Expr *getThreadID() const { return cast<Expr>(ThreadID); }

  child_range children() { return child_range(&ThreadID, &ThreadID + 1); }

  const_child_range children() const {
    return const_child_range(&ThreadID, &ThreadID + 1);
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_filter;
  }
};

/// This represents 'bind' clause in the '#pragma omp ...' directives.
///
/// \code
/// #pragma omp loop bind(parallel)
/// \endcode
class OMPBindClause final : public OMPClause {
  friend class OMPClauseReader;

  /// Location of '('.
  SourceLocation LParenLoc;

  /// The binding kind of 'bind' clause.
  OpenMPBindClauseKind Kind = OMPC_BIND_unknown;

  /// Start location of the kind in source code.
  SourceLocation KindLoc;

  /// Sets the location of '('.
  void setLParenLoc(SourceLocation Loc) { LParenLoc = Loc; }

  /// Set the binding kind.
  void setBindKind(OpenMPBindClauseKind K) { Kind = K; }

  /// Set the binding kind location.
  void setBindKindLoc(SourceLocation KLoc) { KindLoc = KLoc; }

  /// Build 'bind' clause with kind \a K ('teams', 'parallel', or 'thread').
  ///
  /// \param K Binding kind of the clause ('teams', 'parallel' or 'thread').
  /// \param KLoc Starting location of the binding kind.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  OMPBindClause(OpenMPBindClauseKind K, SourceLocation KLoc,
                SourceLocation StartLoc, SourceLocation LParenLoc,
                SourceLocation EndLoc)
      : OMPClause(llvm::omp::OMPC_bind, StartLoc, EndLoc), LParenLoc(LParenLoc),
        Kind(K), KindLoc(KLoc) {}

  /// Build an empty clause.
  OMPBindClause()
      : OMPClause(llvm::omp::OMPC_bind, SourceLocation(), SourceLocation()) {}

public:
  /// Build 'bind' clause with kind \a K ('teams', 'parallel', or 'thread').
  ///
  /// \param C AST context
  /// \param K Binding kind of the clause ('teams', 'parallel' or 'thread').
  /// \param KLoc Starting location of the binding kind.
  /// \param StartLoc Starting location of the clause.
  /// \param LParenLoc Location of '('.
  /// \param EndLoc Ending location of the clause.
  static OMPBindClause *Create(const ASTContext &C, OpenMPBindClauseKind K,
                               SourceLocation KLoc, SourceLocation StartLoc,
                               SourceLocation LParenLoc, SourceLocation EndLoc);

  /// Build an empty 'bind' clause.
  ///
  /// \param C AST context
  static OMPBindClause *CreateEmpty(const ASTContext &C);

  /// Returns the location of '('.
  SourceLocation getLParenLoc() const { return LParenLoc; }

  /// Returns kind of the clause.
  OpenMPBindClauseKind getBindKind() const { return Kind; }

  /// Returns location of clause kind.
  SourceLocation getBindKindLoc() const { return KindLoc; }

  child_range children() {
    return child_range(child_iterator(), child_iterator());
  }

  const_child_range children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  child_range used_children() {
    return child_range(child_iterator(), child_iterator());
  }
  const_child_range used_children() const {
    return const_child_range(const_child_iterator(), const_child_iterator());
  }

  static bool classof(const OMPClause *T) {
    return T->getClauseKind() == llvm::omp::OMPC_bind;
  }
};

/// This class implements a simple visitor for OMPClause
/// subclasses.
template<class ImplClass, template <typename> class Ptr, typename RetTy>
class OMPClauseVisitorBase {
public:
#define PTR(CLASS) Ptr<CLASS>
#define DISPATCH(CLASS) \
  return static_cast<ImplClass*>(this)->Visit##CLASS(static_cast<PTR(CLASS)>(S))

#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class)                                         \
  RetTy Visit##Class(PTR(Class) S) { DISPATCH(Class); }
#include "llvm/Frontend/OpenMP/OMP.inc"

  RetTy Visit(PTR(OMPClause) S) {
    // Top switch clause: visit each OMPClause.
    switch (S->getClauseKind()) {
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class)                                         \
  case llvm::omp::Clause::Enum:                                                \
    return Visit##Class(static_cast<PTR(Class)>(S));
#define CLAUSE_NO_CLASS(Enum, Str)                                             \
  case llvm::omp::Clause::Enum:                                                \
    break;
#include "llvm/Frontend/OpenMP/OMP.inc"
    }
  }
  // Base case, ignore it. :)
  RetTy VisitOMPClause(PTR(OMPClause) Node) { return RetTy(); }
#undef PTR
#undef DISPATCH
};

template <typename T> using const_ptr = std::add_pointer_t<std::add_const_t<T>>;

template <class ImplClass, typename RetTy = void>
class OMPClauseVisitor
    : public OMPClauseVisitorBase<ImplClass, std::add_pointer_t, RetTy> {};
template<class ImplClass, typename RetTy = void>
class ConstOMPClauseVisitor :
      public OMPClauseVisitorBase <ImplClass, const_ptr, RetTy> {};

class OMPClausePrinter final : public OMPClauseVisitor<OMPClausePrinter> {
  raw_ostream &OS;
  const PrintingPolicy &Policy;

  /// Process clauses with list of variables.
  template <typename T> void VisitOMPClauseList(T *Node, char StartSym);
  /// Process motion clauses.
  template <typename T> void VisitOMPMotionClause(T *Node);

public:
  OMPClausePrinter(raw_ostream &OS, const PrintingPolicy &Policy)
      : OS(OS), Policy(Policy) {}

#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(Class *S);
#include "llvm/Frontend/OpenMP/OMP.inc"
};

struct OMPTraitProperty {
  llvm::omp::TraitProperty Kind = llvm::omp::TraitProperty::invalid;

  /// The raw string as we parsed it. This is needed for the `isa` trait set
  /// (which accepts anything) and (later) extensions.
  StringRef RawString;
};
struct OMPTraitSelector {
  Expr *ScoreOrCondition = nullptr;
  llvm::omp::TraitSelector Kind = llvm::omp::TraitSelector::invalid;
  llvm::SmallVector<OMPTraitProperty, 1> Properties;
};
struct OMPTraitSet {
  llvm::omp::TraitSet Kind = llvm::omp::TraitSet::invalid;
  llvm::SmallVector<OMPTraitSelector, 2> Selectors;
};

/// Helper data structure representing the traits in a match clause of an
/// `declare variant` or `metadirective`. The outer level is an ordered
/// collection of selector sets, each with an associated kind and an ordered
/// collection of selectors. A selector has a kind, an optional score/condition,
/// and an ordered collection of properties.
class OMPTraitInfo {
  /// Private constructor accesible only by ASTContext.
  OMPTraitInfo() {}
  friend class ASTContext;

public:
  /// Reconstruct a (partial) OMPTraitInfo object from a mangled name.
  OMPTraitInfo(StringRef MangledName);

  /// The outermost level of selector sets.
  llvm::SmallVector<OMPTraitSet, 2> Sets;

  bool anyScoreOrCondition(
      llvm::function_ref<bool(Expr *&, bool /* IsScore */)> Cond) {
    return llvm::any_of(Sets, [&](OMPTraitSet &Set) {
      return llvm::any_of(
          Set.Selectors, [&](OMPTraitSelector &Selector) {
            return Cond(Selector.ScoreOrCondition,
                        /* IsScore */ Selector.Kind !=
                            llvm::omp::TraitSelector::user_condition);
          });
    });
  }

  /// Create a variant match info object from this trait info object. While the
  /// former is a flat representation the actual main difference is that the
  /// latter uses clang::Expr to store the score/condition while the former is
  /// independent of clang. Thus, expressions and conditions are evaluated in
  /// this method.
  void getAsVariantMatchInfo(ASTContext &ASTCtx,
                             llvm::omp::VariantMatchInfo &VMI) const;

  /// Return a string representation identifying this context selector.
  std::string getMangledName() const;

  /// Check the extension trait \p TP is active.
  bool isExtensionActive(llvm::omp::TraitProperty TP) {
    for (const OMPTraitSet &Set : Sets) {
      if (Set.Kind != llvm::omp::TraitSet::implementation)
        continue;
      for (const OMPTraitSelector &Selector : Set.Selectors) {
        if (Selector.Kind != llvm::omp::TraitSelector::implementation_extension)
          continue;
        for (const OMPTraitProperty &Property : Selector.Properties) {
          if (Property.Kind == TP)
            return true;
        }
      }
    }
    return false;
  }

  /// Print a human readable representation into \p OS.
  void print(llvm::raw_ostream &OS, const PrintingPolicy &Policy) const;
};
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo &TI);
llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo *TI);

/// Clang specific specialization of the OMPContext to lookup target features.
struct TargetOMPContext final : public llvm::omp::OMPContext {
  TargetOMPContext(ASTContext &ASTCtx,
                   std::function<void(StringRef)> &&DiagUnknownTrait,
                   const FunctionDecl *CurrentFunctionDecl,
                   ArrayRef<llvm::omp::TraitProperty> ConstructTraits);

  virtual ~TargetOMPContext() = default;

  /// See llvm::omp::OMPContext::matchesISATrait
  bool matchesISATrait(StringRef RawString) const override;

private:
  std::function<bool(StringRef)> FeatureValidityCheck;
  std::function<void(StringRef)> DiagUnknownTrait;
  llvm::StringMap<bool> FeatureMap;
};

/// Contains data for OpenMP directives: clauses, children
/// expressions/statements (helpers for codegen) and associated statement, if
/// any.
class OMPChildren final
    : private llvm::TrailingObjects<OMPChildren, OMPClause *, Stmt *> {
  friend TrailingObjects;
  friend class OMPClauseReader;
  friend class OMPExecutableDirective;
  template <typename T> friend class OMPDeclarativeDirective;

  /// Numbers of clauses.
  unsigned NumClauses = 0;
  /// Number of child expressions/stmts.
  unsigned NumChildren = 0;
  /// true if the directive has associated statement.
  bool HasAssociatedStmt = false;

  /// Define the sizes of each trailing object array except the last one. This
  /// is required for TrailingObjects to work properly.
  size_t numTrailingObjects(OverloadToken<OMPClause *>) const {
    return NumClauses;
  }

  OMPChildren() = delete;

  OMPChildren(unsigned NumClauses, unsigned NumChildren, bool HasAssociatedStmt)
      : NumClauses(NumClauses), NumChildren(NumChildren),
        HasAssociatedStmt(HasAssociatedStmt) {}

  static size_t size(unsigned NumClauses, bool HasAssociatedStmt,
                     unsigned NumChildren);

  static OMPChildren *Create(void *Mem, ArrayRef<OMPClause *> Clauses);
  static OMPChildren *Create(void *Mem, ArrayRef<OMPClause *> Clauses, Stmt *S,
                             unsigned NumChildren = 0);
  static OMPChildren *CreateEmpty(void *Mem, unsigned NumClauses,
                                  bool HasAssociatedStmt = false,
                                  unsigned NumChildren = 0);

public:
  unsigned getNumClauses() const { return NumClauses; }
  unsigned getNumChildren() const { return NumChildren; }
  bool hasAssociatedStmt() const { return HasAssociatedStmt; }

  /// Set associated statement.
  void setAssociatedStmt(Stmt *S) {
    getTrailingObjects<Stmt *>()[NumChildren] = S;
  }

  void setChildren(ArrayRef<Stmt *> Children);

  /// Sets the list of variables for this clause.
  ///
  /// \param Clauses The list of clauses for the directive.
  ///
  void setClauses(ArrayRef<OMPClause *> Clauses);

  /// Returns statement associated with the directive.
  const Stmt *getAssociatedStmt() const {
    return const_cast<OMPChildren *>(this)->getAssociatedStmt();
  }
  Stmt *getAssociatedStmt() {
    assert(HasAssociatedStmt &&
           "Expected directive with the associated statement.");
    return getTrailingObjects<Stmt *>()[NumChildren];
  }

  /// Get the clauses storage.
  MutableArrayRef<OMPClause *> getClauses() {
    return llvm::makeMutableArrayRef(getTrailingObjects<OMPClause *>(),
                                     NumClauses);
  }
  ArrayRef<OMPClause *> getClauses() const {
    return const_cast<OMPChildren *>(this)->getClauses();
  }

  /// Returns the captured statement associated with the
  /// component region within the (combined) directive.
  ///
  /// \param RegionKind Component region kind.
  const CapturedStmt *
  getCapturedStmt(OpenMPDirectiveKind RegionKind,
                  ArrayRef<OpenMPDirectiveKind> CaptureRegions) const {
    assert(llvm::any_of(
               CaptureRegions,
               [=](const OpenMPDirectiveKind K) { return K == RegionKind; }) &&
           "RegionKind not found in OpenMP CaptureRegions.");
    auto *CS = cast<CapturedStmt>(getAssociatedStmt());
    for (auto ThisCaptureRegion : CaptureRegions) {
      if (ThisCaptureRegion == RegionKind)
        return CS;
      CS = cast<CapturedStmt>(CS->getCapturedStmt());
    }
    llvm_unreachable("Incorrect RegionKind specified for directive.");
  }

  /// Get innermost captured statement for the construct.
  CapturedStmt *
  getInnermostCapturedStmt(ArrayRef<OpenMPDirectiveKind> CaptureRegions) {
    assert(hasAssociatedStmt() && "Must have associated captured statement.");
    assert(!CaptureRegions.empty() &&
           "At least one captured statement must be provided.");
    auto *CS = cast<CapturedStmt>(getAssociatedStmt());
    for (unsigned Level = CaptureRegions.size(); Level > 1; --Level)
      CS = cast<CapturedStmt>(CS->getCapturedStmt());
    return CS;
  }

  const CapturedStmt *
  getInnermostCapturedStmt(ArrayRef<OpenMPDirectiveKind> CaptureRegions) const {
    return const_cast<OMPChildren *>(this)->getInnermostCapturedStmt(
        CaptureRegions);
  }

  MutableArrayRef<Stmt *> getChildren();
  ArrayRef<Stmt *> getChildren() const {
    return const_cast<OMPChildren *>(this)->getChildren();
  }

  Stmt *getRawStmt() {
    assert(HasAssociatedStmt &&
           "Expected directive with the associated statement.");
    if (auto *CS = dyn_cast<CapturedStmt>(getAssociatedStmt())) {
      Stmt *S = nullptr;
      do {
        S = CS->getCapturedStmt();
        CS = dyn_cast<CapturedStmt>(S);
      } while (CS);
      return S;
    }
    return getAssociatedStmt();
  }
  const Stmt *getRawStmt() const {
    return const_cast<OMPChildren *>(this)->getRawStmt();
  }

  Stmt::child_range getAssociatedStmtAsRange() {
    if (!HasAssociatedStmt)
      return Stmt::child_range(Stmt::child_iterator(), Stmt::child_iterator());
    return Stmt::child_range(&getTrailingObjects<Stmt *>()[NumChildren],
                             &getTrailingObjects<Stmt *>()[NumChildren + 1]);
  }
};

} // namespace clang

#endif // LLVM_CLANG_AST_OPENMPCLAUSE_H
