//===- 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_self_maps:
  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_self_maps:
  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()[NumLoop] = NumIterations;
}

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

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

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

const Expr *OMPOrderedClause::getLoopCounter(unsigned NumLoop) const {
  assert(NumLoop < NumberOfLoops && "out of loops number.");
  return getTrailingObjects()[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");
  llvm::copy(VL, 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");
  llvm::copy(VL, varlist_end());
}

void OMPFirstprivateClause::setInits(ArrayRef<Expr *> VL) {
  assert(VL.size() == varlist_size() &&
         "Number of inits is not the same as the preallocated buffer");
  llvm::copy(VL, 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");
  llvm::copy(PrivateCopies, 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");
  llvm::copy(SrcExprs, 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");
  llvm::copy(DstExprs, 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");
  llvm::copy(AssignmentOps, 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");
  llvm::copy(PL, varlist_end());
}

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

void OMPLinearClause::setUpdates(ArrayRef<Expr *> UL) {
  assert(UL.size() == varlist_size() &&
         "Number of updates is not the same as the preallocated buffer");
  llvm::copy(UL, 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");
  llvm::copy(FL, 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");
  llvm::copy(UE, 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");
  llvm::copy(SrcExprs, 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");
  llvm::copy(DstExprs, 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");
  llvm::copy(AssignmentOps, 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");
  llvm::copy(SrcExprs, 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");
  llvm::copy(DstExprs, 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");
  llvm::copy(AssignmentOps, 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");
  llvm::copy(Privates, 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");
  llvm::copy(LHSExprs, 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");
  llvm::copy(RHSExprs, 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");
  llvm::copy(ReductionOps, 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,
    ArrayRef<bool> IsPrivateVarReduction,
    OpenMPOriginalSharingModifier OrignalSharingModifier) {
  void *Mem = C.Allocate(totalSizeToAlloc<Expr *, bool>(
      (Modifier == OMPC_REDUCTION_inscan ? 8 : 5) * VL.size(), VL.size()));
  auto *Clause = new (Mem) OMPReductionClause(
      StartLoc, LParenLoc, ModifierLoc, EndLoc, ColonLoc, Modifier,
      OrignalSharingModifier, 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);
  Clause->setPrivateVariableReductionFlags(IsPrivateVarReduction);
  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 *, bool>(
      (Modifier == OMPC_REDUCTION_inscan ? 8 : 5) * N, 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");
  llvm::copy(Privates, 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");
  llvm::copy(LHSExprs, 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");
  llvm::copy(RHSExprs, 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");
  llvm::copy(ReductionOps, 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");
  llvm::copy(Privates, 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");
  llvm::copy(LHSExprs, 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");
  llvm::copy(RHSExprs, 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");
  llvm::copy(ReductionOps, 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");
  llvm::copy(TaskgroupDescriptors, 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");
  llvm::copy(VL, varlist_end());
}

void OMPUseDevicePtrClause::setInits(ArrayRef<Expr *> VL) {
  assert(VL.size() == varlist_size() &&
         "Number of inits is not the same as the preallocated buffer");
  llvm::copy(VL, 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");
  llvm::copy(VL, 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() + 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(), Version) << ": ";
  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(";
  OpenMPNumThreadsClauseModifier Modifier = Node->getModifier();
  if (Modifier != OMPC_NUMTHREADS_unknown) {
    OS << getOpenMPSimpleClauseTypeName(Node->getClauseKind(), Modifier)
       << ": ";
  }
  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::VisitOMPSelfMapsClause(OMPSelfMapsClause *) {
  OS << "self_maps";
}

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, Version);
    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, Version);
    First = false;
  }
  OS << ")";
}

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

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

void OMPClausePrinter::VisitOMPNoOpenMPConstructsClause(
    OMPNoOpenMPConstructsClause *) {
  OS << "no_openmp_constructs";
}

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, int DeviceNum)
    : OMPContext(ASTCtx.getLangOpts().OpenMPIsTargetDevice,
                 ASTCtx.getTargetInfo().getTriple(),
                 ASTCtx.getLangOpts().OMPTargetTriples.empty()
                     ? llvm::Triple()
                     : ASTCtx.getLangOpts().OMPTargetTriples[0],
                 DeviceNum),
      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;
}
