//===-- Clauses.cpp -- OpenMP clause handling -----------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "Clauses.h"

#include "flang/Common/idioms.h"
#include "flang/Evaluate/expression.h"
#include "flang/Parser/parse-tree.h"
#include "flang/Semantics/expression.h"
#include "flang/Semantics/symbol.h"

#include "llvm/Frontend/OpenMP/OMPConstants.h"

#include <list>
#include <optional>
#include <tuple>
#include <utility>
#include <variant>

namespace detail {
template <typename C>
llvm::omp::Clause getClauseIdForClass(C &&) {
  using namespace Fortran;
  using A = llvm::remove_cvref_t<C>; // A is referenced in OMP.inc
  // The code included below contains a sequence of checks like the following
  // for each OpenMP clause
  //   if constexpr (std::is_same_v<A, parser::OmpClause::AcqRel>)
  //     return llvm::omp::Clause::OMPC_acq_rel;
  //   [...]
#define GEN_FLANG_CLAUSE_PARSER_KIND_MAP
#include "llvm/Frontend/OpenMP/OMP.inc"
}
} // namespace detail

static llvm::omp::Clause getClauseId(const Fortran::parser::OmpClause &clause) {
  return std::visit([](auto &&s) { return detail::getClauseIdForClass(s); },
                    clause.u);
}

namespace Fortran::lower::omp {
using SymbolWithDesignator = std::tuple<semantics::Symbol *, MaybeExpr>;

struct SymbolAndDesignatorExtractor {
  template <typename T>
  static T &&AsRvalueRef(T &&t) {
    return std::move(t);
  }
  template <typename T>
  static T AsRvalueRef(const T &t) {
    return t;
  }

  static semantics::Symbol *symbol_addr(const evaluate::SymbolRef &ref) {
    // Symbols cannot be created after semantic checks, so all symbol
    // pointers that are non-null must point to one of those pre-existing
    // objects. Throughout the code, symbols are often pointed to by
    // non-const pointers, so there is no harm in casting the constness
    // away.
    return const_cast<semantics::Symbol *>(&ref.get());
  }

  template <typename T>
  static SymbolWithDesignator visit(T &&) {
    // Use this to see missing overloads:
    // llvm::errs() << "NULL: " << __PRETTY_FUNCTION__ << '\n';
    return SymbolWithDesignator{};
  }

  template <typename T>
  static SymbolWithDesignator visit(const evaluate::Designator<T> &e) {
    return std::make_tuple(symbol_addr(*e.GetLastSymbol()),
                           evaluate::AsGenericExpr(AsRvalueRef(e)));
  }

  static SymbolWithDesignator visit(const evaluate::ProcedureDesignator &e) {
    return std::make_tuple(symbol_addr(*e.GetSymbol()), std::nullopt);
  }

  template <typename T>
  static SymbolWithDesignator visit(const evaluate::Expr<T> &e) {
    return std::visit([](auto &&s) { return visit(s); }, e.u);
  }

  static void verify(const SymbolWithDesignator &sd) {
    const semantics::Symbol *symbol = std::get<0>(sd);
    assert(symbol && "Expecting symbol");
    auto &maybeDsg = std::get<1>(sd);
    if (!maybeDsg)
      return; // Symbol with no designator -> OK
    std::optional<evaluate::DataRef> maybeRef =
        evaluate::ExtractDataRef(*maybeDsg);
    if (maybeRef) {
      if (&maybeRef->GetLastSymbol() == symbol)
        return; // Symbol with a designator for it -> OK
      llvm_unreachable("Expecting designator for given symbol");
    } else {
      // This could still be a Substring or ComplexPart, but at least Substring
      // is not allowed in OpenMP.
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
      maybeDsg->dump();
#endif
      llvm_unreachable("Expecting DataRef designator");
    }
  }
};

SymbolWithDesignator getSymbolAndDesignator(const MaybeExpr &expr) {
  if (!expr)
    return SymbolWithDesignator{};
  return std::visit(
      [](auto &&s) { return SymbolAndDesignatorExtractor::visit(s); }, expr->u);
}

Object makeObject(const parser::Name &name,
                  semantics::SemanticsContext &semaCtx) {
  assert(name.symbol && "Expecting Symbol");
  return Object{name.symbol, std::nullopt};
}

Object makeObject(const parser::Designator &dsg,
                  semantics::SemanticsContext &semaCtx) {
  evaluate::ExpressionAnalyzer ea{semaCtx};
  SymbolWithDesignator sd = getSymbolAndDesignator(ea.Analyze(dsg));
  SymbolAndDesignatorExtractor::verify(sd);
  return Object{std::get<0>(sd), std::move(std::get<1>(sd))};
}

Object makeObject(const parser::StructureComponent &comp,
                  semantics::SemanticsContext &semaCtx) {
  evaluate::ExpressionAnalyzer ea{semaCtx};
  SymbolWithDesignator sd = getSymbolAndDesignator(ea.Analyze(comp));
  SymbolAndDesignatorExtractor::verify(sd);
  return Object{std::get<0>(sd), std::move(std::get<1>(sd))};
}

Object makeObject(const parser::OmpObject &object,
                  semantics::SemanticsContext &semaCtx) {
  // If object is a common block, expression analyzer won't be able to
  // do anything.
  if (const auto *name = std::get_if<parser::Name>(&object.u)) {
    assert(name->symbol && "Expecting Symbol");
    return Object{name->symbol, std::nullopt};
  }
  // OmpObject is std::variant<Designator, /*common block*/ Name>;
  return makeObject(std::get<parser::Designator>(object.u), semaCtx);
}

std::optional<Object>
getBaseObject(const Object &object,
              Fortran::semantics::SemanticsContext &semaCtx) {
  // If it's just the symbol, then there is no base.
  if (!object.id())
    return std::nullopt;

  auto maybeRef = evaluate::ExtractDataRef(*object.ref());
  if (!maybeRef)
    return std::nullopt;

  evaluate::DataRef ref = *maybeRef;

  if (std::get_if<evaluate::SymbolRef>(&ref.u)) {
    return std::nullopt;
  } else if (auto *comp = std::get_if<evaluate::Component>(&ref.u)) {
    const evaluate::DataRef &base = comp->base();
    return Object{
        SymbolAndDesignatorExtractor::symbol_addr(base.GetLastSymbol()),
        evaluate::AsGenericExpr(
            SymbolAndDesignatorExtractor::AsRvalueRef(base))};
  } else if (auto *arr = std::get_if<evaluate::ArrayRef>(&ref.u)) {
    const evaluate::NamedEntity &base = arr->base();
    evaluate::ExpressionAnalyzer ea{semaCtx};
    if (auto *comp = base.UnwrapComponent()) {
      return Object{SymbolAndDesignatorExtractor::symbol_addr(comp->symbol()),
                    ea.Designate(evaluate::DataRef{
                        SymbolAndDesignatorExtractor::AsRvalueRef(*comp)})};
    } else if (base.UnwrapSymbolRef()) {
      return std::nullopt;
    }
  } else {
    assert(std::holds_alternative<evaluate::CoarrayRef>(ref.u) &&
           "Unexpected variant alternative");
    llvm_unreachable("Coarray reference not supported at the moment");
  }
  return std::nullopt;
}

// Helper macros
#define MAKE_EMPTY_CLASS(cls, from_cls)                                        \
  cls make(const parser::OmpClause::from_cls &,                                \
           semantics::SemanticsContext &) {                                    \
    static_assert(cls::EmptyTrait::value);                                     \
    return cls{};                                                              \
  }                                                                            \
  [[maybe_unused]] extern int xyzzy_semicolon_absorber

#define MAKE_INCOMPLETE_CLASS(cls, from_cls)                                   \
  cls make(const parser::OmpClause::from_cls &,                                \
           semantics::SemanticsContext &) {                                    \
    static_assert(cls::IncompleteTrait::value);                                \
    return cls{};                                                              \
  }                                                                            \
  [[maybe_unused]] extern int xyzzy_semicolon_absorber

#define MS(x, y) CLAUSET_SCOPED_ENUM_MEMBER_CONVERT(x, y)
#define MU(x, y) CLAUSET_UNSCOPED_ENUM_MEMBER_CONVERT(x, y)

namespace clause {
MAKE_EMPTY_CLASS(AcqRel, AcqRel);
MAKE_EMPTY_CLASS(Acquire, Acquire);
MAKE_EMPTY_CLASS(Capture, Capture);
MAKE_EMPTY_CLASS(Compare, Compare);
MAKE_EMPTY_CLASS(DynamicAllocators, DynamicAllocators);
MAKE_EMPTY_CLASS(Full, Full);
MAKE_EMPTY_CLASS(Inbranch, Inbranch);
MAKE_EMPTY_CLASS(Mergeable, Mergeable);
MAKE_EMPTY_CLASS(Nogroup, Nogroup);
// MAKE_EMPTY_CLASS(NoOpenmp, );         // missing-in-parser
// MAKE_EMPTY_CLASS(NoOpenmpRoutines, ); // missing-in-parser
// MAKE_EMPTY_CLASS(NoParallelism, );    // missing-in-parser
MAKE_EMPTY_CLASS(Notinbranch, Notinbranch);
MAKE_EMPTY_CLASS(Nowait, Nowait);
MAKE_EMPTY_CLASS(OmpxAttribute, OmpxAttribute);
MAKE_EMPTY_CLASS(OmpxBare, OmpxBare);
MAKE_EMPTY_CLASS(Read, Read);
MAKE_EMPTY_CLASS(Relaxed, Relaxed);
MAKE_EMPTY_CLASS(Release, Release);
MAKE_EMPTY_CLASS(ReverseOffload, ReverseOffload);
MAKE_EMPTY_CLASS(SeqCst, SeqCst);
MAKE_EMPTY_CLASS(Simd, Simd);
MAKE_EMPTY_CLASS(Threads, Threads);
MAKE_EMPTY_CLASS(UnifiedAddress, UnifiedAddress);
MAKE_EMPTY_CLASS(UnifiedSharedMemory, UnifiedSharedMemory);
MAKE_EMPTY_CLASS(Unknown, Unknown);
MAKE_EMPTY_CLASS(Untied, Untied);
MAKE_EMPTY_CLASS(Weak, Weak);
MAKE_EMPTY_CLASS(Write, Write);

// Artificial clauses
MAKE_EMPTY_CLASS(CancellationConstructType, CancellationConstructType);
MAKE_EMPTY_CLASS(Depobj, Depobj);
MAKE_EMPTY_CLASS(Flush, Flush);
MAKE_EMPTY_CLASS(MemoryOrder, MemoryOrder);
MAKE_EMPTY_CLASS(Threadprivate, Threadprivate);

MAKE_INCOMPLETE_CLASS(AdjustArgs, AdjustArgs);
MAKE_INCOMPLETE_CLASS(AppendArgs, AppendArgs);
MAKE_INCOMPLETE_CLASS(Match, Match);
// MAKE_INCOMPLETE_CLASS(Otherwise, );   // missing-in-parser
MAKE_INCOMPLETE_CLASS(When, When);

DefinedOperator makeDefinedOperator(const parser::DefinedOperator &inp,
                                    semantics::SemanticsContext &semaCtx) {
  CLAUSET_ENUM_CONVERT( //
      convert, parser::DefinedOperator::IntrinsicOperator,
      DefinedOperator::IntrinsicOperator,
      // clang-format off
      MS(Add,      Add)
      MS(AND,      AND)
      MS(Concat,   Concat)
      MS(Divide,   Divide)
      MS(EQ,       EQ)
      MS(EQV,      EQV)
      MS(GE,       GE)
      MS(GT,       GT)
      MS(NOT,      NOT)
      MS(LE,       LE)
      MS(LT,       LT)
      MS(Multiply, Multiply)
      MS(NE,       NE)
      MS(NEQV,     NEQV)
      MS(OR,       OR)
      MS(Power,    Power)
      MS(Subtract, Subtract)
      // clang-format on
  );

  return std::visit(
      common::visitors{
          [&](const parser::DefinedOpName &s) {
            return DefinedOperator{
                DefinedOperator::DefinedOpName{makeObject(s.v, semaCtx)}};
          },
          [&](const parser::DefinedOperator::IntrinsicOperator &s) {
            return DefinedOperator{convert(s)};
          },
      },
      inp.u);
}

ProcedureDesignator
makeProcedureDesignator(const parser::ProcedureDesignator &inp,
                        semantics::SemanticsContext &semaCtx) {
  return ProcedureDesignator{std::visit(
      common::visitors{
          [&](const parser::Name &t) { return makeObject(t, semaCtx); },
          [&](const parser::ProcComponentRef &t) {
            return makeObject(t.v.thing, semaCtx);
          },
      },
      inp.u)};
}

ReductionOperator makeReductionOperator(const parser::OmpReductionOperator &inp,
                                        semantics::SemanticsContext &semaCtx) {
  return std::visit(
      common::visitors{
          [&](const parser::DefinedOperator &s) {
            return ReductionOperator{makeDefinedOperator(s, semaCtx)};
          },
          [&](const parser::ProcedureDesignator &s) {
            return ReductionOperator{makeProcedureDesignator(s, semaCtx)};
          },
      },
      inp.u);
}

// --------------------------------------------------------------------
// Actual clauses. Each T (where tomp::T exists in ClauseT) has its "make".

// Absent: missing-in-parser
// AcqRel: empty
// Acquire: empty
// AdjustArgs: incomplete

Affinity make(const parser::OmpClause::Affinity &inp,
              semantics::SemanticsContext &semaCtx) {
  // inp -> empty
  llvm_unreachable("Empty: affinity");
}

Align make(const parser::OmpClause::Align &inp,
           semantics::SemanticsContext &semaCtx) {
  // inp -> empty
  llvm_unreachable("Empty: align");
}

Aligned make(const parser::OmpClause::Aligned &inp,
             semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpAlignedClause
  auto &t0 = std::get<parser::OmpObjectList>(inp.v.t);
  auto &t1 = std::get<std::optional<parser::ScalarIntConstantExpr>>(inp.v.t);

  return Aligned{{
      /*Alignment=*/maybeApply(makeExprFn(semaCtx), t1),
      /*List=*/makeObjects(t0, semaCtx),
  }};
}

Allocate make(const parser::OmpClause::Allocate &inp,
              semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpAllocateClause
  using wrapped = parser::OmpAllocateClause;
  auto &t0 = std::get<std::optional<wrapped::AllocateModifier>>(inp.v.t);
  auto &t1 = std::get<parser::OmpObjectList>(inp.v.t);

  if (!t0) {
    return Allocate{{/*AllocatorSimpleModifier=*/std::nullopt,
                     /*AllocatorComplexModifier=*/std::nullopt,
                     /*AlignModifier=*/std::nullopt,
                     /*List=*/makeObjects(t1, semaCtx)}};
  }

  using Tuple = decltype(Allocate::t);

  return Allocate{std::visit(
      common::visitors{
          // simple-modifier
          [&](const wrapped::AllocateModifier::Allocator &v) -> Tuple {
            return {/*AllocatorSimpleModifier=*/makeExpr(v.v, semaCtx),
                    /*AllocatorComplexModifier=*/std::nullopt,
                    /*AlignModifier=*/std::nullopt,
                    /*List=*/makeObjects(t1, semaCtx)};
          },
          // complex-modifier + align-modifier
          [&](const wrapped::AllocateModifier::ComplexModifier &v) -> Tuple {
            auto &s0 = std::get<wrapped::AllocateModifier::Allocator>(v.t);
            auto &s1 = std::get<wrapped::AllocateModifier::Align>(v.t);
            return {
                /*AllocatorSimpleModifier=*/std::nullopt,
                /*AllocatorComplexModifier=*/Allocator{makeExpr(s0.v, semaCtx)},
                /*AlignModifier=*/Align{makeExpr(s1.v, semaCtx)},
                /*List=*/makeObjects(t1, semaCtx)};
          },
          // align-modifier
          [&](const wrapped::AllocateModifier::Align &v) -> Tuple {
            return {/*AllocatorSimpleModifier=*/std::nullopt,
                    /*AllocatorComplexModifier=*/std::nullopt,
                    /*AlignModifier=*/Align{makeExpr(v.v, semaCtx)},
                    /*List=*/makeObjects(t1, semaCtx)};
          },
      },
      t0->u)};
}

Allocator make(const parser::OmpClause::Allocator &inp,
               semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::ScalarIntExpr
  return Allocator{/*Allocator=*/makeExpr(inp.v, semaCtx)};
}

// AppendArgs: incomplete

At make(const parser::OmpClause::At &inp,
        semantics::SemanticsContext &semaCtx) {
  // inp -> empty
  llvm_unreachable("Empty: at");
}

// Never called, but needed for using "make" as a Clause visitor.
// See comment about "requires" clauses in Clauses.h.
AtomicDefaultMemOrder make(const parser::OmpClause::AtomicDefaultMemOrder &inp,
                           semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpAtomicDefaultMemOrderClause
  CLAUSET_ENUM_CONVERT( //
      convert, common::OmpAtomicDefaultMemOrderType,
      AtomicDefaultMemOrder::MemoryOrder,
      // clang-format off
      MS(AcqRel,   AcqRel)
      MS(Relaxed,  Relaxed)
      MS(SeqCst,   SeqCst)
      // clang-format on
  );

  return AtomicDefaultMemOrder{/*MemoryOrder=*/convert(inp.v.v)};
}

Bind make(const parser::OmpClause::Bind &inp,
          semantics::SemanticsContext &semaCtx) {
  // inp -> empty
  llvm_unreachable("Empty: bind");
}

// CancellationConstructType: empty
// Capture: empty

Collapse make(const parser::OmpClause::Collapse &inp,
              semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::ScalarIntConstantExpr
  return Collapse{/*N=*/makeExpr(inp.v, semaCtx)};
}

// Compare: empty
// Contains: missing-in-parser

Copyin make(const parser::OmpClause::Copyin &inp,
            semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpObjectList
  return Copyin{/*List=*/makeObjects(inp.v, semaCtx)};
}

Copyprivate make(const parser::OmpClause::Copyprivate &inp,
                 semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpObjectList
  return Copyprivate{/*List=*/makeObjects(inp.v, semaCtx)};
}

Default make(const parser::OmpClause::Default &inp,
             semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpDefaultClause
  using wrapped = parser::OmpDefaultClause;

  CLAUSET_ENUM_CONVERT( //
      convert, wrapped::Type, Default::DataSharingAttribute,
      // clang-format off
      MS(Firstprivate, Firstprivate)
      MS(None,         None)
      MS(Private,      Private)
      MS(Shared,       Shared)
      // clang-format on
  );

  return Default{/*DataSharingAttribute=*/convert(inp.v.v)};
}

Defaultmap make(const parser::OmpClause::Defaultmap &inp,
                semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpDefaultmapClause
  using wrapped = parser::OmpDefaultmapClause;

  CLAUSET_ENUM_CONVERT( //
      convert1, wrapped::ImplicitBehavior, Defaultmap::ImplicitBehavior,
      // clang-format off
      MS(Alloc,        Alloc)
      MS(To,           To)
      MS(From,         From)
      MS(Tofrom,       Tofrom)
      MS(Firstprivate, Firstprivate)
      MS(None,         None)
      MS(Default,      Default)
      // MS(, Present)  missing-in-parser
      // clang-format on
  );

  CLAUSET_ENUM_CONVERT( //
      convert2, wrapped::VariableCategory, Defaultmap::VariableCategory,
      // clang-format off
      MS(Scalar,       Scalar)
      MS(Aggregate,    Aggregate)
      MS(Pointer,      Pointer)
      MS(Allocatable,  Allocatable)
      // clang-format on
  );

  auto &t0 = std::get<wrapped::ImplicitBehavior>(inp.v.t);
  auto &t1 = std::get<std::optional<wrapped::VariableCategory>>(inp.v.t);
  return Defaultmap{{/*ImplicitBehavior=*/convert1(t0),
                     /*VariableCategory=*/maybeApply(convert2, t1)}};
}

Depend make(const parser::OmpClause::Depend &inp,
            semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpDependClause
  using wrapped = parser::OmpDependClause;
  using Variant = decltype(Depend::u);
  // Iteration is the equivalent of parser::OmpDependSinkVec
  using Iteration = Doacross::Vector::value_type; // LoopIterationT

  CLAUSET_ENUM_CONVERT( //
      convert1, parser::OmpDependenceType::Type, Depend::TaskDependenceType,
      // clang-format off
      MS(In,     In)
      MS(Out,    Out)
      MS(Inout,  Inout)
      // MS(, Mutexinoutset)   // missing-in-parser
      // MS(, Inputset)        // missing-in-parser
      // MS(, Depobj)          // missing-in-parser
      // clang-format on
  );

  return Depend{std::visit( //
      common::visitors{
          // Doacross
          [&](const wrapped::Source &s) -> Variant {
            return Doacross{
                {/*DependenceType=*/Doacross::DependenceType::Source,
                 /*Vector=*/{}}};
          },
          // Doacross
          [&](const wrapped::Sink &s) -> Variant {
            using DependLength = parser::OmpDependSinkVecLength;
            auto convert2 = [&](const parser::OmpDependSinkVec &v) {
              auto &t0 = std::get<parser::Name>(v.t);
              auto &t1 = std::get<std::optional<DependLength>>(v.t);

              auto convert3 = [&](const DependLength &u) {
                auto &s0 = std::get<parser::DefinedOperator>(u.t);
                auto &s1 = std::get<parser::ScalarIntConstantExpr>(u.t);
                return Iteration::Distance{
                    {makeDefinedOperator(s0, semaCtx), makeExpr(s1, semaCtx)}};
              };
              return Iteration{
                  {makeObject(t0, semaCtx), maybeApply(convert3, t1)}};
            };
            return Doacross{{/*DependenceType=*/Doacross::DependenceType::Sink,
                             /*Vector=*/makeList(s.v, convert2)}};
          },
          // Depend::WithLocators
          [&](const wrapped::InOut &s) -> Variant {
            auto &t0 = std::get<parser::OmpDependenceType>(s.t);
            auto &t1 = std::get<std::list<parser::Designator>>(s.t);
            auto convert4 = [&](const parser::Designator &t) {
              return makeObject(t, semaCtx);
            };
            return Depend::WithLocators{
                {/*TaskDependenceType=*/convert1(t0.v),
                 /*Iterator=*/std::nullopt,
                 /*LocatorList=*/makeList(t1, convert4)}};
          },
      },
      inp.v.u)};
}

// Depobj: empty

Destroy make(const parser::OmpClause::Destroy &inp,
             semantics::SemanticsContext &semaCtx) {
  // inp -> empty
  llvm_unreachable("Empty: destroy");
}

Detach make(const parser::OmpClause::Detach &inp,
            semantics::SemanticsContext &semaCtx) {
  // inp -> empty
  llvm_unreachable("Empty: detach");
}

Device make(const parser::OmpClause::Device &inp,
            semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpDeviceClause
  using wrapped = parser::OmpDeviceClause;

  CLAUSET_ENUM_CONVERT( //
      convert, parser::OmpDeviceClause::DeviceModifier, Device::DeviceModifier,
      // clang-format off
      MS(Ancestor,   Ancestor)
      MS(Device_Num, DeviceNum)
      // clang-format on
  );
  auto &t0 = std::get<std::optional<wrapped::DeviceModifier>>(inp.v.t);
  auto &t1 = std::get<parser::ScalarIntExpr>(inp.v.t);
  return Device{{/*DeviceModifier=*/maybeApply(convert, t0),
                 /*DeviceDescription=*/makeExpr(t1, semaCtx)}};
}

DeviceType make(const parser::OmpClause::DeviceType &inp,
                semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpDeviceTypeClause
  using wrapped = parser::OmpDeviceTypeClause;

  CLAUSET_ENUM_CONVERT( //
      convert, wrapped::Type, DeviceType::DeviceTypeDescription,
      // clang-format off
      MS(Any,    Any)
      MS(Host,   Host)
      MS(Nohost, Nohost)
      // clang-format om
  );
  return DeviceType{/*DeviceTypeDescription=*/convert(inp.v.v)};
}

DistSchedule make(const parser::OmpClause::DistSchedule &inp,
                  semantics::SemanticsContext &semaCtx) {
  // inp.v -> std::optional<parser::ScalarIntExpr>
  return DistSchedule{{/*Kind=*/DistSchedule::Kind::Static,
                       /*ChunkSize=*/maybeApply(makeExprFn(semaCtx), inp.v)}};
}

Doacross make(const parser::OmpClause::Doacross &inp,
              semantics::SemanticsContext &semaCtx) {
  // inp -> empty
  llvm_unreachable("Empty: doacross");
}

// DynamicAllocators: empty

Enter make(const parser::OmpClause::Enter &inp,
           semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpObjectList
  return Enter{makeObjects(/*List=*/inp.v, semaCtx)};
}

Exclusive make(const parser::OmpClause::Exclusive &inp,
               semantics::SemanticsContext &semaCtx) {
  // inp -> empty
  llvm_unreachable("Empty: exclusive");
}

Fail make(const parser::OmpClause::Fail &inp,
          semantics::SemanticsContext &semaCtx) {
  // inp -> empty
  llvm_unreachable("Empty: fail");
}

Filter make(const parser::OmpClause::Filter &inp,
            semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::ScalarIntExpr
  return Filter{/*ThreadNum=*/makeExpr(inp.v, semaCtx)};
}

Final make(const parser::OmpClause::Final &inp,
           semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::ScalarLogicalExpr
  return Final{/*Finalize=*/makeExpr(inp.v, semaCtx)};
}

Firstprivate make(const parser::OmpClause::Firstprivate &inp,
                  semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpObjectList
  return Firstprivate{/*List=*/makeObjects(inp.v, semaCtx)};
}

// Flush: empty

From make(const parser::OmpClause::From &inp,
          semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpObjectList
  return From{{/*Expectation=*/std::nullopt, /*Mapper=*/std::nullopt,
               /*Iterator=*/std::nullopt,
               /*LocatorList=*/makeObjects(inp.v, semaCtx)}};
}

// Full: empty

Grainsize make(const parser::OmpClause::Grainsize &inp,
               semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::ScalarIntExpr
  return Grainsize{{/*Prescriptiveness=*/std::nullopt,
                    /*GrainSize=*/makeExpr(inp.v, semaCtx)}};
}

HasDeviceAddr make(const parser::OmpClause::HasDeviceAddr &inp,
                   semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpObjectList
  return HasDeviceAddr{/*List=*/makeObjects(inp.v, semaCtx)};
}

Hint make(const parser::OmpClause::Hint &inp,
          semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::ConstantExpr
  return Hint{/*HintExpr=*/makeExpr(inp.v, semaCtx)};
}

// Holds: missing-in-parser

If make(const parser::OmpClause::If &inp,
        semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpIfClause
  using wrapped = parser::OmpIfClause;

  CLAUSET_ENUM_CONVERT( //
      convert, wrapped::DirectiveNameModifier, llvm::omp::Directive,
      // clang-format off
      MS(Parallel,         OMPD_parallel)
      MS(Simd,             OMPD_simd)
      MS(Target,           OMPD_target)
      MS(TargetData,       OMPD_target_data)
      MS(TargetEnterData,  OMPD_target_enter_data)
      MS(TargetExitData,   OMPD_target_exit_data)
      MS(TargetUpdate,     OMPD_target_update)
      MS(Task,             OMPD_task)
      MS(Taskloop,         OMPD_taskloop)
      MS(Teams,            OMPD_teams)
      // clang-format on
  );
  auto &t0 = std::get<std::optional<wrapped::DirectiveNameModifier>>(inp.v.t);
  auto &t1 = std::get<parser::ScalarLogicalExpr>(inp.v.t);
  return If{{/*DirectiveNameModifier=*/maybeApply(convert, t0),
             /*IfExpression=*/makeExpr(t1, semaCtx)}};
}

// Inbranch: empty

Inclusive make(const parser::OmpClause::Inclusive &inp,
               semantics::SemanticsContext &semaCtx) {
  // inp -> empty
  llvm_unreachable("Empty: inclusive");
}

Indirect make(const parser::OmpClause::Indirect &inp,
              semantics::SemanticsContext &semaCtx) {
  // inp -> empty
  llvm_unreachable("Empty: indirect");
}

Init make(const parser::OmpClause::Init &inp,
          semantics::SemanticsContext &semaCtx) {
  // inp -> empty
  llvm_unreachable("Empty: init");
}

// Initializer: missing-in-parser

InReduction make(const parser::OmpClause::InReduction &inp,
                 semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpInReductionClause
  auto &t0 = std::get<parser::OmpReductionOperator>(inp.v.t);
  auto &t1 = std::get<parser::OmpObjectList>(inp.v.t);
  return InReduction{
      {/*ReductionIdentifiers=*/{makeReductionOperator(t0, semaCtx)},
       /*List=*/makeObjects(t1, semaCtx)}};
}

IsDevicePtr make(const parser::OmpClause::IsDevicePtr &inp,
                 semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpObjectList
  return IsDevicePtr{/*List=*/makeObjects(inp.v, semaCtx)};
}

Lastprivate make(const parser::OmpClause::Lastprivate &inp,
                 semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpObjectList
  return Lastprivate{{/*LastprivateModifier=*/std::nullopt,
                      /*List=*/makeObjects(inp.v, semaCtx)}};
}

Linear make(const parser::OmpClause::Linear &inp,
            semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpLinearClause
  using wrapped = parser::OmpLinearClause;

  CLAUSET_ENUM_CONVERT( //
      convert, parser::OmpLinearModifier::Type, Linear::LinearModifier,
      // clang-format off
      MS(Ref,  Ref)
      MS(Val,  Val)
      MS(Uval, Uval)
      // clang-format on
  );

  using Tuple = decltype(Linear::t);

  return Linear{std::visit(
      common::visitors{
          [&](const wrapped::WithModifier &s) -> Tuple {
            return {
                /*StepSimpleModifier=*/std::nullopt,
                /*StepComplexModifier=*/maybeApply(makeExprFn(semaCtx), s.step),
                /*LinearModifier=*/convert(s.modifier.v),
                /*List=*/makeList(s.names, makeObjectFn(semaCtx))};
          },
          [&](const wrapped::WithoutModifier &s) -> Tuple {
            return {
                /*StepSimpleModifier=*/maybeApply(makeExprFn(semaCtx), s.step),
                /*StepComplexModifier=*/std::nullopt,
                /*LinearModifier=*/std::nullopt,
                /*List=*/makeList(s.names, makeObjectFn(semaCtx))};
          },
      },
      inp.v.u)};
}

Link make(const parser::OmpClause::Link &inp,
          semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpObjectList
  return Link{/*List=*/makeObjects(inp.v, semaCtx)};
}

Map make(const parser::OmpClause::Map &inp,
         semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpMapClause

  CLAUSET_ENUM_CONVERT( //
      convert1, parser::OmpMapType::Type, Map::MapType,
      // clang-format off
      MS(To,       To)
      MS(From,     From)
      MS(Tofrom,   Tofrom)
      MS(Alloc,    Alloc)
      MS(Release,  Release)
      MS(Delete,   Delete)
      // clang-format on
  );

  // No convert2: MapTypeModifier is not an enum in parser.

  auto &t0 = std::get<std::optional<parser::OmpMapType>>(inp.v.t);
  auto &t1 = std::get<parser::OmpObjectList>(inp.v.t);

  if (!t0) {
    return Map{{/*MapType=*/std::nullopt, /*MapTypeModifiers=*/std::nullopt,
                /*Mapper=*/std::nullopt, /*Iterator=*/std::nullopt,
                /*LocatorList=*/makeObjects(t1, semaCtx)}};
  }

  auto &s0 = std::get<std::optional<parser::OmpMapType::Always>>(t0->t);
  auto &s1 = std::get<parser::OmpMapType::Type>(t0->t);

  std::optional<Map::MapTypeModifiers> maybeList;
  if (s0)
    maybeList = Map::MapTypeModifiers{Map::MapTypeModifier::Always};

  return Map{{/*MapType=*/convert1(s1),
              /*MapTypeModifiers=*/maybeList,
              /*Mapper=*/std::nullopt, /*Iterator=*/std::nullopt,
              /*LocatorList=*/makeObjects(t1, semaCtx)}};
}

// Match: incomplete
// MemoryOrder: empty
// Mergeable: empty

Message make(const parser::OmpClause::Message &inp,
             semantics::SemanticsContext &semaCtx) {
  // inp -> empty
  llvm_unreachable("Empty: message");
}

Nocontext make(const parser::OmpClause::Nocontext &inp,
               semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::ScalarLogicalExpr
  return Nocontext{/*DoNotUpdateContext=*/makeExpr(inp.v, semaCtx)};
}

// Nogroup: empty

Nontemporal make(const parser::OmpClause::Nontemporal &inp,
                 semantics::SemanticsContext &semaCtx) {
  // inp.v -> std::list<parser::Name>
  return Nontemporal{/*List=*/makeList(inp.v, makeObjectFn(semaCtx))};
}

// NoOpenmp: missing-in-parser
// NoOpenmpRoutines: missing-in-parser
// NoParallelism: missing-in-parser
// Notinbranch: empty

Novariants make(const parser::OmpClause::Novariants &inp,
                semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::ScalarLogicalExpr
  return Novariants{/*DoNotUseVariant=*/makeExpr(inp.v, semaCtx)};
}

// Nowait: empty

NumTasks make(const parser::OmpClause::NumTasks &inp,
              semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::ScalarIntExpr
  return NumTasks{{/*Prescriptiveness=*/std::nullopt,
                   /*NumTasks=*/makeExpr(inp.v, semaCtx)}};
}

NumTeams make(const parser::OmpClause::NumTeams &inp,
              semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::ScalarIntExpr
  return NumTeams{{/*LowerBound=*/std::nullopt,
                   /*UpperBound=*/makeExpr(inp.v, semaCtx)}};
}

NumThreads make(const parser::OmpClause::NumThreads &inp,
                semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::ScalarIntExpr
  return NumThreads{/*Nthreads=*/makeExpr(inp.v, semaCtx)};
}

// OmpxAttribute: empty
// OmpxBare: empty

OmpxDynCgroupMem make(const parser::OmpClause::OmpxDynCgroupMem &inp,
                      semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::ScalarIntExpr
  return OmpxDynCgroupMem{makeExpr(inp.v, semaCtx)};
}

Order make(const parser::OmpClause::Order &inp,
           semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpOrderClause
  using wrapped = parser::OmpOrderClause;

  CLAUSET_ENUM_CONVERT( //
      convert1, parser::OmpOrderModifier::Kind, Order::OrderModifier,
      // clang-format off
      MS(Reproducible,   Reproducible)
      MS(Unconstrained,  Unconstrained)
      // clang-format on
  );

  CLAUSET_ENUM_CONVERT( //
      convert2, wrapped::Type, Order::Ordering,
      // clang-format off
      MS(Concurrent, Concurrent)
      // clang-format on
  );

  auto &t0 = std::get<std::optional<parser::OmpOrderModifier>>(inp.v.t);
  auto &t1 = std::get<wrapped::Type>(inp.v.t);

  auto convert3 = [&](const parser::OmpOrderModifier &s) {
    return std::visit(
        [&](parser::OmpOrderModifier::Kind k) { return convert1(k); }, s.u);
  };
  return Order{
      {/*OrderModifier=*/maybeApply(convert3, t0), /*Ordering=*/convert2(t1)}};
}

Ordered make(const parser::OmpClause::Ordered &inp,
             semantics::SemanticsContext &semaCtx) {
  // inp.v -> std::optional<parser::ScalarIntConstantExpr>
  return Ordered{/*N=*/maybeApply(makeExprFn(semaCtx), inp.v)};
}

// Otherwise: incomplete, missing-in-parser

Partial make(const parser::OmpClause::Partial &inp,
             semantics::SemanticsContext &semaCtx) {
  // inp.v -> std::optional<parser::ScalarIntConstantExpr>
  return Partial{/*UnrollFactor=*/maybeApply(makeExprFn(semaCtx), inp.v)};
}

Priority make(const parser::OmpClause::Priority &inp,
              semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::ScalarIntExpr
  return Priority{/*PriorityValue=*/makeExpr(inp.v, semaCtx)};
}

Private make(const parser::OmpClause::Private &inp,
             semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpObjectList
  return Private{/*List=*/makeObjects(inp.v, semaCtx)};
}

ProcBind make(const parser::OmpClause::ProcBind &inp,
              semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpProcBindClause
  using wrapped = parser::OmpProcBindClause;

  CLAUSET_ENUM_CONVERT( //
      convert, wrapped::Type, ProcBind::AffinityPolicy,
      // clang-format off
      MS(Close,    Close)
      MS(Master,   Master)
      MS(Spread,   Spread)
      MS(Primary,  Primary)
      // clang-format on
  );
  return ProcBind{/*AffinityPolicy=*/convert(inp.v.v)};
}

// Read: empty

Reduction make(const parser::OmpClause::Reduction &inp,
               semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpReductionClause
  using wrapped = parser::OmpReductionClause;

  CLAUSET_ENUM_CONVERT( //
      convert, wrapped::ReductionModifier, Reduction::ReductionModifier,
      // clang-format off
      MS(Inscan,  Inscan)
      MS(Task,    Task)
      MS(Default, Default)
      // clang-format on
  );

  auto &t0 =
      std::get<std::optional<parser::OmpReductionClause::ReductionModifier>>(
          inp.v.t);
  auto &t1 = std::get<parser::OmpReductionOperator>(inp.v.t);
  auto &t2 = std::get<parser::OmpObjectList>(inp.v.t);
  return Reduction{
      {/*ReductionModifier=*/t0
           ? std::make_optional<Reduction::ReductionModifier>(convert(*t0))
           : std::nullopt,
       /*ReductionIdentifiers=*/{makeReductionOperator(t1, semaCtx)},
       /*List=*/makeObjects(t2, semaCtx)}};
}

// Relaxed: empty
// Release: empty
// ReverseOffload: empty

Safelen make(const parser::OmpClause::Safelen &inp,
             semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::ScalarIntConstantExpr
  return Safelen{/*Length=*/makeExpr(inp.v, semaCtx)};
}

Schedule make(const parser::OmpClause::Schedule &inp,
              semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpScheduleClause
  using wrapped = parser::OmpScheduleClause;

  CLAUSET_ENUM_CONVERT( //
      convert1, wrapped::ScheduleType, Schedule::Kind,
      // clang-format off
      MS(Static,   Static)
      MS(Dynamic,  Dynamic)
      MS(Guided,   Guided)
      MS(Auto,     Auto)
      MS(Runtime,  Runtime)
      // clang-format on
  );

  CLAUSET_ENUM_CONVERT( //
      convert2, parser::OmpScheduleModifierType::ModType,
      Schedule::OrderingModifier,
      // clang-format off
      MS(Monotonic,    Monotonic)
      MS(Nonmonotonic, Nonmonotonic)
      // clang-format on
  );

  CLAUSET_ENUM_CONVERT( //
      convert3, parser::OmpScheduleModifierType::ModType,
      Schedule::ChunkModifier,
      // clang-format off
      MS(Simd, Simd)
      // clang-format on
  );

  auto &t0 = std::get<std::optional<parser::OmpScheduleModifier>>(inp.v.t);
  auto &t1 = std::get<wrapped::ScheduleType>(inp.v.t);
  auto &t2 = std::get<std::optional<parser::ScalarIntExpr>>(inp.v.t);

  if (!t0) {
    return Schedule{{/*Kind=*/convert1(t1), /*OrderingModifier=*/std::nullopt,
                     /*ChunkModifier=*/std::nullopt,
                     /*ChunkSize=*/maybeApply(makeExprFn(semaCtx), t2)}};
  }

  // The members of parser::OmpScheduleModifier correspond to OrderingModifier,
  // and ChunkModifier, but they can appear in any order.
  auto &m1 = std::get<parser::OmpScheduleModifier::Modifier1>(t0->t);
  auto &m2 =
      std::get<std::optional<parser::OmpScheduleModifier::Modifier2>>(t0->t);

  std::optional<Schedule::OrderingModifier> omod;
  std::optional<Schedule::ChunkModifier> cmod;

  if (m1.v.v == parser::OmpScheduleModifierType::ModType::Simd) {
    // m1 is chunk-modifier
    cmod = convert3(m1.v.v);
    if (m2)
      omod = convert2(m2->v.v);
  } else {
    // m1 is ordering-modifier
    omod = convert2(m1.v.v);
    if (m2)
      cmod = convert3(m2->v.v);
  }

  return Schedule{{/*Kind=*/convert1(t1),
                   /*OrderingModifier=*/omod,
                   /*ChunkModifier=*/cmod,
                   /*ChunkSize=*/maybeApply(makeExprFn(semaCtx), t2)}};
}

// SeqCst: empty

Severity make(const parser::OmpClause::Severity &inp,
              semantics::SemanticsContext &semaCtx) {
  // inp -> empty
  llvm_unreachable("Empty: severity");
}

Shared make(const parser::OmpClause::Shared &inp,
            semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpObjectList
  return Shared{/*List=*/makeObjects(inp.v, semaCtx)};
}

// Simd: empty

Simdlen make(const parser::OmpClause::Simdlen &inp,
             semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::ScalarIntConstantExpr
  return Simdlen{/*Length=*/makeExpr(inp.v, semaCtx)};
}

Sizes make(const parser::OmpClause::Sizes &inp,
           semantics::SemanticsContext &semaCtx) {
  // inp.v -> std::list<parser::ScalarIntExpr>
  return Sizes{/*SizeList=*/makeList(inp.v, makeExprFn(semaCtx))};
}

TaskReduction make(const parser::OmpClause::TaskReduction &inp,
                   semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpReductionClause
  auto &t0 = std::get<parser::OmpReductionOperator>(inp.v.t);
  auto &t1 = std::get<parser::OmpObjectList>(inp.v.t);
  return TaskReduction{
      {/*ReductionIdentifiers=*/{makeReductionOperator(t0, semaCtx)},
       /*List=*/makeObjects(t1, semaCtx)}};
}

ThreadLimit make(const parser::OmpClause::ThreadLimit &inp,
                 semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::ScalarIntExpr
  return ThreadLimit{/*Threadlim=*/makeExpr(inp.v, semaCtx)};
}

// Threadprivate: empty
// Threads: empty

To make(const parser::OmpClause::To &inp,
        semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpObjectList
  return To{{/*Expectation=*/std::nullopt, /*Mapper=*/std::nullopt,
             /*Iterator=*/std::nullopt,
             /*LocatorList=*/makeObjects(inp.v, semaCtx)}};
}

// UnifiedAddress: empty
// UnifiedSharedMemory: empty

Uniform make(const parser::OmpClause::Uniform &inp,
             semantics::SemanticsContext &semaCtx) {
  // inp.v -> std::list<parser::Name>
  return Uniform{/*ParameterList=*/makeList(inp.v, makeObjectFn(semaCtx))};
}

// Unknown: empty
// Untied: empty

Update make(const parser::OmpClause::Update &inp,
            semantics::SemanticsContext &semaCtx) {
  // inp -> empty
  return Update{/*TaskDependenceType=*/std::nullopt};
}

Use make(const parser::OmpClause::Use &inp,
         semantics::SemanticsContext &semaCtx) {
  // inp -> empty
  llvm_unreachable("Empty: use");
}

UseDeviceAddr make(const parser::OmpClause::UseDeviceAddr &inp,
                   semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpObjectList
  return UseDeviceAddr{/*List=*/makeObjects(inp.v, semaCtx)};
}

UseDevicePtr make(const parser::OmpClause::UseDevicePtr &inp,
                  semantics::SemanticsContext &semaCtx) {
  // inp.v -> parser::OmpObjectList
  return UseDevicePtr{/*List=*/makeObjects(inp.v, semaCtx)};
}

UsesAllocators make(const parser::OmpClause::UsesAllocators &inp,
                    semantics::SemanticsContext &semaCtx) {
  // inp -> empty
  llvm_unreachable("Empty: uses_allocators");
}

// Weak: empty
// When: incomplete
// Write: empty
} // namespace clause

Clause makeClause(const Fortran::parser::OmpClause &cls,
                  semantics::SemanticsContext &semaCtx) {
  return std::visit(
      [&](auto &&s) {
        return makeClause(getClauseId(cls), clause::make(s, semaCtx),
                          cls.source);
      },
      cls.u);
}

List<Clause> makeClauses(const parser::OmpClauseList &clauses,
                         semantics::SemanticsContext &semaCtx) {
  return makeList(clauses.v, [&](const parser::OmpClause &s) {
    return makeClause(s, semaCtx);
  });
}
} // namespace Fortran::lower::omp
