//===- OpenMPClause.cpp - Classes for OpenMP clauses ----------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file implements the subclesses of Stmt class declared in OpenMPClause.h
//
//===----------------------------------------------------------------------===//

#include "clang/AST/OpenMPClause.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclOpenMP.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/OpenMPKinds.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/ErrorHandling.h"
#include <algorithm>
#include <cassert>
#include <optional>

using namespace clang;
using namespace llvm;
using namespace omp;

OMPClause::child_range OMPClause::children() {
  switch (getClauseKind()) {
  default:
    break;
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class)                                         \
  case Enum:                                                                   \
    return static_cast<Class *>(this)->children();
#include "llvm/Frontend/OpenMP/OMP.inc"
  }
  llvm_unreachable("unknown OMPClause");
}

OMPClause::child_range OMPClause::used_children() {
  switch (getClauseKind()) {
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class)                                         \
  case Enum:                                                                   \
    return static_cast<Class *>(this)->used_children();
#define CLAUSE_NO_CLASS(Enum, Str)                                             \
  case Enum:                                                                   \
    break;
#include "llvm/Frontend/OpenMP/OMP.inc"
  }
  llvm_unreachable("unknown OMPClause");
}

OMPClauseWithPreInit *OMPClauseWithPreInit::get(OMPClause *C) {
  auto *Res = OMPClauseWithPreInit::get(const_cast<const OMPClause *>(C));
  return Res ? const_cast<OMPClauseWithPreInit *>(Res) : nullptr;
}

const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
  switch (C->getClauseKind()) {
  case OMPC_schedule:
    return static_cast<const OMPScheduleClause *>(C);
  case OMPC_dist_schedule:
    return static_cast<const OMPDistScheduleClause *>(C);
  case OMPC_firstprivate:
    return static_cast<const OMPFirstprivateClause *>(C);
  case OMPC_lastprivate:
    return static_cast<const OMPLastprivateClause *>(C);
  case OMPC_reduction:
    return static_cast<const OMPReductionClause *>(C);
  case OMPC_task_reduction:
    return static_cast<const OMPTaskReductionClause *>(C);
  case OMPC_in_reduction:
    return static_cast<const OMPInReductionClause *>(C);
  case OMPC_linear:
    return static_cast<const OMPLinearClause *>(C);
  case OMPC_if:
    return static_cast<const OMPIfClause *>(C);
  case OMPC_num_threads:
    return static_cast<const OMPNumThreadsClause *>(C);
  case OMPC_num_teams:
    return static_cast<const OMPNumTeamsClause *>(C);
  case OMPC_thread_limit:
    return static_cast<const OMPThreadLimitClause *>(C);
  case OMPC_device:
    return static_cast<const OMPDeviceClause *>(C);
  case OMPC_grainsize:
    return static_cast<const OMPGrainsizeClause *>(C);
  case OMPC_num_tasks:
    return static_cast<const OMPNumTasksClause *>(C);
  case OMPC_final:
    return static_cast<const OMPFinalClause *>(C);
  case OMPC_priority:
    return static_cast<const OMPPriorityClause *>(C);
  case OMPC_novariants:
    return static_cast<const OMPNovariantsClause *>(C);
  case OMPC_nocontext:
    return static_cast<const OMPNocontextClause *>(C);
  case OMPC_filter:
    return static_cast<const OMPFilterClause *>(C);
  case OMPC_ompx_dyn_cgroup_mem:
    return static_cast<const OMPXDynCGroupMemClause *>(C);
  case OMPC_default:
  case OMPC_proc_bind:
  case OMPC_safelen:
  case OMPC_simdlen:
  case OMPC_sizes:
  case OMPC_allocator:
  case OMPC_allocate:
  case OMPC_collapse:
  case OMPC_private:
  case OMPC_shared:
  case OMPC_aligned:
  case OMPC_copyin:
  case OMPC_copyprivate:
  case OMPC_ordered:
  case OMPC_nowait:
  case OMPC_untied:
  case OMPC_mergeable:
  case OMPC_threadprivate:
  case OMPC_flush:
  case OMPC_depobj:
  case OMPC_read:
  case OMPC_write:
  case OMPC_update:
  case OMPC_capture:
  case OMPC_compare:
  case OMPC_fail:
  case OMPC_seq_cst:
  case OMPC_acq_rel:
  case OMPC_acquire:
  case OMPC_release:
  case OMPC_relaxed:
  case OMPC_depend:
  case OMPC_threads:
  case OMPC_simd:
  case OMPC_map:
  case OMPC_nogroup:
  case OMPC_hint:
  case OMPC_defaultmap:
  case OMPC_unknown:
  case OMPC_uniform:
  case OMPC_to:
  case OMPC_from:
  case OMPC_use_device_ptr:
  case OMPC_use_device_addr:
  case OMPC_is_device_ptr:
  case OMPC_has_device_addr:
  case OMPC_unified_address:
  case OMPC_unified_shared_memory:
  case OMPC_reverse_offload:
  case OMPC_dynamic_allocators:
  case OMPC_atomic_default_mem_order:
  case OMPC_at:
  case OMPC_severity:
  case OMPC_message:
  case OMPC_device_type:
  case OMPC_match:
  case OMPC_nontemporal:
  case OMPC_order:
  case OMPC_destroy:
  case OMPC_detach:
  case OMPC_inclusive:
  case OMPC_exclusive:
  case OMPC_uses_allocators:
  case OMPC_affinity:
  case OMPC_when:
  case OMPC_bind:
  case OMPC_ompx_bare:
    break;
  default:
    break;
  }

  return nullptr;
}

OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(OMPClause *C) {
  auto *Res = OMPClauseWithPostUpdate::get(const_cast<const OMPClause *>(C));
  return Res ? const_cast<OMPClauseWithPostUpdate *>(Res) : nullptr;
}

const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C) {
  switch (C->getClauseKind()) {
  case OMPC_lastprivate:
    return static_cast<const OMPLastprivateClause *>(C);
  case OMPC_reduction:
    return static_cast<const OMPReductionClause *>(C);
  case OMPC_task_reduction:
    return static_cast<const OMPTaskReductionClause *>(C);
  case OMPC_in_reduction:
    return static_cast<const OMPInReductionClause *>(C);
  case OMPC_linear:
    return static_cast<const OMPLinearClause *>(C);
  case OMPC_schedule:
  case OMPC_dist_schedule:
  case OMPC_firstprivate:
  case OMPC_default:
  case OMPC_proc_bind:
  case OMPC_if:
  case OMPC_final:
  case OMPC_num_threads:
  case OMPC_safelen:
  case OMPC_simdlen:
  case OMPC_sizes:
  case OMPC_allocator:
  case OMPC_allocate:
  case OMPC_collapse:
  case OMPC_private:
  case OMPC_shared:
  case OMPC_aligned:
  case OMPC_copyin:
  case OMPC_copyprivate:
  case OMPC_ordered:
  case OMPC_nowait:
  case OMPC_untied:
  case OMPC_mergeable:
  case OMPC_threadprivate:
  case OMPC_flush:
  case OMPC_depobj:
  case OMPC_read:
  case OMPC_write:
  case OMPC_update:
  case OMPC_capture:
  case OMPC_compare:
  case OMPC_fail:
  case OMPC_seq_cst:
  case OMPC_acq_rel:
  case OMPC_acquire:
  case OMPC_release:
  case OMPC_relaxed:
  case OMPC_depend:
  case OMPC_device:
  case OMPC_threads:
  case OMPC_simd:
  case OMPC_map:
  case OMPC_num_teams:
  case OMPC_thread_limit:
  case OMPC_priority:
  case OMPC_grainsize:
  case OMPC_nogroup:
  case OMPC_num_tasks:
  case OMPC_hint:
  case OMPC_defaultmap:
  case OMPC_unknown:
  case OMPC_uniform:
  case OMPC_to:
  case OMPC_from:
  case OMPC_use_device_ptr:
  case OMPC_use_device_addr:
  case OMPC_is_device_ptr:
  case OMPC_has_device_addr:
  case OMPC_unified_address:
  case OMPC_unified_shared_memory:
  case OMPC_reverse_offload:
  case OMPC_dynamic_allocators:
  case OMPC_atomic_default_mem_order:
  case OMPC_at:
  case OMPC_severity:
  case OMPC_message:
  case OMPC_device_type:
  case OMPC_match:
  case OMPC_nontemporal:
  case OMPC_order:
  case OMPC_destroy:
  case OMPC_novariants:
  case OMPC_nocontext:
  case OMPC_detach:
  case OMPC_inclusive:
  case OMPC_exclusive:
  case OMPC_uses_allocators:
  case OMPC_affinity:
  case OMPC_when:
  case OMPC_bind:
    break;
  default:
    break;
  }

  return nullptr;
}

/// Gets the address of the original, non-captured, expression used in the
/// clause as the preinitializer.
static Stmt **getAddrOfExprAsWritten(Stmt *S) {
  if (!S)
    return nullptr;
  if (auto *DS = dyn_cast<DeclStmt>(S)) {
    assert(DS->isSingleDecl() && "Only single expression must be captured.");
    if (auto *OED = dyn_cast<OMPCapturedExprDecl>(DS->getSingleDecl()))
      return OED->getInitAddress();
  }
  return nullptr;
}

OMPClause::child_range OMPIfClause::used_children() {
  if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
    return child_range(C, C + 1);
  return child_range(&Condition, &Condition + 1);
}

OMPClause::child_range OMPGrainsizeClause::used_children() {
  if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
    return child_range(C, C + 1);
  return child_range(&Grainsize, &Grainsize + 1);
}

OMPClause::child_range OMPNumTasksClause::used_children() {
  if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
    return child_range(C, C + 1);
  return child_range(&NumTasks, &NumTasks + 1);
}

OMPClause::child_range OMPFinalClause::used_children() {
  if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
    return child_range(C, C + 1);
  return children();
}

OMPClause::child_range OMPPriorityClause::used_children() {
  if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
    return child_range(C, C + 1);
  return child_range(&Priority, &Priority + 1);
}

OMPClause::child_range OMPNovariantsClause::used_children() {
  if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
    return child_range(C, C + 1);
  return children();
}

OMPClause::child_range OMPNocontextClause::used_children() {
  if (Stmt **C = getAddrOfExprAsWritten(getPreInitStmt()))
    return child_range(C, C + 1);
  return children();
}

OMPOrderedClause *OMPOrderedClause::Create(const ASTContext &C, Expr *Num,
                                           unsigned NumLoops,
                                           SourceLocation StartLoc,
                                           SourceLocation LParenLoc,
                                           SourceLocation EndLoc) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * NumLoops));
  auto *Clause =
      new (Mem) OMPOrderedClause(Num, NumLoops, StartLoc, LParenLoc, EndLoc);
  for (unsigned I = 0; I < NumLoops; ++I) {
    Clause->setLoopNumIterations(I, nullptr);
    Clause->setLoopCounter(I, nullptr);
  }
  return Clause;
}

OMPOrderedClause *OMPOrderedClause::CreateEmpty(const ASTContext &C,
                                                unsigned NumLoops) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * NumLoops));
  auto *Clause = new (Mem) OMPOrderedClause(NumLoops);
  for (unsigned I = 0; I < NumLoops; ++I) {
    Clause->setLoopNumIterations(I, nullptr);
    Clause->setLoopCounter(I, nullptr);
  }
  return Clause;
}

void OMPOrderedClause::setLoopNumIterations(unsigned NumLoop,
                                            Expr *NumIterations) {
  assert(NumLoop < NumberOfLoops && "out of loops number.");
  getTrailingObjects<Expr *>()[NumLoop] = NumIterations;
}

ArrayRef<Expr *> OMPOrderedClause::getLoopNumIterations() const {
  return llvm::ArrayRef(getTrailingObjects<Expr *>(), NumberOfLoops);
}

void OMPOrderedClause::setLoopCounter(unsigned NumLoop, Expr *Counter) {
  assert(NumLoop < NumberOfLoops && "out of loops number.");
  getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop] = Counter;
}

Expr *OMPOrderedClause::getLoopCounter(unsigned NumLoop) {
  assert(NumLoop < NumberOfLoops && "out of loops number.");
  return getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop];
}

const Expr *OMPOrderedClause::getLoopCounter(unsigned NumLoop) const {
  assert(NumLoop < NumberOfLoops && "out of loops number.");
  return getTrailingObjects<Expr *>()[NumberOfLoops + NumLoop];
}

OMPUpdateClause *OMPUpdateClause::Create(const ASTContext &C,
                                         SourceLocation StartLoc,
                                         SourceLocation EndLoc) {
  return new (C) OMPUpdateClause(StartLoc, EndLoc, /*IsExtended=*/false);
}

OMPUpdateClause *
OMPUpdateClause::Create(const ASTContext &C, SourceLocation StartLoc,
                        SourceLocation LParenLoc, SourceLocation ArgumentLoc,
                        OpenMPDependClauseKind DK, SourceLocation EndLoc) {
  void *Mem =
      C.Allocate(totalSizeToAlloc<SourceLocation, OpenMPDependClauseKind>(2, 1),
                 alignof(OMPUpdateClause));
  auto *Clause =
      new (Mem) OMPUpdateClause(StartLoc, EndLoc, /*IsExtended=*/true);
  Clause->setLParenLoc(LParenLoc);
  Clause->setArgumentLoc(ArgumentLoc);
  Clause->setDependencyKind(DK);
  return Clause;
}

OMPUpdateClause *OMPUpdateClause::CreateEmpty(const ASTContext &C,
                                              bool IsExtended) {
  if (!IsExtended)
    return new (C) OMPUpdateClause(/*IsExtended=*/false);
  void *Mem =
      C.Allocate(totalSizeToAlloc<SourceLocation, OpenMPDependClauseKind>(2, 1),
                 alignof(OMPUpdateClause));
  auto *Clause = new (Mem) OMPUpdateClause(/*IsExtended=*/true);
  Clause->IsExtended = true;
  return Clause;
}

void OMPPrivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
  assert(VL.size() == varlist_size() &&
         "Number of private copies is not the same as the preallocated buffer");
  std::copy(VL.begin(), VL.end(), varlist_end());
}

OMPPrivateClause *
OMPPrivateClause::Create(const ASTContext &C, SourceLocation StartLoc,
                         SourceLocation LParenLoc, SourceLocation EndLoc,
                         ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL) {
  // Allocate space for private variables and initializer expressions.
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * VL.size()));
  OMPPrivateClause *Clause =
      new (Mem) OMPPrivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
  Clause->setVarRefs(VL);
  Clause->setPrivateCopies(PrivateVL);
  return Clause;
}

OMPPrivateClause *OMPPrivateClause::CreateEmpty(const ASTContext &C,
                                                unsigned N) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * N));
  return new (Mem) OMPPrivateClause(N);
}

void OMPFirstprivateClause::setPrivateCopies(ArrayRef<Expr *> VL) {
  assert(VL.size() == varlist_size() &&
         "Number of private copies is not the same as the preallocated buffer");
  std::copy(VL.begin(), VL.end(), varlist_end());
}

void OMPFirstprivateClause::setInits(ArrayRef<Expr *> VL) {
  assert(VL.size() == varlist_size() &&
         "Number of inits is not the same as the preallocated buffer");
  std::copy(VL.begin(), VL.end(), getPrivateCopies().end());
}

OMPFirstprivateClause *
OMPFirstprivateClause::Create(const ASTContext &C, SourceLocation StartLoc,
                              SourceLocation LParenLoc, SourceLocation EndLoc,
                              ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,
                              ArrayRef<Expr *> InitVL, Stmt *PreInit) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(3 * VL.size()));
  OMPFirstprivateClause *Clause =
      new (Mem) OMPFirstprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
  Clause->setVarRefs(VL);
  Clause->setPrivateCopies(PrivateVL);
  Clause->setInits(InitVL);
  Clause->setPreInitStmt(PreInit);
  return Clause;
}

OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C,
                                                          unsigned N) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(3 * N));
  return new (Mem) OMPFirstprivateClause(N);
}

void OMPLastprivateClause::setPrivateCopies(ArrayRef<Expr *> PrivateCopies) {
  assert(PrivateCopies.size() == varlist_size() &&
         "Number of private copies is not the same as the preallocated buffer");
  std::copy(PrivateCopies.begin(), PrivateCopies.end(), varlist_end());
}

void OMPLastprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
  assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
                                              "not the same as the "
                                              "preallocated buffer");
  std::copy(SrcExprs.begin(), SrcExprs.end(), getPrivateCopies().end());
}

void OMPLastprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
  assert(DstExprs.size() == varlist_size() && "Number of destination "
                                              "expressions is not the same as "
                                              "the preallocated buffer");
  std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
}

void OMPLastprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
  assert(AssignmentOps.size() == varlist_size() &&
         "Number of assignment expressions is not the same as the preallocated "
         "buffer");
  std::copy(AssignmentOps.begin(), AssignmentOps.end(),
            getDestinationExprs().end());
}

OMPLastprivateClause *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) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
  OMPLastprivateClause *Clause = new (Mem) OMPLastprivateClause(
      StartLoc, LParenLoc, EndLoc, LPKind, LPKindLoc, ColonLoc, VL.size());
  Clause->setVarRefs(VL);
  Clause->setSourceExprs(SrcExprs);
  Clause->setDestinationExprs(DstExprs);
  Clause->setAssignmentOps(AssignmentOps);
  Clause->setPreInitStmt(PreInit);
  Clause->setPostUpdateExpr(PostUpdate);
  return Clause;
}

OMPLastprivateClause *OMPLastprivateClause::CreateEmpty(const ASTContext &C,
                                                        unsigned N) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));
  return new (Mem) OMPLastprivateClause(N);
}

OMPSharedClause *OMPSharedClause::Create(const ASTContext &C,
                                         SourceLocation StartLoc,
                                         SourceLocation LParenLoc,
                                         SourceLocation EndLoc,
                                         ArrayRef<Expr *> VL) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
  OMPSharedClause *Clause =
      new (Mem) OMPSharedClause(StartLoc, LParenLoc, EndLoc, VL.size());
  Clause->setVarRefs(VL);
  return Clause;
}

OMPSharedClause *OMPSharedClause::CreateEmpty(const ASTContext &C, unsigned N) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
  return new (Mem) OMPSharedClause(N);
}

void OMPLinearClause::setPrivates(ArrayRef<Expr *> PL) {
  assert(PL.size() == varlist_size() &&
         "Number of privates is not the same as the preallocated buffer");
  std::copy(PL.begin(), PL.end(), varlist_end());
}

void OMPLinearClause::setInits(ArrayRef<Expr *> IL) {
  assert(IL.size() == varlist_size() &&
         "Number of inits is not the same as the preallocated buffer");
  std::copy(IL.begin(), IL.end(), getPrivates().end());
}

void OMPLinearClause::setUpdates(ArrayRef<Expr *> UL) {
  assert(UL.size() == varlist_size() &&
         "Number of updates is not the same as the preallocated buffer");
  std::copy(UL.begin(), UL.end(), getInits().end());
}

void OMPLinearClause::setFinals(ArrayRef<Expr *> FL) {
  assert(FL.size() == varlist_size() &&
         "Number of final updates is not the same as the preallocated buffer");
  std::copy(FL.begin(), FL.end(), getUpdates().end());
}

void OMPLinearClause::setUsedExprs(ArrayRef<Expr *> UE) {
  assert(
      UE.size() == varlist_size() + 1 &&
      "Number of used expressions is not the same as the preallocated buffer");
  std::copy(UE.begin(), UE.end(), getFinals().end() + 2);
}

OMPLinearClause *OMPLinearClause::Create(
    const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
    OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc,
    SourceLocation ColonLoc, SourceLocation StepModifierLoc,
    SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> PL,
    ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit,
    Expr *PostUpdate) {
  // Allocate space for 5 lists (Vars, Inits, Updates, Finals), 2 expressions
  // (Step and CalcStep), list of used expression + step.
  void *Mem =
      C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size() + 2 + VL.size() + 1));
  OMPLinearClause *Clause =
      new (Mem) OMPLinearClause(StartLoc, LParenLoc, Modifier, ModifierLoc,
                                ColonLoc, StepModifierLoc, EndLoc, VL.size());
  Clause->setVarRefs(VL);
  Clause->setPrivates(PL);
  Clause->setInits(IL);
  // Fill update and final expressions with zeroes, they are provided later,
  // after the directive construction.
  std::fill(Clause->getInits().end(), Clause->getInits().end() + VL.size(),
            nullptr);
  std::fill(Clause->getUpdates().end(), Clause->getUpdates().end() + VL.size(),
            nullptr);
  std::fill(Clause->getUsedExprs().begin(), Clause->getUsedExprs().end(),
            nullptr);
  Clause->setStep(Step);
  Clause->setCalcStep(CalcStep);
  Clause->setPreInitStmt(PreInit);
  Clause->setPostUpdateExpr(PostUpdate);
  return Clause;
}

OMPLinearClause *OMPLinearClause::CreateEmpty(const ASTContext &C,
                                              unsigned NumVars) {
  // Allocate space for 5 lists (Vars, Inits, Updates, Finals), 2 expressions
  // (Step and CalcStep), list of used expression + step.
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * NumVars + 2 + NumVars  +1));
  return new (Mem) OMPLinearClause(NumVars);
}

OMPClause::child_range OMPLinearClause::used_children() {
  // Range includes only non-nullptr elements.
  return child_range(
      reinterpret_cast<Stmt **>(getUsedExprs().begin()),
      reinterpret_cast<Stmt **>(llvm::find(getUsedExprs(), nullptr)));
}

OMPAlignedClause *
OMPAlignedClause::Create(const ASTContext &C, SourceLocation StartLoc,
                         SourceLocation LParenLoc, SourceLocation ColonLoc,
                         SourceLocation EndLoc, ArrayRef<Expr *> VL, Expr *A) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1));
  OMPAlignedClause *Clause = new (Mem)
      OMPAlignedClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
  Clause->setVarRefs(VL);
  Clause->setAlignment(A);
  return Clause;
}

OMPAlignedClause *OMPAlignedClause::CreateEmpty(const ASTContext &C,
                                                unsigned NumVars) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumVars + 1));
  return new (Mem) OMPAlignedClause(NumVars);
}

OMPAlignClause *OMPAlignClause::Create(const ASTContext &C, Expr *A,
                                       SourceLocation StartLoc,
                                       SourceLocation LParenLoc,
                                       SourceLocation EndLoc) {
  return new (C) OMPAlignClause(A, StartLoc, LParenLoc, EndLoc);
}

void OMPCopyinClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
  assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
                                              "not the same as the "
                                              "preallocated buffer");
  std::copy(SrcExprs.begin(), SrcExprs.end(), varlist_end());
}

void OMPCopyinClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
  assert(DstExprs.size() == varlist_size() && "Number of destination "
                                              "expressions is not the same as "
                                              "the preallocated buffer");
  std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
}

void OMPCopyinClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
  assert(AssignmentOps.size() == varlist_size() &&
         "Number of assignment expressions is not the same as the preallocated "
         "buffer");
  std::copy(AssignmentOps.begin(), AssignmentOps.end(),
            getDestinationExprs().end());
}

OMPCopyinClause *OMPCopyinClause::Create(
    const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
    SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
    ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * VL.size()));
  OMPCopyinClause *Clause =
      new (Mem) OMPCopyinClause(StartLoc, LParenLoc, EndLoc, VL.size());
  Clause->setVarRefs(VL);
  Clause->setSourceExprs(SrcExprs);
  Clause->setDestinationExprs(DstExprs);
  Clause->setAssignmentOps(AssignmentOps);
  return Clause;
}

OMPCopyinClause *OMPCopyinClause::CreateEmpty(const ASTContext &C, unsigned N) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * N));
  return new (Mem) OMPCopyinClause(N);
}

void OMPCopyprivateClause::setSourceExprs(ArrayRef<Expr *> SrcExprs) {
  assert(SrcExprs.size() == varlist_size() && "Number of source expressions is "
                                              "not the same as the "
                                              "preallocated buffer");
  std::copy(SrcExprs.begin(), SrcExprs.end(), varlist_end());
}

void OMPCopyprivateClause::setDestinationExprs(ArrayRef<Expr *> DstExprs) {
  assert(DstExprs.size() == varlist_size() && "Number of destination "
                                              "expressions is not the same as "
                                              "the preallocated buffer");
  std::copy(DstExprs.begin(), DstExprs.end(), getSourceExprs().end());
}

void OMPCopyprivateClause::setAssignmentOps(ArrayRef<Expr *> AssignmentOps) {
  assert(AssignmentOps.size() == varlist_size() &&
         "Number of assignment expressions is not the same as the preallocated "
         "buffer");
  std::copy(AssignmentOps.begin(), AssignmentOps.end(),
            getDestinationExprs().end());
}

OMPCopyprivateClause *OMPCopyprivateClause::Create(
    const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
    SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
    ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * VL.size()));
  OMPCopyprivateClause *Clause =
      new (Mem) OMPCopyprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
  Clause->setVarRefs(VL);
  Clause->setSourceExprs(SrcExprs);
  Clause->setDestinationExprs(DstExprs);
  Clause->setAssignmentOps(AssignmentOps);
  return Clause;
}

OMPCopyprivateClause *OMPCopyprivateClause::CreateEmpty(const ASTContext &C,
                                                        unsigned N) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * N));
  return new (Mem) OMPCopyprivateClause(N);
}

void OMPReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
  assert(Privates.size() == varlist_size() &&
         "Number of private copies is not the same as the preallocated buffer");
  std::copy(Privates.begin(), Privates.end(), varlist_end());
}

void OMPReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
  assert(
      LHSExprs.size() == varlist_size() &&
      "Number of LHS expressions is not the same as the preallocated buffer");
  std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
}

void OMPReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
  assert(
      RHSExprs.size() == varlist_size() &&
      "Number of RHS expressions is not the same as the preallocated buffer");
  std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
}

void OMPReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
  assert(ReductionOps.size() == varlist_size() && "Number of reduction "
                                                  "expressions is not the same "
                                                  "as the preallocated buffer");
  std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
}

void OMPReductionClause::setInscanCopyOps(ArrayRef<Expr *> Ops) {
  assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");
  assert(Ops.size() == varlist_size() && "Number of copy "
                                         "expressions is not the same "
                                         "as the preallocated buffer");
  llvm::copy(Ops, getReductionOps().end());
}

void OMPReductionClause::setInscanCopyArrayTemps(
    ArrayRef<Expr *> CopyArrayTemps) {
  assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");
  assert(CopyArrayTemps.size() == varlist_size() &&
         "Number of copy temp expressions is not the same as the preallocated "
         "buffer");
  llvm::copy(CopyArrayTemps, getInscanCopyOps().end());
}

void OMPReductionClause::setInscanCopyArrayElems(
    ArrayRef<Expr *> CopyArrayElems) {
  assert(Modifier == OMPC_REDUCTION_inscan && "Expected inscan reduction.");
  assert(CopyArrayElems.size() == varlist_size() &&
         "Number of copy temp expressions is not the same as the preallocated "
         "buffer");
  llvm::copy(CopyArrayElems, getInscanCopyArrayTemps().end());
}

OMPReductionClause *OMPReductionClause::Create(
    const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
    SourceLocation ModifierLoc, SourceLocation EndLoc, SourceLocation ColonLoc,
    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) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(
      (Modifier == OMPC_REDUCTION_inscan ? 8 : 5) * VL.size()));
  auto *Clause = new (Mem)
      OMPReductionClause(StartLoc, LParenLoc, ModifierLoc, EndLoc, ColonLoc,
                         Modifier, VL.size(), QualifierLoc, NameInfo);
  Clause->setVarRefs(VL);
  Clause->setPrivates(Privates);
  Clause->setLHSExprs(LHSExprs);
  Clause->setRHSExprs(RHSExprs);
  Clause->setReductionOps(ReductionOps);
  Clause->setPreInitStmt(PreInit);
  Clause->setPostUpdateExpr(PostUpdate);
  if (Modifier == OMPC_REDUCTION_inscan) {
    Clause->setInscanCopyOps(CopyOps);
    Clause->setInscanCopyArrayTemps(CopyArrayTemps);
    Clause->setInscanCopyArrayElems(CopyArrayElems);
  } else {
    assert(CopyOps.empty() &&
           "copy operations are expected in inscan reductions only.");
    assert(CopyArrayTemps.empty() &&
           "copy array temps are expected in inscan reductions only.");
    assert(CopyArrayElems.empty() &&
           "copy array temps are expected in inscan reductions only.");
  }
  return Clause;
}

OMPReductionClause *
OMPReductionClause::CreateEmpty(const ASTContext &C, unsigned N,
                                OpenMPReductionClauseModifier Modifier) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(
      (Modifier == OMPC_REDUCTION_inscan ? 8 : 5) * N));
  auto *Clause = new (Mem) OMPReductionClause(N);
  Clause->setModifier(Modifier);
  return Clause;
}

void OMPTaskReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
  assert(Privates.size() == varlist_size() &&
         "Number of private copies is not the same as the preallocated buffer");
  std::copy(Privates.begin(), Privates.end(), varlist_end());
}

void OMPTaskReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
  assert(
      LHSExprs.size() == varlist_size() &&
      "Number of LHS expressions is not the same as the preallocated buffer");
  std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
}

void OMPTaskReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
  assert(
      RHSExprs.size() == varlist_size() &&
      "Number of RHS expressions is not the same as the preallocated buffer");
  std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
}

void OMPTaskReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
  assert(ReductionOps.size() == varlist_size() && "Number of task reduction "
                                                  "expressions is not the same "
                                                  "as the preallocated buffer");
  std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
}

OMPTaskReductionClause *OMPTaskReductionClause::Create(
    const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
    SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
    NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
    ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
    ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps, Stmt *PreInit,
    Expr *PostUpdate) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
  OMPTaskReductionClause *Clause = new (Mem) OMPTaskReductionClause(
      StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
  Clause->setVarRefs(VL);
  Clause->setPrivates(Privates);
  Clause->setLHSExprs(LHSExprs);
  Clause->setRHSExprs(RHSExprs);
  Clause->setReductionOps(ReductionOps);
  Clause->setPreInitStmt(PreInit);
  Clause->setPostUpdateExpr(PostUpdate);
  return Clause;
}

OMPTaskReductionClause *OMPTaskReductionClause::CreateEmpty(const ASTContext &C,
                                                            unsigned N) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));
  return new (Mem) OMPTaskReductionClause(N);
}

void OMPInReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
  assert(Privates.size() == varlist_size() &&
         "Number of private copies is not the same as the preallocated buffer");
  std::copy(Privates.begin(), Privates.end(), varlist_end());
}

void OMPInReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
  assert(
      LHSExprs.size() == varlist_size() &&
      "Number of LHS expressions is not the same as the preallocated buffer");
  std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
}

void OMPInReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
  assert(
      RHSExprs.size() == varlist_size() &&
      "Number of RHS expressions is not the same as the preallocated buffer");
  std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
}

void OMPInReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
  assert(ReductionOps.size() == varlist_size() && "Number of in reduction "
                                                  "expressions is not the same "
                                                  "as the preallocated buffer");
  std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
}

void OMPInReductionClause::setTaskgroupDescriptors(
    ArrayRef<Expr *> TaskgroupDescriptors) {
  assert(TaskgroupDescriptors.size() == varlist_size() &&
         "Number of in reduction descriptors is not the same as the "
         "preallocated buffer");
  std::copy(TaskgroupDescriptors.begin(), TaskgroupDescriptors.end(),
            getReductionOps().end());
}

OMPInReductionClause *OMPInReductionClause::Create(
    const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
    SourceLocation EndLoc, SourceLocation ColonLoc, 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) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(6 * VL.size()));
  OMPInReductionClause *Clause = new (Mem) OMPInReductionClause(
      StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
  Clause->setVarRefs(VL);
  Clause->setPrivates(Privates);
  Clause->setLHSExprs(LHSExprs);
  Clause->setRHSExprs(RHSExprs);
  Clause->setReductionOps(ReductionOps);
  Clause->setTaskgroupDescriptors(TaskgroupDescriptors);
  Clause->setPreInitStmt(PreInit);
  Clause->setPostUpdateExpr(PostUpdate);
  return Clause;
}

OMPInReductionClause *OMPInReductionClause::CreateEmpty(const ASTContext &C,
                                                        unsigned N) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(6 * N));
  return new (Mem) OMPInReductionClause(N);
}

OMPSizesClause *OMPSizesClause::Create(const ASTContext &C,
                                       SourceLocation StartLoc,
                                       SourceLocation LParenLoc,
                                       SourceLocation EndLoc,
                                       ArrayRef<Expr *> Sizes) {
  OMPSizesClause *Clause = CreateEmpty(C, Sizes.size());
  Clause->setLocStart(StartLoc);
  Clause->setLParenLoc(LParenLoc);
  Clause->setLocEnd(EndLoc);
  Clause->setSizesRefs(Sizes);
  return Clause;
}

OMPSizesClause *OMPSizesClause::CreateEmpty(const ASTContext &C,
                                            unsigned NumSizes) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumSizes));
  return new (Mem) OMPSizesClause(NumSizes);
}

OMPPermutationClause *OMPPermutationClause::Create(const ASTContext &C,
                                                   SourceLocation StartLoc,
                                                   SourceLocation LParenLoc,
                                                   SourceLocation EndLoc,
                                                   ArrayRef<Expr *> Args) {
  OMPPermutationClause *Clause = CreateEmpty(C, Args.size());
  Clause->setLocStart(StartLoc);
  Clause->setLParenLoc(LParenLoc);
  Clause->setLocEnd(EndLoc);
  Clause->setArgRefs(Args);
  return Clause;
}

OMPPermutationClause *OMPPermutationClause::CreateEmpty(const ASTContext &C,
                                                        unsigned NumLoops) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumLoops));
  return new (Mem) OMPPermutationClause(NumLoops);
}

OMPFullClause *OMPFullClause::Create(const ASTContext &C,
                                     SourceLocation StartLoc,
                                     SourceLocation EndLoc) {
  OMPFullClause *Clause = CreateEmpty(C);
  Clause->setLocStart(StartLoc);
  Clause->setLocEnd(EndLoc);
  return Clause;
}

OMPFullClause *OMPFullClause::CreateEmpty(const ASTContext &C) {
  return new (C) OMPFullClause();
}

OMPPartialClause *OMPPartialClause::Create(const ASTContext &C,
                                           SourceLocation StartLoc,
                                           SourceLocation LParenLoc,
                                           SourceLocation EndLoc,
                                           Expr *Factor) {
  OMPPartialClause *Clause = CreateEmpty(C);
  Clause->setLocStart(StartLoc);
  Clause->setLParenLoc(LParenLoc);
  Clause->setLocEnd(EndLoc);
  Clause->setFactor(Factor);
  return Clause;
}

OMPPartialClause *OMPPartialClause::CreateEmpty(const ASTContext &C) {
  return new (C) OMPPartialClause();
}

OMPAllocateClause *OMPAllocateClause::Create(
    const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
    Expr *Allocator, Expr *Alignment, SourceLocation ColonLoc,
    OpenMPAllocateClauseModifier Modifier1, SourceLocation Modifier1Loc,
    OpenMPAllocateClauseModifier Modifier2, SourceLocation Modifier2Loc,
    SourceLocation EndLoc, ArrayRef<Expr *> VL) {

  // Allocate space for private variables and initializer expressions.
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
  auto *Clause = new (Mem) OMPAllocateClause(
      StartLoc, LParenLoc, Allocator, Alignment, ColonLoc, Modifier1,
      Modifier1Loc, Modifier2, Modifier2Loc, EndLoc, VL.size());

  Clause->setVarRefs(VL);
  return Clause;
}

OMPAllocateClause *OMPAllocateClause::CreateEmpty(const ASTContext &C,
                                                  unsigned N) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
  return new (Mem) OMPAllocateClause(N);
}

OMPFlushClause *OMPFlushClause::Create(const ASTContext &C,
                                       SourceLocation StartLoc,
                                       SourceLocation LParenLoc,
                                       SourceLocation EndLoc,
                                       ArrayRef<Expr *> VL) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1));
  OMPFlushClause *Clause =
      new (Mem) OMPFlushClause(StartLoc, LParenLoc, EndLoc, VL.size());
  Clause->setVarRefs(VL);
  return Clause;
}

OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext &C, unsigned N) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
  return new (Mem) OMPFlushClause(N);
}

OMPDepobjClause *OMPDepobjClause::Create(const ASTContext &C,
                                         SourceLocation StartLoc,
                                         SourceLocation LParenLoc,
                                         SourceLocation RParenLoc,
                                         Expr *Depobj) {
  auto *Clause = new (C) OMPDepobjClause(StartLoc, LParenLoc, RParenLoc);
  Clause->setDepobj(Depobj);
  return Clause;
}

OMPDepobjClause *OMPDepobjClause::CreateEmpty(const ASTContext &C) {
  return new (C) OMPDepobjClause();
}

OMPDependClause *
OMPDependClause::Create(const ASTContext &C, SourceLocation StartLoc,
                        SourceLocation LParenLoc, SourceLocation EndLoc,
                        DependDataTy Data, Expr *DepModifier,
                        ArrayRef<Expr *> VL, unsigned NumLoops) {
  void *Mem = C.Allocate(
      totalSizeToAlloc<Expr *>(VL.size() + /*depend-modifier*/ 1 + NumLoops),
      alignof(OMPDependClause));
  OMPDependClause *Clause = new (Mem)
      OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size(), NumLoops);
  Clause->setDependencyKind(Data.DepKind);
  Clause->setDependencyLoc(Data.DepLoc);
  Clause->setColonLoc(Data.ColonLoc);
  Clause->setOmpAllMemoryLoc(Data.OmpAllMemoryLoc);
  Clause->setModifier(DepModifier);
  Clause->setVarRefs(VL);
  for (unsigned I = 0 ; I < NumLoops; ++I)
    Clause->setLoopData(I, nullptr);
  return Clause;
}

OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N,
                                              unsigned NumLoops) {
  void *Mem =
      C.Allocate(totalSizeToAlloc<Expr *>(N + /*depend-modifier*/ 1 + NumLoops),
                 alignof(OMPDependClause));
  return new (Mem) OMPDependClause(N, NumLoops);
}

void OMPDependClause::setLoopData(unsigned NumLoop, Expr *Cnt) {
  assert((getDependencyKind() == OMPC_DEPEND_sink ||
          getDependencyKind() == OMPC_DEPEND_source) &&
         NumLoop < NumLoops &&
         "Expected sink or source depend + loop index must be less number of "
         "loops.");
  auto *It = std::next(getVarRefs().end(), NumLoop + 1);
  *It = Cnt;
}

Expr *OMPDependClause::getLoopData(unsigned NumLoop) {
  assert((getDependencyKind() == OMPC_DEPEND_sink ||
          getDependencyKind() == OMPC_DEPEND_source) &&
         NumLoop < NumLoops &&
         "Expected sink or source depend + loop index must be less number of "
         "loops.");
  auto *It = std::next(getVarRefs().end(), NumLoop + 1);
  return *It;
}

const Expr *OMPDependClause::getLoopData(unsigned NumLoop) const {
  assert((getDependencyKind() == OMPC_DEPEND_sink ||
          getDependencyKind() == OMPC_DEPEND_source) &&
         NumLoop < NumLoops &&
         "Expected sink or source depend + loop index must be less number of "
         "loops.");
  const auto *It = std::next(getVarRefs().end(), NumLoop + 1);
  return *It;
}

void OMPDependClause::setModifier(Expr *DepModifier) {
  *getVarRefs().end() = DepModifier;
}
Expr *OMPDependClause::getModifier() { return *getVarRefs().end(); }

unsigned OMPClauseMappableExprCommon::getComponentsTotalNumber(
    MappableExprComponentListsRef ComponentLists) {
  unsigned TotalNum = 0u;
  for (auto &C : ComponentLists)
    TotalNum += C.size();
  return TotalNum;
}

unsigned OMPClauseMappableExprCommon::getUniqueDeclarationsTotalNumber(
    ArrayRef<const ValueDecl *> Declarations) {
  llvm::SmallPtrSet<const ValueDecl *, 8> UniqueDecls;
  for (const ValueDecl *D : Declarations) {
    const ValueDecl *VD = D ? cast<ValueDecl>(D->getCanonicalDecl()) : nullptr;
    UniqueDecls.insert(VD);
  }
  return UniqueDecls.size();
}

OMPMapClause *OMPMapClause::Create(
    const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
    ArrayRef<ValueDecl *> Declarations,
    MappableExprComponentListsRef ComponentLists, ArrayRef<Expr *> UDMapperRefs,
    Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapModifiers,
    ArrayRef<SourceLocation> MapModifiersLoc,
    NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId,
    OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc) {
  OMPMappableExprListSizeTy Sizes;
  Sizes.NumVars = Vars.size();
  Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
  Sizes.NumComponentLists = ComponentLists.size();
  Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);

  // We need to allocate:
  // 2 x NumVars x Expr* - we have an original list expression and an associated
  // user-defined mapper for each clause list entry.
  // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
  // with each component list.
  // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
  // number of lists for each unique declaration and the size of each component
  // list.
  // NumComponents x MappableComponent - the total of all the components in all
  // the lists.
  void *Mem = C.Allocate(
      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
                       OMPClauseMappableExprCommon::MappableComponent>(
          2 * Sizes.NumVars + 1, Sizes.NumUniqueDeclarations,
          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
          Sizes.NumComponents));
  OMPMapClause *Clause = new (Mem)
      OMPMapClause(MapModifiers, MapModifiersLoc, UDMQualifierLoc, MapperId,
                   Type, TypeIsImplicit, TypeLoc, Locs, Sizes);

  Clause->setVarRefs(Vars);
  Clause->setUDMapperRefs(UDMapperRefs);
  Clause->setIteratorModifier(IteratorModifier);
  Clause->setClauseInfo(Declarations, ComponentLists);
  Clause->setMapType(Type);
  Clause->setMapLoc(TypeLoc);
  return Clause;
}

OMPMapClause *
OMPMapClause::CreateEmpty(const ASTContext &C,
                          const OMPMappableExprListSizeTy &Sizes) {
  void *Mem = C.Allocate(
      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
                       OMPClauseMappableExprCommon::MappableComponent>(
          2 * Sizes.NumVars + 1, Sizes.NumUniqueDeclarations,
          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
          Sizes.NumComponents));
  OMPMapClause *Clause = new (Mem) OMPMapClause(Sizes);
  Clause->setIteratorModifier(nullptr);
  return Clause;
}

OMPToClause *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) {
  OMPMappableExprListSizeTy Sizes;
  Sizes.NumVars = Vars.size();
  Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
  Sizes.NumComponentLists = ComponentLists.size();
  Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);

  // We need to allocate:
  // 2 x NumVars x Expr* - we have an original list expression and an associated
  // user-defined mapper for each clause list entry.
  // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
  // with each component list.
  // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
  // number of lists for each unique declaration and the size of each component
  // list.
  // NumComponents x MappableComponent - the total of all the components in all
  // the lists.
  void *Mem = C.Allocate(
      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
                       OMPClauseMappableExprCommon::MappableComponent>(
          2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
          Sizes.NumComponents));

  auto *Clause = new (Mem) OMPToClause(MotionModifiers, MotionModifiersLoc,
                                       UDMQualifierLoc, MapperId, Locs, Sizes);

  Clause->setVarRefs(Vars);
  Clause->setUDMapperRefs(UDMapperRefs);
  Clause->setClauseInfo(Declarations, ComponentLists);
  return Clause;
}

OMPToClause *OMPToClause::CreateEmpty(const ASTContext &C,
                                      const OMPMappableExprListSizeTy &Sizes) {
  void *Mem = C.Allocate(
      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
                       OMPClauseMappableExprCommon::MappableComponent>(
          2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
          Sizes.NumComponents));
  return new (Mem) OMPToClause(Sizes);
}

OMPFromClause *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) {
  OMPMappableExprListSizeTy Sizes;
  Sizes.NumVars = Vars.size();
  Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
  Sizes.NumComponentLists = ComponentLists.size();
  Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);

  // We need to allocate:
  // 2 x NumVars x Expr* - we have an original list expression and an associated
  // user-defined mapper for each clause list entry.
  // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
  // with each component list.
  // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
  // number of lists for each unique declaration and the size of each component
  // list.
  // NumComponents x MappableComponent - the total of all the components in all
  // the lists.
  void *Mem = C.Allocate(
      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
                       OMPClauseMappableExprCommon::MappableComponent>(
          2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
          Sizes.NumComponents));

  auto *Clause =
      new (Mem) OMPFromClause(MotionModifiers, MotionModifiersLoc,
                              UDMQualifierLoc, MapperId, Locs, Sizes);

  Clause->setVarRefs(Vars);
  Clause->setUDMapperRefs(UDMapperRefs);
  Clause->setClauseInfo(Declarations, ComponentLists);
  return Clause;
}

OMPFromClause *
OMPFromClause::CreateEmpty(const ASTContext &C,
                           const OMPMappableExprListSizeTy &Sizes) {
  void *Mem = C.Allocate(
      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
                       OMPClauseMappableExprCommon::MappableComponent>(
          2 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
          Sizes.NumComponents));
  return new (Mem) OMPFromClause(Sizes);
}

void OMPUseDevicePtrClause::setPrivateCopies(ArrayRef<Expr *> VL) {
  assert(VL.size() == varlist_size() &&
         "Number of private copies is not the same as the preallocated buffer");
  std::copy(VL.begin(), VL.end(), varlist_end());
}

void OMPUseDevicePtrClause::setInits(ArrayRef<Expr *> VL) {
  assert(VL.size() == varlist_size() &&
         "Number of inits is not the same as the preallocated buffer");
  std::copy(VL.begin(), VL.end(), getPrivateCopies().end());
}

OMPUseDevicePtrClause *OMPUseDevicePtrClause::Create(
    const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef<Expr *> Vars,
    ArrayRef<Expr *> PrivateVars, ArrayRef<Expr *> Inits,
    ArrayRef<ValueDecl *> Declarations,
    MappableExprComponentListsRef ComponentLists) {
  OMPMappableExprListSizeTy Sizes;
  Sizes.NumVars = Vars.size();
  Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
  Sizes.NumComponentLists = ComponentLists.size();
  Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);

  // We need to allocate:
  // NumVars x Expr* - we have an original list expression for each clause
  // list entry.
  // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
  // with each component list.
  // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
  // number of lists for each unique declaration and the size of each component
  // list.
  // NumComponents x MappableComponent - the total of all the components in all
  // the lists.
  void *Mem = C.Allocate(
      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
                       OMPClauseMappableExprCommon::MappableComponent>(
          3 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
          Sizes.NumComponents));

  OMPUseDevicePtrClause *Clause = new (Mem) OMPUseDevicePtrClause(Locs, Sizes);

  Clause->setVarRefs(Vars);
  Clause->setPrivateCopies(PrivateVars);
  Clause->setInits(Inits);
  Clause->setClauseInfo(Declarations, ComponentLists);
  return Clause;
}

OMPUseDevicePtrClause *
OMPUseDevicePtrClause::CreateEmpty(const ASTContext &C,
                                   const OMPMappableExprListSizeTy &Sizes) {
  void *Mem = C.Allocate(
      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
                       OMPClauseMappableExprCommon::MappableComponent>(
          3 * Sizes.NumVars, Sizes.NumUniqueDeclarations,
          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
          Sizes.NumComponents));
  return new (Mem) OMPUseDevicePtrClause(Sizes);
}

OMPUseDeviceAddrClause *
OMPUseDeviceAddrClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs,
                               ArrayRef<Expr *> Vars,
                               ArrayRef<ValueDecl *> Declarations,
                               MappableExprComponentListsRef ComponentLists) {
  OMPMappableExprListSizeTy Sizes;
  Sizes.NumVars = Vars.size();
  Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
  Sizes.NumComponentLists = ComponentLists.size();
  Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);

  // We need to allocate:
  // 3 x NumVars x Expr* - we have an original list expression for each clause
  // list entry and an equal number of private copies and inits.
  // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
  // with each component list.
  // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
  // number of lists for each unique declaration and the size of each component
  // list.
  // NumComponents x MappableComponent - the total of all the components in all
  // the lists.
  void *Mem = C.Allocate(
      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
                       OMPClauseMappableExprCommon::MappableComponent>(
          Sizes.NumVars, Sizes.NumUniqueDeclarations,
          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
          Sizes.NumComponents));

  auto *Clause = new (Mem) OMPUseDeviceAddrClause(Locs, Sizes);

  Clause->setVarRefs(Vars);
  Clause->setClauseInfo(Declarations, ComponentLists);
  return Clause;
}

OMPUseDeviceAddrClause *
OMPUseDeviceAddrClause::CreateEmpty(const ASTContext &C,
                                    const OMPMappableExprListSizeTy &Sizes) {
  void *Mem = C.Allocate(
      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
                       OMPClauseMappableExprCommon::MappableComponent>(
          Sizes.NumVars, Sizes.NumUniqueDeclarations,
          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
          Sizes.NumComponents));
  return new (Mem) OMPUseDeviceAddrClause(Sizes);
}

OMPIsDevicePtrClause *
OMPIsDevicePtrClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs,
                             ArrayRef<Expr *> Vars,
                             ArrayRef<ValueDecl *> Declarations,
                             MappableExprComponentListsRef ComponentLists) {
  OMPMappableExprListSizeTy Sizes;
  Sizes.NumVars = Vars.size();
  Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
  Sizes.NumComponentLists = ComponentLists.size();
  Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);

  // We need to allocate:
  // NumVars x Expr* - we have an original list expression for each clause list
  // entry.
  // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
  // with each component list.
  // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
  // number of lists for each unique declaration and the size of each component
  // list.
  // NumComponents x MappableComponent - the total of all the components in all
  // the lists.
  void *Mem = C.Allocate(
      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
                       OMPClauseMappableExprCommon::MappableComponent>(
          Sizes.NumVars, Sizes.NumUniqueDeclarations,
          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
          Sizes.NumComponents));

  OMPIsDevicePtrClause *Clause = new (Mem) OMPIsDevicePtrClause(Locs, Sizes);

  Clause->setVarRefs(Vars);
  Clause->setClauseInfo(Declarations, ComponentLists);
  return Clause;
}

OMPIsDevicePtrClause *
OMPIsDevicePtrClause::CreateEmpty(const ASTContext &C,
                                  const OMPMappableExprListSizeTy &Sizes) {
  void *Mem = C.Allocate(
      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
                       OMPClauseMappableExprCommon::MappableComponent>(
          Sizes.NumVars, Sizes.NumUniqueDeclarations,
          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
          Sizes.NumComponents));
  return new (Mem) OMPIsDevicePtrClause(Sizes);
}

OMPHasDeviceAddrClause *
OMPHasDeviceAddrClause::Create(const ASTContext &C, const OMPVarListLocTy &Locs,
                               ArrayRef<Expr *> Vars,
                               ArrayRef<ValueDecl *> Declarations,
                               MappableExprComponentListsRef ComponentLists) {
  OMPMappableExprListSizeTy Sizes;
  Sizes.NumVars = Vars.size();
  Sizes.NumUniqueDeclarations = getUniqueDeclarationsTotalNumber(Declarations);
  Sizes.NumComponentLists = ComponentLists.size();
  Sizes.NumComponents = getComponentsTotalNumber(ComponentLists);

  // We need to allocate:
  // NumVars x Expr* - we have an original list expression for each clause list
  // entry.
  // NumUniqueDeclarations x ValueDecl* - unique base declarations associated
  // with each component list.
  // (NumUniqueDeclarations + NumComponentLists) x unsigned - we specify the
  // number of lists for each unique declaration and the size of each component
  // list.
  // NumComponents x MappableComponent - the total of all the components in all
  // the lists.
  void *Mem = C.Allocate(
      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
                       OMPClauseMappableExprCommon::MappableComponent>(
          Sizes.NumVars, Sizes.NumUniqueDeclarations,
          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
          Sizes.NumComponents));

  auto *Clause = new (Mem) OMPHasDeviceAddrClause(Locs, Sizes);

  Clause->setVarRefs(Vars);
  Clause->setClauseInfo(Declarations, ComponentLists);
  return Clause;
}

OMPHasDeviceAddrClause *
OMPHasDeviceAddrClause::CreateEmpty(const ASTContext &C,
                                    const OMPMappableExprListSizeTy &Sizes) {
  void *Mem = C.Allocate(
      totalSizeToAlloc<Expr *, ValueDecl *, unsigned,
                       OMPClauseMappableExprCommon::MappableComponent>(
          Sizes.NumVars, Sizes.NumUniqueDeclarations,
          Sizes.NumUniqueDeclarations + Sizes.NumComponentLists,
          Sizes.NumComponents));
  return new (Mem) OMPHasDeviceAddrClause(Sizes);
}

OMPNontemporalClause *OMPNontemporalClause::Create(const ASTContext &C,
                                                   SourceLocation StartLoc,
                                                   SourceLocation LParenLoc,
                                                   SourceLocation EndLoc,
                                                   ArrayRef<Expr *> VL) {
  // Allocate space for nontemporal variables + private references.
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * VL.size()));
  auto *Clause =
      new (Mem) OMPNontemporalClause(StartLoc, LParenLoc, EndLoc, VL.size());
  Clause->setVarRefs(VL);
  return Clause;
}

OMPNontemporalClause *OMPNontemporalClause::CreateEmpty(const ASTContext &C,
                                                        unsigned N) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * N));
  return new (Mem) OMPNontemporalClause(N);
}

void OMPNontemporalClause::setPrivateRefs(ArrayRef<Expr *> VL) {
  assert(VL.size() == varlist_size() && "Number of private references is not "
                                        "the same as the preallocated buffer");
  std::copy(VL.begin(), VL.end(), varlist_end());
}

OMPInclusiveClause *OMPInclusiveClause::Create(const ASTContext &C,
                                               SourceLocation StartLoc,
                                               SourceLocation LParenLoc,
                                               SourceLocation EndLoc,
                                               ArrayRef<Expr *> VL) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
  auto *Clause =
      new (Mem) OMPInclusiveClause(StartLoc, LParenLoc, EndLoc, VL.size());
  Clause->setVarRefs(VL);
  return Clause;
}

OMPInclusiveClause *OMPInclusiveClause::CreateEmpty(const ASTContext &C,
                                                    unsigned N) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
  return new (Mem) OMPInclusiveClause(N);
}

OMPExclusiveClause *OMPExclusiveClause::Create(const ASTContext &C,
                                               SourceLocation StartLoc,
                                               SourceLocation LParenLoc,
                                               SourceLocation EndLoc,
                                               ArrayRef<Expr *> VL) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
  auto *Clause =
      new (Mem) OMPExclusiveClause(StartLoc, LParenLoc, EndLoc, VL.size());
  Clause->setVarRefs(VL);
  return Clause;
}

OMPExclusiveClause *OMPExclusiveClause::CreateEmpty(const ASTContext &C,
                                                    unsigned N) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
  return new (Mem) OMPExclusiveClause(N);
}

void OMPUsesAllocatorsClause::setAllocatorsData(
    ArrayRef<OMPUsesAllocatorsClause::Data> Data) {
  assert(Data.size() == NumOfAllocators &&
         "Size of allocators data is not the same as the preallocated buffer.");
  for (unsigned I = 0, E = Data.size(); I < E; ++I) {
    const OMPUsesAllocatorsClause::Data &D = Data[I];
    getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
                                 static_cast<int>(ExprOffsets::Allocator)] =
        D.Allocator;
    getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
                                 static_cast<int>(
                                     ExprOffsets::AllocatorTraits)] =
        D.AllocatorTraits;
    getTrailingObjects<
        SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
                          static_cast<int>(ParenLocsOffsets::LParen)] =
        D.LParenLoc;
    getTrailingObjects<
        SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
                          static_cast<int>(ParenLocsOffsets::RParen)] =
        D.RParenLoc;
  }
}

OMPUsesAllocatorsClause::Data
OMPUsesAllocatorsClause::getAllocatorData(unsigned I) const {
  OMPUsesAllocatorsClause::Data Data;
  Data.Allocator =
      getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
                                   static_cast<int>(ExprOffsets::Allocator)];
  Data.AllocatorTraits =
      getTrailingObjects<Expr *>()[I * static_cast<int>(ExprOffsets::Total) +
                                   static_cast<int>(
                                       ExprOffsets::AllocatorTraits)];
  Data.LParenLoc = getTrailingObjects<
      SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
                        static_cast<int>(ParenLocsOffsets::LParen)];
  Data.RParenLoc = getTrailingObjects<
      SourceLocation>()[I * static_cast<int>(ParenLocsOffsets::Total) +
                        static_cast<int>(ParenLocsOffsets::RParen)];
  return Data;
}

OMPUsesAllocatorsClause *
OMPUsesAllocatorsClause::Create(const ASTContext &C, SourceLocation StartLoc,
                                SourceLocation LParenLoc, SourceLocation EndLoc,
                                ArrayRef<OMPUsesAllocatorsClause::Data> Data) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *, SourceLocation>(
      static_cast<int>(ExprOffsets::Total) * Data.size(),
      static_cast<int>(ParenLocsOffsets::Total) * Data.size()));
  auto *Clause = new (Mem)
      OMPUsesAllocatorsClause(StartLoc, LParenLoc, EndLoc, Data.size());
  Clause->setAllocatorsData(Data);
  return Clause;
}

OMPUsesAllocatorsClause *
OMPUsesAllocatorsClause::CreateEmpty(const ASTContext &C, unsigned N) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *, SourceLocation>(
      static_cast<int>(ExprOffsets::Total) * N,
      static_cast<int>(ParenLocsOffsets::Total) * N));
  return new (Mem) OMPUsesAllocatorsClause(N);
}

OMPAffinityClause *
OMPAffinityClause::Create(const ASTContext &C, SourceLocation StartLoc,
                          SourceLocation LParenLoc, SourceLocation ColonLoc,
                          SourceLocation EndLoc, Expr *Modifier,
                          ArrayRef<Expr *> Locators) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(Locators.size() + 1));
  auto *Clause = new (Mem)
      OMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, Locators.size());
  Clause->setModifier(Modifier);
  Clause->setVarRefs(Locators);
  return Clause;
}

OMPAffinityClause *OMPAffinityClause::CreateEmpty(const ASTContext &C,
                                                  unsigned N) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N + 1));
  return new (Mem) OMPAffinityClause(N);
}

OMPInitClause *OMPInitClause::Create(const ASTContext &C, Expr *InteropVar,
                                     OMPInteropInfo &InteropInfo,
                                     SourceLocation StartLoc,
                                     SourceLocation LParenLoc,
                                     SourceLocation VarLoc,
                                     SourceLocation EndLoc) {

  void *Mem =
      C.Allocate(totalSizeToAlloc<Expr *>(InteropInfo.PreferTypes.size() + 1));
  auto *Clause = new (Mem) OMPInitClause(
      InteropInfo.IsTarget, InteropInfo.IsTargetSync, StartLoc, LParenLoc,
      VarLoc, EndLoc, InteropInfo.PreferTypes.size() + 1);
  Clause->setInteropVar(InteropVar);
  llvm::copy(InteropInfo.PreferTypes, Clause->getTrailingObjects<Expr *>() + 1);
  return Clause;
}

OMPInitClause *OMPInitClause::CreateEmpty(const ASTContext &C, unsigned N) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
  return new (Mem) OMPInitClause(N);
}

OMPBindClause *
OMPBindClause::Create(const ASTContext &C, OpenMPBindClauseKind K,
                      SourceLocation KLoc, SourceLocation StartLoc,
                      SourceLocation LParenLoc, SourceLocation EndLoc) {
  return new (C) OMPBindClause(K, KLoc, StartLoc, LParenLoc, EndLoc);
}

OMPBindClause *OMPBindClause::CreateEmpty(const ASTContext &C) {
  return new (C) OMPBindClause();
}

OMPDoacrossClause *
OMPDoacrossClause::Create(const ASTContext &C, SourceLocation StartLoc,
                          SourceLocation LParenLoc, SourceLocation EndLoc,
                          OpenMPDoacrossClauseModifier DepType,
                          SourceLocation DepLoc, SourceLocation ColonLoc,
                          ArrayRef<Expr *> VL, unsigned NumLoops) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + NumLoops),
                         alignof(OMPDoacrossClause));
  OMPDoacrossClause *Clause = new (Mem)
      OMPDoacrossClause(StartLoc, LParenLoc, EndLoc, VL.size(), NumLoops);
  Clause->setDependenceType(DepType);
  Clause->setDependenceLoc(DepLoc);
  Clause->setColonLoc(ColonLoc);
  Clause->setVarRefs(VL);
  for (unsigned I = 0; I < NumLoops; ++I)
    Clause->setLoopData(I, nullptr);
  return Clause;
}

OMPDoacrossClause *OMPDoacrossClause::CreateEmpty(const ASTContext &C,
                                                  unsigned N,
                                                  unsigned NumLoops) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N + NumLoops),
                         alignof(OMPDoacrossClause));
  return new (Mem) OMPDoacrossClause(N, NumLoops);
}

void OMPDoacrossClause::setLoopData(unsigned NumLoop, Expr *Cnt) {
  assert(NumLoop < NumLoops && "Loop index must be less number of loops.");
  auto *It = std::next(getVarRefs().end(), NumLoop);
  *It = Cnt;
}

Expr *OMPDoacrossClause::getLoopData(unsigned NumLoop) {
  assert(NumLoop < NumLoops && "Loop index must be less number of loops.");
  auto *It = std::next(getVarRefs().end(), NumLoop);
  return *It;
}

const Expr *OMPDoacrossClause::getLoopData(unsigned NumLoop) const {
  assert(NumLoop < NumLoops && "Loop index must be less number of loops.");
  const auto *It = std::next(getVarRefs().end(), NumLoop);
  return *It;
}

OMPAbsentClause *OMPAbsentClause::Create(const ASTContext &C,
                                         ArrayRef<OpenMPDirectiveKind> DKVec,
                                         SourceLocation Loc,
                                         SourceLocation LLoc,
                                         SourceLocation RLoc) {
  void *Mem = C.Allocate(totalSizeToAlloc<OpenMPDirectiveKind>(DKVec.size()),
                         alignof(OMPAbsentClause));
  auto *AC = new (Mem) OMPAbsentClause(Loc, LLoc, RLoc, DKVec.size());
  AC->setDirectiveKinds(DKVec);
  return AC;
}

OMPAbsentClause *OMPAbsentClause::CreateEmpty(const ASTContext &C, unsigned K) {
  void *Mem = C.Allocate(totalSizeToAlloc<OpenMPDirectiveKind>(K),
                         alignof(OMPAbsentClause));
  return new (Mem) OMPAbsentClause(K);
}

OMPContainsClause *OMPContainsClause::Create(
    const ASTContext &C, ArrayRef<OpenMPDirectiveKind> DKVec,
    SourceLocation Loc, SourceLocation LLoc, SourceLocation RLoc) {
  void *Mem = C.Allocate(totalSizeToAlloc<OpenMPDirectiveKind>(DKVec.size()),
                         alignof(OMPContainsClause));
  auto *CC = new (Mem) OMPContainsClause(Loc, LLoc, RLoc, DKVec.size());
  CC->setDirectiveKinds(DKVec);
  return CC;
}

OMPContainsClause *OMPContainsClause::CreateEmpty(const ASTContext &C,
                                                  unsigned K) {
  void *Mem = C.Allocate(totalSizeToAlloc<OpenMPDirectiveKind>(K),
                         alignof(OMPContainsClause));
  return new (Mem) OMPContainsClause(K);
}

OMPNumTeamsClause *OMPNumTeamsClause::Create(
    const ASTContext &C, OpenMPDirectiveKind CaptureRegion,
    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
    ArrayRef<Expr *> VL, Stmt *PreInit) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
  OMPNumTeamsClause *Clause =
      new (Mem) OMPNumTeamsClause(C, StartLoc, LParenLoc, EndLoc, VL.size());
  Clause->setVarRefs(VL);
  Clause->setPreInitStmt(PreInit, CaptureRegion);
  return Clause;
}

OMPNumTeamsClause *OMPNumTeamsClause::CreateEmpty(const ASTContext &C,
                                                  unsigned N) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
  return new (Mem) OMPNumTeamsClause(N);
}

OMPThreadLimitClause *OMPThreadLimitClause::Create(
    const ASTContext &C, OpenMPDirectiveKind CaptureRegion,
    SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
    ArrayRef<Expr *> VL, Stmt *PreInit) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
  OMPThreadLimitClause *Clause =
      new (Mem) OMPThreadLimitClause(C, StartLoc, LParenLoc, EndLoc, VL.size());
  Clause->setVarRefs(VL);
  Clause->setPreInitStmt(PreInit, CaptureRegion);
  return Clause;
}

OMPThreadLimitClause *OMPThreadLimitClause::CreateEmpty(const ASTContext &C,
                                                        unsigned N) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
  return new (Mem) OMPThreadLimitClause(N);
}

//===----------------------------------------------------------------------===//
//  OpenMP clauses printing methods
//===----------------------------------------------------------------------===//

void OMPClausePrinter::VisitOMPIfClause(OMPIfClause *Node) {
  OS << "if(";
  if (Node->getNameModifier() != OMPD_unknown)
    OS << getOpenMPDirectiveName(Node->getNameModifier()) << ": ";
  Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
  OS << ")";
}

void OMPClausePrinter::VisitOMPFinalClause(OMPFinalClause *Node) {
  OS << "final(";
  Node->getCondition()->printPretty(OS, nullptr, Policy, 0);
  OS << ")";
}

void OMPClausePrinter::VisitOMPNumThreadsClause(OMPNumThreadsClause *Node) {
  OS << "num_threads(";
  Node->getNumThreads()->printPretty(OS, nullptr, Policy, 0);
  OS << ")";
}

void OMPClausePrinter::VisitOMPAlignClause(OMPAlignClause *Node) {
  OS << "align(";
  Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
  OS << ")";
}

void OMPClausePrinter::VisitOMPSafelenClause(OMPSafelenClause *Node) {
  OS << "safelen(";
  Node->getSafelen()->printPretty(OS, nullptr, Policy, 0);
  OS << ")";
}

void OMPClausePrinter::VisitOMPSimdlenClause(OMPSimdlenClause *Node) {
  OS << "simdlen(";
  Node->getSimdlen()->printPretty(OS, nullptr, Policy, 0);
  OS << ")";
}

void OMPClausePrinter::VisitOMPSizesClause(OMPSizesClause *Node) {
  OS << "sizes(";
  bool First = true;
  for (auto *Size : Node->getSizesRefs()) {
    if (!First)
      OS << ", ";
    Size->printPretty(OS, nullptr, Policy, 0);
    First = false;
  }
  OS << ")";
}

void OMPClausePrinter::VisitOMPPermutationClause(OMPPermutationClause *Node) {
  OS << "permutation(";
  llvm::interleaveComma(Node->getArgsRefs(), OS, [&](const Expr *E) {
    E->printPretty(OS, nullptr, Policy, 0);
  });
  OS << ")";
}

void OMPClausePrinter::VisitOMPFullClause(OMPFullClause *Node) { OS << "full"; }

void OMPClausePrinter::VisitOMPPartialClause(OMPPartialClause *Node) {
  OS << "partial";

  if (Expr *Factor = Node->getFactor()) {
    OS << '(';
    Factor->printPretty(OS, nullptr, Policy, 0);
    OS << ')';
  }
}

void OMPClausePrinter::VisitOMPAllocatorClause(OMPAllocatorClause *Node) {
  OS << "allocator(";
  Node->getAllocator()->printPretty(OS, nullptr, Policy, 0);
  OS << ")";
}

void OMPClausePrinter::VisitOMPCollapseClause(OMPCollapseClause *Node) {
  OS << "collapse(";
  Node->getNumForLoops()->printPretty(OS, nullptr, Policy, 0);
  OS << ")";
}

void OMPClausePrinter::VisitOMPDetachClause(OMPDetachClause *Node) {
  OS << "detach(";
  Node->getEventHandler()->printPretty(OS, nullptr, Policy, 0);
  OS << ")";
}

void OMPClausePrinter::VisitOMPDefaultClause(OMPDefaultClause *Node) {
  OS << "default("
     << getOpenMPSimpleClauseTypeName(OMPC_default,
                                      unsigned(Node->getDefaultKind()))
     << ")";
}

void OMPClausePrinter::VisitOMPProcBindClause(OMPProcBindClause *Node) {
  OS << "proc_bind("
     << getOpenMPSimpleClauseTypeName(OMPC_proc_bind,
                                      unsigned(Node->getProcBindKind()))
     << ")";
}

void OMPClausePrinter::VisitOMPUnifiedAddressClause(OMPUnifiedAddressClause *) {
  OS << "unified_address";
}

void OMPClausePrinter::VisitOMPUnifiedSharedMemoryClause(
    OMPUnifiedSharedMemoryClause *) {
  OS << "unified_shared_memory";
}

void OMPClausePrinter::VisitOMPReverseOffloadClause(OMPReverseOffloadClause *) {
  OS << "reverse_offload";
}

void OMPClausePrinter::VisitOMPDynamicAllocatorsClause(
    OMPDynamicAllocatorsClause *) {
  OS << "dynamic_allocators";
}

void OMPClausePrinter::VisitOMPAtomicDefaultMemOrderClause(
    OMPAtomicDefaultMemOrderClause *Node) {
  OS << "atomic_default_mem_order("
     << getOpenMPSimpleClauseTypeName(OMPC_atomic_default_mem_order,
                                      Node->getAtomicDefaultMemOrderKind())
     << ")";
}

void OMPClausePrinter::VisitOMPAtClause(OMPAtClause *Node) {
  OS << "at(" << getOpenMPSimpleClauseTypeName(OMPC_at, Node->getAtKind())
     << ")";
}

void OMPClausePrinter::VisitOMPSeverityClause(OMPSeverityClause *Node) {
  OS << "severity("
     << getOpenMPSimpleClauseTypeName(OMPC_severity, Node->getSeverityKind())
     << ")";
}

void OMPClausePrinter::VisitOMPMessageClause(OMPMessageClause *Node) {
  OS << "message(\""
     << cast<StringLiteral>(Node->getMessageString())->getString() << "\")";
}

void OMPClausePrinter::VisitOMPScheduleClause(OMPScheduleClause *Node) {
  OS << "schedule(";
  if (Node->getFirstScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
    OS << getOpenMPSimpleClauseTypeName(OMPC_schedule,
                                        Node->getFirstScheduleModifier());
    if (Node->getSecondScheduleModifier() != OMPC_SCHEDULE_MODIFIER_unknown) {
      OS << ", ";
      OS << getOpenMPSimpleClauseTypeName(OMPC_schedule,
                                          Node->getSecondScheduleModifier());
    }
    OS << ": ";
  }
  OS << getOpenMPSimpleClauseTypeName(OMPC_schedule, Node->getScheduleKind());
  if (auto *E = Node->getChunkSize()) {
    OS << ", ";
    E->printPretty(OS, nullptr, Policy);
  }
  OS << ")";
}

void OMPClausePrinter::VisitOMPOrderedClause(OMPOrderedClause *Node) {
  OS << "ordered";
  if (auto *Num = Node->getNumForLoops()) {
    OS << "(";
    Num->printPretty(OS, nullptr, Policy, 0);
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPNowaitClause(OMPNowaitClause *) {
  OS << "nowait";
}

void OMPClausePrinter::VisitOMPUntiedClause(OMPUntiedClause *) {
  OS << "untied";
}

void OMPClausePrinter::VisitOMPNogroupClause(OMPNogroupClause *) {
  OS << "nogroup";
}

void OMPClausePrinter::VisitOMPMergeableClause(OMPMergeableClause *) {
  OS << "mergeable";
}

void OMPClausePrinter::VisitOMPReadClause(OMPReadClause *) { OS << "read"; }

void OMPClausePrinter::VisitOMPWriteClause(OMPWriteClause *) { OS << "write"; }

void OMPClausePrinter::VisitOMPUpdateClause(OMPUpdateClause *Node) {
  OS << "update";
  if (Node->isExtended()) {
    OS << "(";
    OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
                                        Node->getDependencyKind());
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPCaptureClause(OMPCaptureClause *) {
  OS << "capture";
}

void OMPClausePrinter::VisitOMPCompareClause(OMPCompareClause *) {
  OS << "compare";
}

void OMPClausePrinter::VisitOMPFailClause(OMPFailClause *Node) {
  OS << "fail";
  if (Node) {
    OS << "(";
    OS << getOpenMPSimpleClauseTypeName(
        Node->getClauseKind(), static_cast<int>(Node->getFailParameter()));
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPAbsentClause(OMPAbsentClause *Node) {
  OS << "absent(";
  bool First = true;
  for (auto &D : Node->getDirectiveKinds()) {
    if (!First)
      OS << ", ";
    OS << getOpenMPDirectiveName(D);
    First = false;
  }
  OS << ")";
}

void OMPClausePrinter::VisitOMPHoldsClause(OMPHoldsClause *Node) {
  OS << "holds(";
  Node->getExpr()->printPretty(OS, nullptr, Policy, 0);
  OS << ")";
}

void OMPClausePrinter::VisitOMPContainsClause(OMPContainsClause *Node) {
  OS << "contains(";
  bool First = true;
  for (auto &D : Node->getDirectiveKinds()) {
    if (!First)
      OS << ", ";
    OS << getOpenMPDirectiveName(D);
    First = false;
  }
  OS << ")";
}

void OMPClausePrinter::VisitOMPNoOpenMPClause(OMPNoOpenMPClause *) {
  OS << "no_openmp";
}

void OMPClausePrinter::VisitOMPNoOpenMPRoutinesClause(
    OMPNoOpenMPRoutinesClause *) {
  OS << "no_openmp_routines";
}

void OMPClausePrinter::VisitOMPNoParallelismClause(OMPNoParallelismClause *) {
  OS << "no_parallelism";
}

void OMPClausePrinter::VisitOMPSeqCstClause(OMPSeqCstClause *) {
  OS << "seq_cst";
}

void OMPClausePrinter::VisitOMPAcqRelClause(OMPAcqRelClause *) {
  OS << "acq_rel";
}

void OMPClausePrinter::VisitOMPAcquireClause(OMPAcquireClause *) {
  OS << "acquire";
}

void OMPClausePrinter::VisitOMPReleaseClause(OMPReleaseClause *) {
  OS << "release";
}

void OMPClausePrinter::VisitOMPRelaxedClause(OMPRelaxedClause *) {
  OS << "relaxed";
}

void OMPClausePrinter::VisitOMPWeakClause(OMPWeakClause *) { OS << "weak"; }

void OMPClausePrinter::VisitOMPThreadsClause(OMPThreadsClause *) {
  OS << "threads";
}

void OMPClausePrinter::VisitOMPSIMDClause(OMPSIMDClause *) { OS << "simd"; }

void OMPClausePrinter::VisitOMPDeviceClause(OMPDeviceClause *Node) {
  OS << "device(";
  OpenMPDeviceClauseModifier Modifier = Node->getModifier();
  if (Modifier != OMPC_DEVICE_unknown) {
    OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier)
       << ": ";
  }
  Node->getDevice()->printPretty(OS, nullptr, Policy, 0);
  OS << ")";
}

void OMPClausePrinter::VisitOMPNumTeamsClause(OMPNumTeamsClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "num_teams";
    VisitOMPClauseList(Node, '(');
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPThreadLimitClause(OMPThreadLimitClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "thread_limit";
    VisitOMPClauseList(Node, '(');
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPPriorityClause(OMPPriorityClause *Node) {
  OS << "priority(";
  Node->getPriority()->printPretty(OS, nullptr, Policy, 0);
  OS << ")";
}

void OMPClausePrinter::VisitOMPGrainsizeClause(OMPGrainsizeClause *Node) {
  OS << "grainsize(";
  OpenMPGrainsizeClauseModifier Modifier = Node->getModifier();
  if (Modifier != OMPC_GRAINSIZE_unknown) {
    OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier)
       << ": ";
  }
  Node->getGrainsize()->printPretty(OS, nullptr, Policy, 0);
  OS << ")";
}

void OMPClausePrinter::VisitOMPNumTasksClause(OMPNumTasksClause *Node) {
  OS << "num_tasks(";
  OpenMPNumTasksClauseModifier Modifier = Node->getModifier();
  if (Modifier != OMPC_NUMTASKS_unknown) {
    OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier)
       << ": ";
  }
  Node->getNumTasks()->printPretty(OS, nullptr, Policy, 0);
  OS << ")";
}

void OMPClausePrinter::VisitOMPHintClause(OMPHintClause *Node) {
  OS << "hint(";
  Node->getHint()->printPretty(OS, nullptr, Policy, 0);
  OS << ")";
}

void OMPClausePrinter::VisitOMPInitClause(OMPInitClause *Node) {
  OS << "init(";
  bool First = true;
  for (const Expr *E : Node->prefs()) {
    if (First)
      OS << "prefer_type(";
    else
      OS << ",";
    E->printPretty(OS, nullptr, Policy);
    First = false;
  }
  if (!First)
    OS << "), ";
  if (Node->getIsTarget())
    OS << "target";
  if (Node->getIsTargetSync()) {
    if (Node->getIsTarget())
      OS << ", ";
    OS << "targetsync";
  }
  OS << " : ";
  Node->getInteropVar()->printPretty(OS, nullptr, Policy);
  OS << ")";
}

void OMPClausePrinter::VisitOMPUseClause(OMPUseClause *Node) {
  OS << "use(";
  Node->getInteropVar()->printPretty(OS, nullptr, Policy);
  OS << ")";
}

void OMPClausePrinter::VisitOMPDestroyClause(OMPDestroyClause *Node) {
  OS << "destroy";
  if (Expr *E = Node->getInteropVar()) {
    OS << "(";
    E->printPretty(OS, nullptr, Policy);
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPNovariantsClause(OMPNovariantsClause *Node) {
  OS << "novariants";
  if (Expr *E = Node->getCondition()) {
    OS << "(";
    E->printPretty(OS, nullptr, Policy, 0);
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPNocontextClause(OMPNocontextClause *Node) {
  OS << "nocontext";
  if (Expr *E = Node->getCondition()) {
    OS << "(";
    E->printPretty(OS, nullptr, Policy, 0);
    OS << ")";
  }
}

template<typename T>
void OMPClausePrinter::VisitOMPClauseList(T *Node, char StartSym) {
  for (typename T::varlist_iterator I = Node->varlist_begin(),
                                    E = Node->varlist_end();
       I != E; ++I) {
    assert(*I && "Expected non-null Stmt");
    OS << (I == Node->varlist_begin() ? StartSym : ',');
    if (auto *DRE = dyn_cast<DeclRefExpr>(*I)) {
      if (isa<OMPCapturedExprDecl>(DRE->getDecl()))
        DRE->printPretty(OS, nullptr, Policy, 0);
      else
        DRE->getDecl()->printQualifiedName(OS);
    } else
      (*I)->printPretty(OS, nullptr, Policy, 0);
  }
}

void OMPClausePrinter::VisitOMPAllocateClause(OMPAllocateClause *Node) {
  if (Node->varlist_empty())
    return;

  Expr *FirstModifier = nullptr;
  Expr *SecondModifier = nullptr;
  auto FirstAllocMod = Node->getFirstAllocateModifier();
  auto SecondAllocMod = Node->getSecondAllocateModifier();
  bool FirstUnknown = FirstAllocMod == OMPC_ALLOCATE_unknown;
  bool SecondUnknown = SecondAllocMod == OMPC_ALLOCATE_unknown;
  if (FirstAllocMod == OMPC_ALLOCATE_allocator ||
      (FirstAllocMod == OMPC_ALLOCATE_unknown && Node->getAllocator())) {
    FirstModifier = Node->getAllocator();
    SecondModifier = Node->getAlignment();
  } else {
    FirstModifier = Node->getAlignment();
    SecondModifier = Node->getAllocator();
  }

  OS << "allocate";
  // If we have any explicit modifiers.
  if (FirstModifier) {
    OS << "(";
    if (!FirstUnknown) {
      OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), FirstAllocMod);
      OS << "(";
    }
    FirstModifier->printPretty(OS, nullptr, Policy, 0);
    if (!FirstUnknown)
      OS << ")";
    if (SecondModifier) {
      OS << ", ";
      if (!SecondUnknown) {
        OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
                                            SecondAllocMod);
        OS << "(";
      }
      SecondModifier->printPretty(OS, nullptr, Policy, 0);
      if (!SecondUnknown)
        OS << ")";
    }
    OS << ":";
    VisitOMPClauseList(Node, ' ');
  } else {
    // No modifiers. Just print the variable list.
    VisitOMPClauseList(Node, '(');
  }
  OS << ")";
}

void OMPClausePrinter::VisitOMPPrivateClause(OMPPrivateClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "private";
    VisitOMPClauseList(Node, '(');
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPFirstprivateClause(OMPFirstprivateClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "firstprivate";
    VisitOMPClauseList(Node, '(');
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPLastprivateClause(OMPLastprivateClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "lastprivate";
    OpenMPLastprivateModifier LPKind = Node->getKind();
    if (LPKind != OMPC_LASTPRIVATE_unknown) {
      OS << "("
         << getOpenMPSimpleClauseTypeName(OMPC_lastprivate, Node->getKind())
         << ":";
    }
    VisitOMPClauseList(Node, LPKind == OMPC_LASTPRIVATE_unknown ? '(' : ' ');
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPSharedClause(OMPSharedClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "shared";
    VisitOMPClauseList(Node, '(');
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "reduction(";
    if (Node->getModifierLoc().isValid())
      OS << getOpenMPSimpleClauseTypeName(OMPC_reduction, Node->getModifier())
         << ", ";
    NestedNameSpecifier *QualifierLoc =
        Node->getQualifierLoc().getNestedNameSpecifier();
    OverloadedOperatorKind OOK =
        Node->getNameInfo().getName().getCXXOverloadedOperator();
    if (QualifierLoc == nullptr && OOK != OO_None) {
      // Print reduction identifier in C format
      OS << getOperatorSpelling(OOK);
    } else {
      // Use C++ format
      if (QualifierLoc != nullptr)
        QualifierLoc->print(OS, Policy);
      OS << Node->getNameInfo();
    }
    OS << ":";
    VisitOMPClauseList(Node, ' ');
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPTaskReductionClause(
    OMPTaskReductionClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "task_reduction(";
    NestedNameSpecifier *QualifierLoc =
        Node->getQualifierLoc().getNestedNameSpecifier();
    OverloadedOperatorKind OOK =
        Node->getNameInfo().getName().getCXXOverloadedOperator();
    if (QualifierLoc == nullptr && OOK != OO_None) {
      // Print reduction identifier in C format
      OS << getOperatorSpelling(OOK);
    } else {
      // Use C++ format
      if (QualifierLoc != nullptr)
        QualifierLoc->print(OS, Policy);
      OS << Node->getNameInfo();
    }
    OS << ":";
    VisitOMPClauseList(Node, ' ');
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPInReductionClause(OMPInReductionClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "in_reduction(";
    NestedNameSpecifier *QualifierLoc =
        Node->getQualifierLoc().getNestedNameSpecifier();
    OverloadedOperatorKind OOK =
        Node->getNameInfo().getName().getCXXOverloadedOperator();
    if (QualifierLoc == nullptr && OOK != OO_None) {
      // Print reduction identifier in C format
      OS << getOperatorSpelling(OOK);
    } else {
      // Use C++ format
      if (QualifierLoc != nullptr)
        QualifierLoc->print(OS, Policy);
      OS << Node->getNameInfo();
    }
    OS << ":";
    VisitOMPClauseList(Node, ' ');
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "linear";
    VisitOMPClauseList(Node, '(');
    if (Node->getModifierLoc().isValid() || Node->getStep() != nullptr) {
      OS << ": ";
    }
    if (Node->getModifierLoc().isValid()) {
      OS << getOpenMPSimpleClauseTypeName(OMPC_linear, Node->getModifier());
    }
    if (Node->getStep() != nullptr) {
      if (Node->getModifierLoc().isValid()) {
        OS << ", ";
      }
      OS << "step(";
      Node->getStep()->printPretty(OS, nullptr, Policy, 0);
      OS << ")";
    }
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPAlignedClause(OMPAlignedClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "aligned";
    VisitOMPClauseList(Node, '(');
    if (Node->getAlignment() != nullptr) {
      OS << ": ";
      Node->getAlignment()->printPretty(OS, nullptr, Policy, 0);
    }
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPCopyinClause(OMPCopyinClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "copyin";
    VisitOMPClauseList(Node, '(');
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPCopyprivateClause(OMPCopyprivateClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "copyprivate";
    VisitOMPClauseList(Node, '(');
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPFlushClause(OMPFlushClause *Node) {
  if (!Node->varlist_empty()) {
    VisitOMPClauseList(Node, '(');
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPDepobjClause(OMPDepobjClause *Node) {
  OS << "(";
  Node->getDepobj()->printPretty(OS, nullptr, Policy, 0);
  OS << ")";
}

void OMPClausePrinter::VisitOMPDependClause(OMPDependClause *Node) {
  OS << "depend(";
  if (Expr *DepModifier = Node->getModifier()) {
    DepModifier->printPretty(OS, nullptr, Policy);
    OS << ", ";
  }
  OpenMPDependClauseKind DepKind = Node->getDependencyKind();
  OpenMPDependClauseKind PrintKind = DepKind;
  bool IsOmpAllMemory = false;
  if (PrintKind == OMPC_DEPEND_outallmemory) {
    PrintKind = OMPC_DEPEND_out;
    IsOmpAllMemory = true;
  } else if (PrintKind == OMPC_DEPEND_inoutallmemory) {
    PrintKind = OMPC_DEPEND_inout;
    IsOmpAllMemory = true;
  }
  OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), PrintKind);
  if (!Node->varlist_empty() || IsOmpAllMemory)
    OS << " :";
  VisitOMPClauseList(Node, ' ');
  if (IsOmpAllMemory) {
    OS << (Node->varlist_empty() ? " " : ",");
    OS << "omp_all_memory";
  }
  OS << ")";
}

template <typename T>
static void PrintMapper(raw_ostream &OS, T *Node,
                        const PrintingPolicy &Policy) {
  OS << '(';
  NestedNameSpecifier *MapperNNS =
      Node->getMapperQualifierLoc().getNestedNameSpecifier();
  if (MapperNNS)
    MapperNNS->print(OS, Policy);
  OS << Node->getMapperIdInfo() << ')';
}

template <typename T>
static void PrintIterator(raw_ostream &OS, T *Node,
                          const PrintingPolicy &Policy) {
  if (Expr *IteratorModifier = Node->getIteratorModifier())
    IteratorModifier->printPretty(OS, nullptr, Policy);
}

void OMPClausePrinter::VisitOMPMapClause(OMPMapClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "map(";
    if (Node->getMapType() != OMPC_MAP_unknown) {
      for (unsigned I = 0; I < NumberOfOMPMapClauseModifiers; ++I) {
        if (Node->getMapTypeModifier(I) != OMPC_MAP_MODIFIER_unknown) {
          if (Node->getMapTypeModifier(I) == OMPC_MAP_MODIFIER_iterator) {
            PrintIterator(OS, Node, Policy);
          } else {
            OS << getOpenMPSimpleClauseTypeName(OMPC_map,
                                                Node->getMapTypeModifier(I));
            if (Node->getMapTypeModifier(I) == OMPC_MAP_MODIFIER_mapper)
              PrintMapper(OS, Node, Policy);
          }
          OS << ',';
        }
      }
      OS << getOpenMPSimpleClauseTypeName(OMPC_map, Node->getMapType());
      OS << ':';
    }
    VisitOMPClauseList(Node, ' ');
    OS << ")";
  }
}

template <typename T> void OMPClausePrinter::VisitOMPMotionClause(T *Node) {
  if (Node->varlist_empty())
    return;
  OS << getOpenMPClauseName(Node->getClauseKind());
  unsigned ModifierCount = 0;
  for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
    if (Node->getMotionModifier(I) != OMPC_MOTION_MODIFIER_unknown)
      ++ModifierCount;
  }
  if (ModifierCount) {
    OS << '(';
    for (unsigned I = 0; I < NumberOfOMPMotionModifiers; ++I) {
      if (Node->getMotionModifier(I) != OMPC_MOTION_MODIFIER_unknown) {
        OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(),
                                            Node->getMotionModifier(I));
        if (Node->getMotionModifier(I) == OMPC_MOTION_MODIFIER_mapper)
          PrintMapper(OS, Node, Policy);
        if (I < ModifierCount - 1)
          OS << ", ";
      }
    }
    OS << ':';
    VisitOMPClauseList(Node, ' ');
  } else {
    VisitOMPClauseList(Node, '(');
  }
  OS << ")";
}

void OMPClausePrinter::VisitOMPToClause(OMPToClause *Node) {
  VisitOMPMotionClause(Node);
}

void OMPClausePrinter::VisitOMPFromClause(OMPFromClause *Node) {
  VisitOMPMotionClause(Node);
}

void OMPClausePrinter::VisitOMPDistScheduleClause(OMPDistScheduleClause *Node) {
  OS << "dist_schedule(" << getOpenMPSimpleClauseTypeName(
                           OMPC_dist_schedule, Node->getDistScheduleKind());
  if (auto *E = Node->getChunkSize()) {
    OS << ", ";
    E->printPretty(OS, nullptr, Policy);
  }
  OS << ")";
}

void OMPClausePrinter::VisitOMPDefaultmapClause(OMPDefaultmapClause *Node) {
  OS << "defaultmap(";
  OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
                                      Node->getDefaultmapModifier());
  if (Node->getDefaultmapKind() != OMPC_DEFAULTMAP_unknown) {
    OS << ": ";
    OS << getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
                                        Node->getDefaultmapKind());
  }
  OS << ")";
}

void OMPClausePrinter::VisitOMPUseDevicePtrClause(OMPUseDevicePtrClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "use_device_ptr";
    VisitOMPClauseList(Node, '(');
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPUseDeviceAddrClause(
    OMPUseDeviceAddrClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "use_device_addr";
    VisitOMPClauseList(Node, '(');
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPIsDevicePtrClause(OMPIsDevicePtrClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "is_device_ptr";
    VisitOMPClauseList(Node, '(');
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPHasDeviceAddrClause(OMPHasDeviceAddrClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "has_device_addr";
    VisitOMPClauseList(Node, '(');
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPNontemporalClause(OMPNontemporalClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "nontemporal";
    VisitOMPClauseList(Node, '(');
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPOrderClause(OMPOrderClause *Node) {
  OS << "order(";
  if (Node->getModifier() != OMPC_ORDER_MODIFIER_unknown) {
    OS << getOpenMPSimpleClauseTypeName(OMPC_order, Node->getModifier());
    OS << ": ";
  }
  OS << getOpenMPSimpleClauseTypeName(OMPC_order, Node->getKind()) << ")";
}

void OMPClausePrinter::VisitOMPInclusiveClause(OMPInclusiveClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "inclusive";
    VisitOMPClauseList(Node, '(');
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPExclusiveClause(OMPExclusiveClause *Node) {
  if (!Node->varlist_empty()) {
    OS << "exclusive";
    VisitOMPClauseList(Node, '(');
    OS << ")";
  }
}

void OMPClausePrinter::VisitOMPUsesAllocatorsClause(
    OMPUsesAllocatorsClause *Node) {
  if (Node->getNumberOfAllocators() == 0)
    return;
  OS << "uses_allocators(";
  for (unsigned I = 0, E = Node->getNumberOfAllocators(); I < E; ++I) {
    OMPUsesAllocatorsClause::Data Data = Node->getAllocatorData(I);
    Data.Allocator->printPretty(OS, nullptr, Policy);
    if (Data.AllocatorTraits) {
      OS << "(";
      Data.AllocatorTraits->printPretty(OS, nullptr, Policy);
      OS << ")";
    }
    if (I < E - 1)
      OS << ",";
  }
  OS << ")";
}

void OMPClausePrinter::VisitOMPAffinityClause(OMPAffinityClause *Node) {
  if (Node->varlist_empty())
    return;
  OS << "affinity";
  char StartSym = '(';
  if (Expr *Modifier = Node->getModifier()) {
    OS << "(";
    Modifier->printPretty(OS, nullptr, Policy);
    OS << " :";
    StartSym = ' ';
  }
  VisitOMPClauseList(Node, StartSym);
  OS << ")";
}

void OMPClausePrinter::VisitOMPFilterClause(OMPFilterClause *Node) {
  OS << "filter(";
  Node->getThreadID()->printPretty(OS, nullptr, Policy, 0);
  OS << ")";
}

void OMPClausePrinter::VisitOMPBindClause(OMPBindClause *Node) {
  OS << "bind("
     << getOpenMPSimpleClauseTypeName(OMPC_bind, unsigned(Node->getBindKind()))
     << ")";
}

void OMPClausePrinter::VisitOMPXDynCGroupMemClause(
    OMPXDynCGroupMemClause *Node) {
  OS << "ompx_dyn_cgroup_mem(";
  Node->getSize()->printPretty(OS, nullptr, Policy, 0);
  OS << ")";
}

void OMPClausePrinter::VisitOMPDoacrossClause(OMPDoacrossClause *Node) {
  OS << "doacross(";
  OpenMPDoacrossClauseModifier DepType = Node->getDependenceType();

  switch (DepType) {
  case OMPC_DOACROSS_source:
    OS << "source:";
    break;
  case OMPC_DOACROSS_sink:
    OS << "sink:";
    break;
  case OMPC_DOACROSS_source_omp_cur_iteration:
    OS << "source: omp_cur_iteration";
    break;
  case OMPC_DOACROSS_sink_omp_cur_iteration:
    OS << "sink: omp_cur_iteration - 1";
    break;
  default:
    llvm_unreachable("unknown docaross modifier");
  }
  VisitOMPClauseList(Node, ' ');
  OS << ")";
}

void OMPClausePrinter::VisitOMPXAttributeClause(OMPXAttributeClause *Node) {
  OS << "ompx_attribute(";
  bool IsFirst = true;
  for (auto &Attr : Node->getAttrs()) {
    if (!IsFirst)
      OS << ", ";
    Attr->printPretty(OS, Policy);
    IsFirst = false;
  }
  OS << ")";
}

void OMPClausePrinter::VisitOMPXBareClause(OMPXBareClause *Node) {
  OS << "ompx_bare";
}

void OMPTraitInfo::getAsVariantMatchInfo(ASTContext &ASTCtx,
                                         VariantMatchInfo &VMI) const {
  for (const OMPTraitSet &Set : Sets) {
    for (const OMPTraitSelector &Selector : Set.Selectors) {

      // User conditions are special as we evaluate the condition here.
      if (Selector.Kind == TraitSelector::user_condition) {
        assert(Selector.ScoreOrCondition &&
               "Ill-formed user condition, expected condition expression!");
        assert(Selector.Properties.size() == 1 &&
               Selector.Properties.front().Kind ==
                   TraitProperty::user_condition_unknown &&
               "Ill-formed user condition, expected unknown trait property!");

        if (std::optional<APSInt> CondVal =
                Selector.ScoreOrCondition->getIntegerConstantExpr(ASTCtx))
          VMI.addTrait(CondVal->isZero() ? TraitProperty::user_condition_false
                                         : TraitProperty::user_condition_true,
                       "<condition>");
        else
          VMI.addTrait(TraitProperty::user_condition_false, "<condition>");
        continue;
      }

      std::optional<llvm::APSInt> Score;
      llvm::APInt *ScorePtr = nullptr;
      if (Selector.ScoreOrCondition) {
        if ((Score = Selector.ScoreOrCondition->getIntegerConstantExpr(ASTCtx)))
          ScorePtr = &*Score;
        else
          VMI.addTrait(TraitProperty::user_condition_false,
                       "<non-constant-score>");
      }

      for (const OMPTraitProperty &Property : Selector.Properties)
        VMI.addTrait(Set.Kind, Property.Kind, Property.RawString, ScorePtr);

      if (Set.Kind != TraitSet::construct)
        continue;

      // TODO: This might not hold once we implement SIMD properly.
      assert(Selector.Properties.size() == 1 &&
             Selector.Properties.front().Kind ==
                 getOpenMPContextTraitPropertyForSelector(
                     Selector.Kind) &&
             "Ill-formed construct selector!");
    }
  }
}

void OMPTraitInfo::print(llvm::raw_ostream &OS,
                         const PrintingPolicy &Policy) const {
  bool FirstSet = true;
  for (const OMPTraitSet &Set : Sets) {
    if (!FirstSet)
      OS << ", ";
    FirstSet = false;
    OS << getOpenMPContextTraitSetName(Set.Kind) << "={";

    bool FirstSelector = true;
    for (const OMPTraitSelector &Selector : Set.Selectors) {
      if (!FirstSelector)
        OS << ", ";
      FirstSelector = false;
      OS << getOpenMPContextTraitSelectorName(Selector.Kind);

      bool AllowsTraitScore = false;
      bool RequiresProperty = false;
      isValidTraitSelectorForTraitSet(
          Selector.Kind, Set.Kind, AllowsTraitScore, RequiresProperty);

      if (!RequiresProperty)
        continue;

      OS << "(";
      if (Selector.Kind == TraitSelector::user_condition) {
        if (Selector.ScoreOrCondition)
          Selector.ScoreOrCondition->printPretty(OS, nullptr, Policy);
        else
          OS << "...";
      } else {

        if (Selector.ScoreOrCondition) {
          OS << "score(";
          Selector.ScoreOrCondition->printPretty(OS, nullptr, Policy);
          OS << "): ";
        }

        bool FirstProperty = true;
        for (const OMPTraitProperty &Property : Selector.Properties) {
          if (!FirstProperty)
            OS << ", ";
          FirstProperty = false;
          OS << getOpenMPContextTraitPropertyName(Property.Kind,
                                                  Property.RawString);
        }
      }
      OS << ")";
    }
    OS << "}";
  }
}

std::string OMPTraitInfo::getMangledName() const {
  std::string MangledName;
  llvm::raw_string_ostream OS(MangledName);
  for (const OMPTraitSet &Set : Sets) {
    OS << '$' << 'S' << unsigned(Set.Kind);
    for (const OMPTraitSelector &Selector : Set.Selectors) {

      bool AllowsTraitScore = false;
      bool RequiresProperty = false;
      isValidTraitSelectorForTraitSet(
          Selector.Kind, Set.Kind, AllowsTraitScore, RequiresProperty);
      OS << '$' << 's' << unsigned(Selector.Kind);

      if (!RequiresProperty ||
          Selector.Kind == TraitSelector::user_condition)
        continue;

      for (const OMPTraitProperty &Property : Selector.Properties)
        OS << '$' << 'P'
           << getOpenMPContextTraitPropertyName(Property.Kind,
                                                Property.RawString);
    }
  }
  return MangledName;
}

OMPTraitInfo::OMPTraitInfo(StringRef MangledName) {
  unsigned long U;
  do {
    if (!MangledName.consume_front("$S"))
      break;
    if (MangledName.consumeInteger(10, U))
      break;
    Sets.push_back(OMPTraitSet());
    OMPTraitSet &Set = Sets.back();
    Set.Kind = TraitSet(U);
    do {
      if (!MangledName.consume_front("$s"))
        break;
      if (MangledName.consumeInteger(10, U))
        break;
      Set.Selectors.push_back(OMPTraitSelector());
      OMPTraitSelector &Selector = Set.Selectors.back();
      Selector.Kind = TraitSelector(U);
      do {
        if (!MangledName.consume_front("$P"))
          break;
        Selector.Properties.push_back(OMPTraitProperty());
        OMPTraitProperty &Property = Selector.Properties.back();
        std::pair<StringRef, StringRef> PropRestPair = MangledName.split('$');
        Property.RawString = PropRestPair.first;
        Property.Kind = getOpenMPContextTraitPropertyKind(
            Set.Kind, Selector.Kind, PropRestPair.first);
        MangledName = MangledName.drop_front(PropRestPair.first.size());
      } while (true);
    } while (true);
  } while (true);
}

llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
                                     const OMPTraitInfo &TI) {
  LangOptions LO;
  PrintingPolicy Policy(LO);
  TI.print(OS, Policy);
  return OS;
}
llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
                                     const OMPTraitInfo *TI) {
  return TI ? OS << *TI : OS;
}

TargetOMPContext::TargetOMPContext(
    ASTContext &ASTCtx, std::function<void(StringRef)> &&DiagUnknownTrait,
    const FunctionDecl *CurrentFunctionDecl,
    ArrayRef<llvm::omp::TraitProperty> ConstructTraits)
    : OMPContext(ASTCtx.getLangOpts().OpenMPIsTargetDevice,
                 ASTCtx.getTargetInfo().getTriple()),
      FeatureValidityCheck([&](StringRef FeatureName) {
        return ASTCtx.getTargetInfo().isValidFeatureName(FeatureName);
      }),
      DiagUnknownTrait(std::move(DiagUnknownTrait)) {
  ASTCtx.getFunctionFeatureMap(FeatureMap, CurrentFunctionDecl);

  for (llvm::omp::TraitProperty Property : ConstructTraits)
    addTrait(Property);
}

bool TargetOMPContext::matchesISATrait(StringRef RawString) const {
  auto It = FeatureMap.find(RawString);
  if (It != FeatureMap.end())
    return It->second;
  if (!FeatureValidityCheck(RawString))
    DiagUnknownTrait(RawString);
  return false;
}
