//===-- lib/Evaluate/tools.cpp --------------------------------------------===//
//
// 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 "flang/Evaluate/tools.h"
#include "flang/Common/idioms.h"
#include "flang/Evaluate/characteristics.h"
#include "flang/Evaluate/traverse.h"
#include "flang/Parser/message.h"
#include "flang/Semantics/tools.h"
#include <algorithm>
#include <variant>

using namespace Fortran::parser::literals;

namespace Fortran::evaluate {

// Can x*(a,b) be represented as (x*a,x*b)?  This code duplication
// of the subexpression "x" cannot (yet?) be reliably undone by
// common subexpression elimination in lowering, so it's disabled
// here for now to avoid the risk of potential duplication of
// expensive subexpressions (e.g., large array expressions, references
// to expensive functions) in generate code.
static constexpr bool allowOperandDuplication{false};

std::optional<Expr<SomeType>> AsGenericExpr(DataRef &&ref) {
  const Symbol &symbol{ref.GetLastSymbol()};
  if (auto dyType{DynamicType::From(symbol)}) {
    return TypedWrapper<Designator, DataRef>(*dyType, std::move(ref));
  }
  return std::nullopt;
}

std::optional<Expr<SomeType>> AsGenericExpr(const Symbol &symbol) {
  return AsGenericExpr(DataRef{symbol});
}

Expr<SomeType> Parenthesize(Expr<SomeType> &&expr) {
  return common::visit(
      [&](auto &&x) {
        using T = std::decay_t<decltype(x)>;
        if constexpr (common::HasMember<T, TypelessExpression>) {
          return expr; // no parentheses around typeless
        } else if constexpr (std::is_same_v<T, Expr<SomeDerived>>) {
          return AsGenericExpr(Parentheses<SomeDerived>{std::move(x)});
        } else {
          return common::visit(
              [](auto &&y) {
                using T = ResultType<decltype(y)>;
                return AsGenericExpr(Parentheses<T>{std::move(y)});
              },
              std::move(x.u));
        }
      },
      std::move(expr.u));
}

std::optional<DataRef> ExtractDataRef(
    const ActualArgument &arg, bool intoSubstring, bool intoComplexPart) {
  return ExtractDataRef(arg.UnwrapExpr(), intoSubstring, intoComplexPart);
}

std::optional<DataRef> ExtractSubstringBase(const Substring &substring) {
  return common::visit(
      common::visitors{
          [&](const DataRef &x) -> std::optional<DataRef> { return x; },
          [&](const StaticDataObject::Pointer &) -> std::optional<DataRef> {
            return std::nullopt;
          },
      },
      substring.parent());
}

// IsVariable()

auto IsVariableHelper::operator()(const Symbol &symbol) const -> Result {
  // ASSOCIATE(x => expr) -- x counts as a variable, but undefinable
  const Symbol &ultimate{symbol.GetUltimate()};
  return !IsNamedConstant(ultimate) &&
      (ultimate.has<semantics::ObjectEntityDetails>() ||
          ultimate.has<semantics::AssocEntityDetails>());
}
auto IsVariableHelper::operator()(const Component &x) const -> Result {
  const Symbol &comp{x.GetLastSymbol()};
  return (*this)(comp) && (IsPointer(comp) || (*this)(x.base()));
}
auto IsVariableHelper::operator()(const ArrayRef &x) const -> Result {
  return (*this)(x.base());
}
auto IsVariableHelper::operator()(const Substring &x) const -> Result {
  return (*this)(x.GetBaseObject());
}
auto IsVariableHelper::operator()(const ProcedureDesignator &x) const
    -> Result {
  if (const Symbol * symbol{x.GetSymbol()}) {
    const Symbol *result{FindFunctionResult(*symbol)};
    return result && IsPointer(*result) && !IsProcedurePointer(*result);
  }
  return false;
}

// Conversions of COMPLEX component expressions to REAL.
ConvertRealOperandsResult ConvertRealOperands(
    parser::ContextualMessages &messages, Expr<SomeType> &&x,
    Expr<SomeType> &&y, int defaultRealKind) {
  return common::visit(
      common::visitors{
          [&](Expr<SomeInteger> &&ix,
              Expr<SomeInteger> &&iy) -> ConvertRealOperandsResult {
            // Can happen in a CMPLX() constructor.  Per F'2018,
            // both integer operands are converted to default REAL.
            return {AsSameKindExprs<TypeCategory::Real>(
                ConvertToKind<TypeCategory::Real>(
                    defaultRealKind, std::move(ix)),
                ConvertToKind<TypeCategory::Real>(
                    defaultRealKind, std::move(iy)))};
          },
          [&](Expr<SomeInteger> &&ix,
              Expr<SomeReal> &&ry) -> ConvertRealOperandsResult {
            return {AsSameKindExprs<TypeCategory::Real>(
                ConvertTo(ry, std::move(ix)), std::move(ry))};
          },
          [&](Expr<SomeReal> &&rx,
              Expr<SomeInteger> &&iy) -> ConvertRealOperandsResult {
            return {AsSameKindExprs<TypeCategory::Real>(
                std::move(rx), ConvertTo(rx, std::move(iy)))};
          },
          [&](Expr<SomeReal> &&rx,
              Expr<SomeReal> &&ry) -> ConvertRealOperandsResult {
            return {AsSameKindExprs<TypeCategory::Real>(
                std::move(rx), std::move(ry))};
          },
          [&](Expr<SomeInteger> &&ix,
              BOZLiteralConstant &&by) -> ConvertRealOperandsResult {
            return {AsSameKindExprs<TypeCategory::Real>(
                ConvertToKind<TypeCategory::Real>(
                    defaultRealKind, std::move(ix)),
                ConvertToKind<TypeCategory::Real>(
                    defaultRealKind, std::move(by)))};
          },
          [&](BOZLiteralConstant &&bx,
              Expr<SomeInteger> &&iy) -> ConvertRealOperandsResult {
            return {AsSameKindExprs<TypeCategory::Real>(
                ConvertToKind<TypeCategory::Real>(
                    defaultRealKind, std::move(bx)),
                ConvertToKind<TypeCategory::Real>(
                    defaultRealKind, std::move(iy)))};
          },
          [&](Expr<SomeReal> &&rx,
              BOZLiteralConstant &&by) -> ConvertRealOperandsResult {
            return {AsSameKindExprs<TypeCategory::Real>(
                std::move(rx), ConvertTo(rx, std::move(by)))};
          },
          [&](BOZLiteralConstant &&bx,
              Expr<SomeReal> &&ry) -> ConvertRealOperandsResult {
            return {AsSameKindExprs<TypeCategory::Real>(
                ConvertTo(ry, std::move(bx)), std::move(ry))};
          },
          [&](auto &&, auto &&) -> ConvertRealOperandsResult { // C718
            messages.Say("operands must be INTEGER or REAL"_err_en_US);
            return std::nullopt;
          },
      },
      std::move(x.u), std::move(y.u));
}

// Helpers for NumericOperation and its subroutines below.
static std::optional<Expr<SomeType>> NoExpr() { return std::nullopt; }

template <TypeCategory CAT>
std::optional<Expr<SomeType>> Package(Expr<SomeKind<CAT>> &&catExpr) {
  return {AsGenericExpr(std::move(catExpr))};
}
template <TypeCategory CAT>
std::optional<Expr<SomeType>> Package(
    std::optional<Expr<SomeKind<CAT>>> &&catExpr) {
  if (catExpr) {
    return {AsGenericExpr(std::move(*catExpr))};
  } else {
    return std::nullopt;
  }
}

// Mixed REAL+INTEGER operations.  REAL**INTEGER is a special case that
// does not require conversion of the exponent expression.
template <template <typename> class OPR>
std::optional<Expr<SomeType>> MixedRealLeft(
    Expr<SomeReal> &&rx, Expr<SomeInteger> &&iy) {
  return Package(common::visit(
      [&](auto &&rxk) -> Expr<SomeReal> {
        using resultType = ResultType<decltype(rxk)>;
        if constexpr (std::is_same_v<OPR<resultType>, Power<resultType>>) {
          return AsCategoryExpr(
              RealToIntPower<resultType>{std::move(rxk), std::move(iy)});
        }
        // G++ 8.1.0 emits bogus warnings about missing return statements if
        // this statement is wrapped in an "else", as it should be.
        return AsCategoryExpr(OPR<resultType>{
            std::move(rxk), ConvertToType<resultType>(std::move(iy))});
      },
      std::move(rx.u)));
}

template <int KIND>
Expr<SomeComplex> MakeComplex(Expr<Type<TypeCategory::Real, KIND>> &&re,
    Expr<Type<TypeCategory::Real, KIND>> &&im) {
  return AsCategoryExpr(ComplexConstructor<KIND>{std::move(re), std::move(im)});
}

std::optional<Expr<SomeComplex>> ConstructComplex(
    parser::ContextualMessages &messages, Expr<SomeType> &&real,
    Expr<SomeType> &&imaginary, int defaultRealKind) {
  if (auto converted{ConvertRealOperands(
          messages, std::move(real), std::move(imaginary), defaultRealKind)}) {
    return {common::visit(
        [](auto &&pair) {
          return MakeComplex(std::move(pair[0]), std::move(pair[1]));
        },
        std::move(*converted))};
  }
  return std::nullopt;
}

std::optional<Expr<SomeComplex>> ConstructComplex(
    parser::ContextualMessages &messages, std::optional<Expr<SomeType>> &&real,
    std::optional<Expr<SomeType>> &&imaginary, int defaultRealKind) {
  if (auto parts{common::AllPresent(std::move(real), std::move(imaginary))}) {
    return ConstructComplex(messages, std::get<0>(std::move(*parts)),
        std::get<1>(std::move(*parts)), defaultRealKind);
  }
  return std::nullopt;
}

// Extracts the real or imaginary part of the result of a COMPLEX
// expression, when that expression is simple enough to be duplicated.
template <bool GET_IMAGINARY> struct ComplexPartExtractor {
  template <typename A> static std::optional<Expr<SomeReal>> Get(const A &) {
    return std::nullopt;
  }

  template <int KIND>
  static std::optional<Expr<SomeReal>> Get(
      const Parentheses<Type<TypeCategory::Complex, KIND>> &kz) {
    if (auto x{Get(kz.left())}) {
      return AsGenericExpr(AsSpecificExpr(
          Parentheses<Type<TypeCategory::Real, KIND>>{std::move(*x)}));
    } else {
      return std::nullopt;
    }
  }

  template <int KIND>
  static std::optional<Expr<SomeReal>> Get(
      const Negate<Type<TypeCategory::Complex, KIND>> &kz) {
    if (auto x{Get(kz.left())}) {
      return AsGenericExpr(AsSpecificExpr(
          Negate<Type<TypeCategory::Real, KIND>>{std::move(*x)}));
    } else {
      return std::nullopt;
    }
  }

  template <int KIND>
  static std::optional<Expr<SomeReal>> Get(
      const Convert<Type<TypeCategory::Complex, KIND>, TypeCategory::Complex>
          &kz) {
    if (auto x{Get(kz.left())}) {
      return AsGenericExpr(AsSpecificExpr(
          Convert<Type<TypeCategory::Real, KIND>, TypeCategory::Real>{
              AsGenericExpr(std::move(*x))}));
    } else {
      return std::nullopt;
    }
  }

  template <int KIND>
  static std::optional<Expr<SomeReal>> Get(const ComplexConstructor<KIND> &kz) {
    return GET_IMAGINARY ? Get(kz.right()) : Get(kz.left());
  }

  template <int KIND>
  static std::optional<Expr<SomeReal>> Get(
      const Constant<Type<TypeCategory::Complex, KIND>> &kz) {
    if (auto cz{kz.GetScalarValue()}) {
      return AsGenericExpr(
          AsSpecificExpr(GET_IMAGINARY ? cz->AIMAG() : cz->REAL()));
    } else {
      return std::nullopt;
    }
  }

  template <int KIND>
  static std::optional<Expr<SomeReal>> Get(
      const Designator<Type<TypeCategory::Complex, KIND>> &kz) {
    if (const auto *symbolRef{std::get_if<SymbolRef>(&kz.u)}) {
      return AsGenericExpr(AsSpecificExpr(
          Designator<Type<TypeCategory::Complex, KIND>>{ComplexPart{
              DataRef{*symbolRef},
              GET_IMAGINARY ? ComplexPart::Part::IM : ComplexPart::Part::RE}}));
    } else {
      return std::nullopt;
    }
  }

  template <int KIND>
  static std::optional<Expr<SomeReal>> Get(
      const Expr<Type<TypeCategory::Complex, KIND>> &kz) {
    return Get(kz.u);
  }

  static std::optional<Expr<SomeReal>> Get(const Expr<SomeComplex> &z) {
    return Get(z.u);
  }
};

// Convert REAL to COMPLEX of the same kind. Preserving the real operand kind
// and then applying complex operand promotion rules allows the result to have
// the highest precision of REAL and COMPLEX operands as required by Fortran
// 2018 10.9.1.3.
Expr<SomeComplex> PromoteRealToComplex(Expr<SomeReal> &&someX) {
  return common::visit(
      [](auto &&x) {
        using RT = ResultType<decltype(x)>;
        return AsCategoryExpr(ComplexConstructor<RT::kind>{
            std::move(x), AsExpr(Constant<RT>{Scalar<RT>{}})});
      },
      std::move(someX.u));
}

// Handle mixed COMPLEX+REAL (or INTEGER) operations in a better way
// than just converting the second operand to COMPLEX and performing the
// corresponding COMPLEX+COMPLEX operation.
template <template <typename> class OPR, TypeCategory RCAT>
std::optional<Expr<SomeType>> MixedComplexLeft(
    parser::ContextualMessages &messages, const Expr<SomeComplex> &zx,
    const Expr<SomeKind<RCAT>> &iry, [[maybe_unused]] int defaultRealKind) {
  if constexpr (RCAT == TypeCategory::Integer &&
      std::is_same_v<OPR<LargestReal>, Power<LargestReal>>) {
    // COMPLEX**INTEGER is a special case that doesn't convert the exponent.
    return Package(common::visit(
        [&](const auto &zxk) {
          using Ty = ResultType<decltype(zxk)>;
          return AsCategoryExpr(AsExpr(
              RealToIntPower<Ty>{common::Clone(zxk), common::Clone(iry)}));
        },
        zx.u));
  }
  std::optional<Expr<SomeReal>> zr{ComplexPartExtractor<false>{}.Get(zx)};
  std::optional<Expr<SomeReal>> zi{ComplexPartExtractor<true>{}.Get(zx)};
  if (!zr || !zi) {
  } else if constexpr (std::is_same_v<OPR<LargestReal>, Add<LargestReal>> ||
      std::is_same_v<OPR<LargestReal>, Subtract<LargestReal>>) {
    // (a,b) + x -> (a+x, b)
    // (a,b) - x -> (a-x, b)
    if (std::optional<Expr<SomeType>> rr{
            NumericOperation<OPR>(messages, AsGenericExpr(std::move(*zr)),
                AsGenericExpr(common::Clone(iry)), defaultRealKind)}) {
      return Package(ConstructComplex(messages, std::move(*rr),
          AsGenericExpr(std::move(*zi)), defaultRealKind));
    }
  } else if constexpr (allowOperandDuplication &&
      (std::is_same_v<OPR<LargestReal>, Multiply<LargestReal>> ||
          std::is_same_v<OPR<LargestReal>, Divide<LargestReal>>)) {
    // (a,b) * x -> (a*x, b*x)
    // (a,b) / x -> (a/x, b/x)
    auto copy{iry};
    auto rr{NumericOperation<OPR>(messages, AsGenericExpr(std::move(*zr)),
        AsGenericExpr(common::Clone(iry)), defaultRealKind)};
    auto ri{NumericOperation<OPR>(messages, AsGenericExpr(std::move(*zi)),
        AsGenericExpr(std::move(copy)), defaultRealKind)};
    if (auto parts{common::AllPresent(std::move(rr), std::move(ri))}) {
      return Package(ConstructComplex(messages, std::get<0>(std::move(*parts)),
          std::get<1>(std::move(*parts)), defaultRealKind));
    }
  }
  return std::nullopt;
}

// Mixed COMPLEX operations with the COMPLEX operand on the right.
//  x + (a,b) -> (x+a, b)
//  x - (a,b) -> (x-a, -b)
//  x * (a,b) -> (x*a, x*b)
//  x / (a,b) -> (x,0) / (a,b)   (and **)
template <template <typename> class OPR, TypeCategory LCAT>
std::optional<Expr<SomeType>> MixedComplexRight(
    parser::ContextualMessages &messages, const Expr<SomeKind<LCAT>> &irx,
    const Expr<SomeComplex> &zy, [[maybe_unused]] int defaultRealKind) {
  if constexpr (std::is_same_v<OPR<LargestReal>, Add<LargestReal>>) {
    // x + (a,b) -> (a,b) + x -> (a+x, b)
    return MixedComplexLeft<OPR, LCAT>(messages, zy, irx, defaultRealKind);
  } else if constexpr (allowOperandDuplication &&
      std::is_same_v<OPR<LargestReal>, Multiply<LargestReal>>) {
    // x * (a,b) -> (a,b) * x -> (a*x, b*x)
    return MixedComplexLeft<OPR, LCAT>(messages, zy, irx, defaultRealKind);
  } else if constexpr (std::is_same_v<OPR<LargestReal>,
                           Subtract<LargestReal>>) {
    // x - (a,b) -> (x-a, -b)
    std::optional<Expr<SomeReal>> zr{ComplexPartExtractor<false>{}.Get(zy)};
    std::optional<Expr<SomeReal>> zi{ComplexPartExtractor<true>{}.Get(zy)};
    if (zr && zi) {
      if (std::optional<Expr<SomeType>> rr{NumericOperation<Subtract>(messages,
              AsGenericExpr(common::Clone(irx)), AsGenericExpr(std::move(*zr)),
              defaultRealKind)}) {
        return Package(ConstructComplex(messages, std::move(*rr),
            AsGenericExpr(-std::move(*zi)), defaultRealKind));
      }
    }
  }
  return std::nullopt;
}

// Promotes REAL(rk) and COMPLEX(zk) operands COMPLEX(max(rk,zk))
// then combine them with an operator.
template <template <typename> class OPR, TypeCategory XCAT, TypeCategory YCAT>
Expr<SomeComplex> PromoteMixedComplexReal(
    Expr<SomeKind<XCAT>> &&x, Expr<SomeKind<YCAT>> &&y) {
  static_assert(XCAT == TypeCategory::Complex || YCAT == TypeCategory::Complex);
  static_assert(XCAT == TypeCategory::Real || YCAT == TypeCategory::Real);
  return common::visit(
      [&](const auto &kx, const auto &ky) {
        constexpr int maxKind{std::max(
            ResultType<decltype(kx)>::kind, ResultType<decltype(ky)>::kind)};
        using ZTy = Type<TypeCategory::Complex, maxKind>;
        return Expr<SomeComplex>{
            Expr<ZTy>{OPR<ZTy>{ConvertToType<ZTy>(std::move(x)),
                ConvertToType<ZTy>(std::move(y))}}};
      },
      x.u, y.u);
}

// N.B. When a "typeless" BOZ literal constant appears as one (not both!) of
// the operands to a dyadic operation where one is permitted, it assumes the
// type and kind of the other operand.
template <template <typename> class OPR>
std::optional<Expr<SomeType>> NumericOperation(
    parser::ContextualMessages &messages, Expr<SomeType> &&x,
    Expr<SomeType> &&y, int defaultRealKind) {
  return common::visit(
      common::visitors{
          [](Expr<SomeInteger> &&ix, Expr<SomeInteger> &&iy) {
            return Package(PromoteAndCombine<OPR, TypeCategory::Integer>(
                std::move(ix), std::move(iy)));
          },
          [](Expr<SomeReal> &&rx, Expr<SomeReal> &&ry) {
            return Package(PromoteAndCombine<OPR, TypeCategory::Real>(
                std::move(rx), std::move(ry)));
          },
          // Mixed REAL/INTEGER operations
          [](Expr<SomeReal> &&rx, Expr<SomeInteger> &&iy) {
            return MixedRealLeft<OPR>(std::move(rx), std::move(iy));
          },
          [](Expr<SomeInteger> &&ix, Expr<SomeReal> &&ry) {
            return Package(common::visit(
                [&](auto &&ryk) -> Expr<SomeReal> {
                  using resultType = ResultType<decltype(ryk)>;
                  return AsCategoryExpr(
                      OPR<resultType>{ConvertToType<resultType>(std::move(ix)),
                          std::move(ryk)});
                },
                std::move(ry.u)));
          },
          // Homogeneous and mixed COMPLEX operations
          [](Expr<SomeComplex> &&zx, Expr<SomeComplex> &&zy) {
            return Package(PromoteAndCombine<OPR, TypeCategory::Complex>(
                std::move(zx), std::move(zy)));
          },
          [&](Expr<SomeComplex> &&zx, Expr<SomeInteger> &&iy) {
            if (auto result{
                    MixedComplexLeft<OPR>(messages, zx, iy, defaultRealKind)}) {
              return result;
            } else {
              return Package(PromoteAndCombine<OPR, TypeCategory::Complex>(
                  std::move(zx), ConvertTo(zx, std::move(iy))));
            }
          },
          [&](Expr<SomeComplex> &&zx, Expr<SomeReal> &&ry) {
            if (auto result{
                    MixedComplexLeft<OPR>(messages, zx, ry, defaultRealKind)}) {
              return result;
            } else {
              return Package(
                  PromoteMixedComplexReal<OPR>(std::move(zx), std::move(ry)));
            }
          },
          [&](Expr<SomeInteger> &&ix, Expr<SomeComplex> &&zy) {
            if (auto result{MixedComplexRight<OPR>(
                    messages, ix, zy, defaultRealKind)}) {
              return result;
            } else {
              return Package(PromoteAndCombine<OPR, TypeCategory::Complex>(
                  ConvertTo(zy, std::move(ix)), std::move(zy)));
            }
          },
          [&](Expr<SomeReal> &&rx, Expr<SomeComplex> &&zy) {
            if (auto result{MixedComplexRight<OPR>(
                    messages, rx, zy, defaultRealKind)}) {
              return result;
            } else {
              return Package(
                  PromoteMixedComplexReal<OPR>(std::move(rx), std::move(zy)));
            }
          },
          // Operations with one typeless operand
          [&](BOZLiteralConstant &&bx, Expr<SomeInteger> &&iy) {
            return NumericOperation<OPR>(messages,
                AsGenericExpr(ConvertTo(iy, std::move(bx))), std::move(y),
                defaultRealKind);
          },
          [&](BOZLiteralConstant &&bx, Expr<SomeReal> &&ry) {
            return NumericOperation<OPR>(messages,
                AsGenericExpr(ConvertTo(ry, std::move(bx))), std::move(y),
                defaultRealKind);
          },
          [&](Expr<SomeInteger> &&ix, BOZLiteralConstant &&by) {
            return NumericOperation<OPR>(messages, std::move(x),
                AsGenericExpr(ConvertTo(ix, std::move(by))), defaultRealKind);
          },
          [&](Expr<SomeReal> &&rx, BOZLiteralConstant &&by) {
            return NumericOperation<OPR>(messages, std::move(x),
                AsGenericExpr(ConvertTo(rx, std::move(by))), defaultRealKind);
          },
          // Default case
          [&](auto &&, auto &&) {
            messages.Say("non-numeric operands to numeric operation"_err_en_US);
            return NoExpr();
          },
      },
      std::move(x.u), std::move(y.u));
}

template std::optional<Expr<SomeType>> NumericOperation<Power>(
    parser::ContextualMessages &, Expr<SomeType> &&, Expr<SomeType> &&,
    int defaultRealKind);
template std::optional<Expr<SomeType>> NumericOperation<Multiply>(
    parser::ContextualMessages &, Expr<SomeType> &&, Expr<SomeType> &&,
    int defaultRealKind);
template std::optional<Expr<SomeType>> NumericOperation<Divide>(
    parser::ContextualMessages &, Expr<SomeType> &&, Expr<SomeType> &&,
    int defaultRealKind);
template std::optional<Expr<SomeType>> NumericOperation<Add>(
    parser::ContextualMessages &, Expr<SomeType> &&, Expr<SomeType> &&,
    int defaultRealKind);
template std::optional<Expr<SomeType>> NumericOperation<Subtract>(
    parser::ContextualMessages &, Expr<SomeType> &&, Expr<SomeType> &&,
    int defaultRealKind);

std::optional<Expr<SomeType>> Negation(
    parser::ContextualMessages &messages, Expr<SomeType> &&x) {
  return common::visit(
      common::visitors{
          [&](BOZLiteralConstant &&) {
            messages.Say("BOZ literal cannot be negated"_err_en_US);
            return NoExpr();
          },
          [&](NullPointer &&) {
            messages.Say("NULL() cannot be negated"_err_en_US);
            return NoExpr();
          },
          [&](ProcedureDesignator &&) {
            messages.Say("Subroutine cannot be negated"_err_en_US);
            return NoExpr();
          },
          [&](ProcedureRef &&) {
            messages.Say("Pointer to subroutine cannot be negated"_err_en_US);
            return NoExpr();
          },
          [&](Expr<SomeInteger> &&x) { return Package(-std::move(x)); },
          [&](Expr<SomeReal> &&x) { return Package(-std::move(x)); },
          [&](Expr<SomeComplex> &&x) { return Package(-std::move(x)); },
          [&](Expr<SomeCharacter> &&) {
            messages.Say("CHARACTER cannot be negated"_err_en_US);
            return NoExpr();
          },
          [&](Expr<SomeLogical> &&) {
            messages.Say("LOGICAL cannot be negated"_err_en_US);
            return NoExpr();
          },
          [&](Expr<SomeDerived> &&) {
            messages.Say("Operand cannot be negated"_err_en_US);
            return NoExpr();
          },
      },
      std::move(x.u));
}

Expr<SomeLogical> LogicalNegation(Expr<SomeLogical> &&x) {
  return common::visit(
      [](auto &&xk) { return AsCategoryExpr(LogicalNegation(std::move(xk))); },
      std::move(x.u));
}

template <TypeCategory CAT>
Expr<LogicalResult> PromoteAndRelate(
    RelationalOperator opr, Expr<SomeKind<CAT>> &&x, Expr<SomeKind<CAT>> &&y) {
  return common::visit(
      [=](auto &&xy) {
        return PackageRelation(opr, std::move(xy[0]), std::move(xy[1]));
      },
      AsSameKindExprs(std::move(x), std::move(y)));
}

std::optional<Expr<LogicalResult>> Relate(parser::ContextualMessages &messages,
    RelationalOperator opr, Expr<SomeType> &&x, Expr<SomeType> &&y) {
  return common::visit(
      common::visitors{
          [=](Expr<SomeInteger> &&ix,
              Expr<SomeInteger> &&iy) -> std::optional<Expr<LogicalResult>> {
            return PromoteAndRelate(opr, std::move(ix), std::move(iy));
          },
          [=](Expr<SomeReal> &&rx,
              Expr<SomeReal> &&ry) -> std::optional<Expr<LogicalResult>> {
            return PromoteAndRelate(opr, std::move(rx), std::move(ry));
          },
          [&](Expr<SomeReal> &&rx, Expr<SomeInteger> &&iy) {
            return Relate(messages, opr, std::move(x),
                AsGenericExpr(ConvertTo(rx, std::move(iy))));
          },
          [&](Expr<SomeInteger> &&ix, Expr<SomeReal> &&ry) {
            return Relate(messages, opr,
                AsGenericExpr(ConvertTo(ry, std::move(ix))), std::move(y));
          },
          [&](Expr<SomeComplex> &&zx,
              Expr<SomeComplex> &&zy) -> std::optional<Expr<LogicalResult>> {
            if (opr == RelationalOperator::EQ ||
                opr == RelationalOperator::NE) {
              return PromoteAndRelate(opr, std::move(zx), std::move(zy));
            } else {
              messages.Say(
                  "COMPLEX data may be compared only for equality"_err_en_US);
              return std::nullopt;
            }
          },
          [&](Expr<SomeComplex> &&zx, Expr<SomeInteger> &&iy) {
            return Relate(messages, opr, std::move(x),
                AsGenericExpr(ConvertTo(zx, std::move(iy))));
          },
          [&](Expr<SomeComplex> &&zx, Expr<SomeReal> &&ry) {
            return Relate(messages, opr, std::move(x),
                AsGenericExpr(ConvertTo(zx, std::move(ry))));
          },
          [&](Expr<SomeInteger> &&ix, Expr<SomeComplex> &&zy) {
            return Relate(messages, opr,
                AsGenericExpr(ConvertTo(zy, std::move(ix))), std::move(y));
          },
          [&](Expr<SomeReal> &&rx, Expr<SomeComplex> &&zy) {
            return Relate(messages, opr,
                AsGenericExpr(ConvertTo(zy, std::move(rx))), std::move(y));
          },
          [&](Expr<SomeCharacter> &&cx, Expr<SomeCharacter> &&cy) {
            return common::visit(
                [&](auto &&cxk,
                    auto &&cyk) -> std::optional<Expr<LogicalResult>> {
                  using Ty = ResultType<decltype(cxk)>;
                  if constexpr (std::is_same_v<Ty, ResultType<decltype(cyk)>>) {
                    return PackageRelation(opr, std::move(cxk), std::move(cyk));
                  } else {
                    messages.Say(
                        "CHARACTER operands do not have same KIND"_err_en_US);
                    return std::nullopt;
                  }
                },
                std::move(cx.u), std::move(cy.u));
          },
          // Default case
          [&](auto &&, auto &&) {
            DIE("invalid types for relational operator");
            return std::optional<Expr<LogicalResult>>{};
          },
      },
      std::move(x.u), std::move(y.u));
}

Expr<SomeLogical> BinaryLogicalOperation(
    LogicalOperator opr, Expr<SomeLogical> &&x, Expr<SomeLogical> &&y) {
  CHECK(opr != LogicalOperator::Not);
  return common::visit(
      [=](auto &&xy) {
        using Ty = ResultType<decltype(xy[0])>;
        return Expr<SomeLogical>{BinaryLogicalOperation<Ty::kind>(
            opr, std::move(xy[0]), std::move(xy[1]))};
      },
      AsSameKindExprs(std::move(x), std::move(y)));
}

template <TypeCategory TO>
std::optional<Expr<SomeType>> ConvertToNumeric(int kind, Expr<SomeType> &&x) {
  static_assert(common::IsNumericTypeCategory(TO));
  return common::visit(
      [=](auto &&cx) -> std::optional<Expr<SomeType>> {
        using cxType = std::decay_t<decltype(cx)>;
        if constexpr (!common::HasMember<cxType, TypelessExpression>) {
          if constexpr (IsNumericTypeCategory(ResultType<cxType>::category)) {
            return Expr<SomeType>{ConvertToKind<TO>(kind, std::move(cx))};
          }
        }
        return std::nullopt;
      },
      std::move(x.u));
}

std::optional<Expr<SomeType>> ConvertToType(
    const DynamicType &type, Expr<SomeType> &&x) {
  if (type.IsTypelessIntrinsicArgument()) {
    return std::nullopt;
  }
  switch (type.category()) {
  case TypeCategory::Integer:
    if (auto *boz{std::get_if<BOZLiteralConstant>(&x.u)}) {
      // Extension to C7109: allow BOZ literals to appear in integer contexts
      // when the type is unambiguous.
      return Expr<SomeType>{
          ConvertToKind<TypeCategory::Integer>(type.kind(), std::move(*boz))};
    }
    return ConvertToNumeric<TypeCategory::Integer>(type.kind(), std::move(x));
  case TypeCategory::Real:
    if (auto *boz{std::get_if<BOZLiteralConstant>(&x.u)}) {
      return Expr<SomeType>{
          ConvertToKind<TypeCategory::Real>(type.kind(), std::move(*boz))};
    }
    return ConvertToNumeric<TypeCategory::Real>(type.kind(), std::move(x));
  case TypeCategory::Complex:
    return ConvertToNumeric<TypeCategory::Complex>(type.kind(), std::move(x));
  case TypeCategory::Character:
    if (auto *cx{UnwrapExpr<Expr<SomeCharacter>>(x)}) {
      auto converted{
          ConvertToKind<TypeCategory::Character>(type.kind(), std::move(*cx))};
      if (auto length{type.GetCharLength()}) {
        converted = common::visit(
            [&](auto &&x) {
              using CharacterType = ResultType<decltype(x)>;
              return Expr<SomeCharacter>{
                  Expr<CharacterType>{SetLength<CharacterType::kind>{
                      std::move(x), std::move(*length)}}};
            },
            std::move(converted.u));
      }
      return Expr<SomeType>{std::move(converted)};
    }
    break;
  case TypeCategory::Logical:
    if (auto *cx{UnwrapExpr<Expr<SomeLogical>>(x)}) {
      return Expr<SomeType>{
          ConvertToKind<TypeCategory::Logical>(type.kind(), std::move(*cx))};
    }
    break;
  case TypeCategory::Derived:
    if (auto fromType{x.GetType()}) {
      if (type.IsTkCompatibleWith(*fromType)) {
        // "x" could be assigned or passed to "type", or appear in a
        // structure constructor as a value for a component with "type"
        return std::move(x);
      }
    }
    break;
  }
  return std::nullopt;
}

std::optional<Expr<SomeType>> ConvertToType(
    const DynamicType &to, std::optional<Expr<SomeType>> &&x) {
  if (x) {
    return ConvertToType(to, std::move(*x));
  } else {
    return std::nullopt;
  }
}

std::optional<Expr<SomeType>> ConvertToType(
    const Symbol &symbol, Expr<SomeType> &&x) {
  if (auto symType{DynamicType::From(symbol)}) {
    return ConvertToType(*symType, std::move(x));
  }
  return std::nullopt;
}

std::optional<Expr<SomeType>> ConvertToType(
    const Symbol &to, std::optional<Expr<SomeType>> &&x) {
  if (x) {
    return ConvertToType(to, std::move(*x));
  } else {
    return std::nullopt;
  }
}

bool IsAssumedRank(const Symbol &original) {
  if (const auto *assoc{original.detailsIf<semantics::AssocEntityDetails>()}) {
    if (assoc->rank()) {
      return false; // in RANK(n) or RANK(*)
    } else if (assoc->IsAssumedRank()) {
      return true; // RANK DEFAULT
    }
  }
  const Symbol &symbol{semantics::ResolveAssociations(original)};
  const auto *object{symbol.detailsIf<semantics::ObjectEntityDetails>()};
  return object && object->IsAssumedRank();
}

bool IsAssumedRank(const ActualArgument &arg) {
  if (const auto *expr{arg.UnwrapExpr()}) {
    return IsAssumedRank(*expr);
  } else {
    const Symbol *assumedTypeDummy{arg.GetAssumedTypeDummy()};
    CHECK(assumedTypeDummy);
    return IsAssumedRank(*assumedTypeDummy);
  }
}

bool IsCoarray(const ActualArgument &arg) {
  const auto *expr{arg.UnwrapExpr()};
  return expr && IsCoarray(*expr);
}

bool IsCoarray(const Symbol &symbol) {
  return GetAssociationRoot(symbol).Corank() > 0;
}

bool IsProcedure(const Expr<SomeType> &expr) {
  return std::holds_alternative<ProcedureDesignator>(expr.u);
}
bool IsFunction(const Expr<SomeType> &expr) {
  const auto *designator{std::get_if<ProcedureDesignator>(&expr.u)};
  return designator && designator->GetType().has_value();
}

bool IsPointer(const Expr<SomeType> &expr) {
  return IsObjectPointer(expr) || IsProcedurePointer(expr);
}

bool IsProcedurePointer(const Expr<SomeType> &expr) {
  if (IsNullProcedurePointer(expr)) {
    return true;
  } else if (const auto *funcRef{UnwrapProcedureRef(expr)}) {
    if (const Symbol * proc{funcRef->proc().GetSymbol()}) {
      const Symbol *result{FindFunctionResult(*proc)};
      return result && IsProcedurePointer(*result);
    } else {
      return false;
    }
  } else if (const auto *proc{std::get_if<ProcedureDesignator>(&expr.u)}) {
    return IsProcedurePointer(proc->GetSymbol());
  } else {
    return false;
  }
}

bool IsProcedurePointerTarget(const Expr<SomeType> &expr) {
  return common::visit(common::visitors{
                           [](const NullPointer &) { return true; },
                           [](const ProcedureDesignator &) { return true; },
                           [](const ProcedureRef &) { return true; },
                           [&](const auto &) {
                             const Symbol *last{GetLastSymbol(expr)};
                             return last && IsProcedurePointer(*last);
                           },
                       },
      expr.u);
}

bool IsObjectPointer(const Expr<SomeType> &expr) {
  if (IsNullObjectPointer(expr)) {
    return true;
  } else if (IsProcedurePointerTarget(expr)) {
    return false;
  } else if (const auto *funcRef{UnwrapProcedureRef(expr)}) {
    return IsVariable(*funcRef);
  } else if (const Symbol * symbol{UnwrapWholeSymbolOrComponentDataRef(expr)}) {
    return IsPointer(symbol->GetUltimate());
  } else {
    return false;
  }
}

// IsNullPointer() & variations

template <bool IS_PROC_PTR> struct IsNullPointerHelper {
  template <typename A> bool operator()(const A &) const { return false; }
  bool operator()(const ProcedureRef &call) const {
    if constexpr (IS_PROC_PTR) {
      const auto *intrinsic{call.proc().GetSpecificIntrinsic()};
      return intrinsic &&
          intrinsic->characteristics.value().attrs.test(
              characteristics::Procedure::Attr::NullPointer);
    } else {
      return false;
    }
  }
  template <typename T> bool operator()(const FunctionRef<T> &call) const {
    if constexpr (IS_PROC_PTR) {
      return false;
    } else {
      const auto *intrinsic{call.proc().GetSpecificIntrinsic()};
      return intrinsic &&
          intrinsic->characteristics.value().attrs.test(
              characteristics::Procedure::Attr::NullPointer);
    }
  }
  template <typename T> bool operator()(const Designator<T> &x) const {
    if (const auto *component{std::get_if<Component>(&x.u)}) {
      if (const auto *baseSym{std::get_if<SymbolRef>(&component->base().u)}) {
        const Symbol &base{**baseSym};
        if (const auto *object{
                base.detailsIf<semantics::ObjectEntityDetails>()}) {
          // TODO: nested component and array references
          if (IsNamedConstant(base) && object->init()) {
            if (auto structCons{
                    GetScalarConstantValue<SomeDerived>(*object->init())}) {
              auto iter{structCons->values().find(component->GetLastSymbol())};
              if (iter != structCons->values().end()) {
                return (*this)(iter->second.value());
              }
            }
          }
        }
      }
    }
    return false;
  }
  bool operator()(const NullPointer &) const { return true; }
  template <typename T> bool operator()(const Parentheses<T> &x) const {
    return (*this)(x.left());
  }
  template <typename T> bool operator()(const Expr<T> &x) const {
    return common::visit(*this, x.u);
  }
};

bool IsNullObjectPointer(const Expr<SomeType> &expr) {
  return IsNullPointerHelper<false>{}(expr);
}

bool IsNullProcedurePointer(const Expr<SomeType> &expr) {
  return IsNullPointerHelper<true>{}(expr);
}

bool IsNullPointer(const Expr<SomeType> &expr) {
  return IsNullObjectPointer(expr) || IsNullProcedurePointer(expr);
}

bool IsBareNullPointer(const Expr<SomeType> *expr) {
  return expr && std::holds_alternative<NullPointer>(expr->u);
}

// GetSymbolVector()
auto GetSymbolVectorHelper::operator()(const Symbol &x) const -> Result {
  if (const auto *details{x.detailsIf<semantics::AssocEntityDetails>()}) {
    if (IsVariable(details->expr()) && !UnwrapProcedureRef(*details->expr())) {
      // associate(x => variable that is not a pointer returned by a function)
      return (*this)(details->expr());
    }
  }
  return {x.GetUltimate()};
}
auto GetSymbolVectorHelper::operator()(const Component &x) const -> Result {
  Result result{(*this)(x.base())};
  result.emplace_back(x.GetLastSymbol());
  return result;
}
auto GetSymbolVectorHelper::operator()(const ArrayRef &x) const -> Result {
  return GetSymbolVector(x.base());
}
auto GetSymbolVectorHelper::operator()(const CoarrayRef &x) const -> Result {
  return x.base();
}

const Symbol *GetLastTarget(const SymbolVector &symbols) {
  auto end{std::crend(symbols)};
  // N.B. Neither clang nor g++ recognizes "symbols.crbegin()" here.
  auto iter{std::find_if(std::crbegin(symbols), end, [](const Symbol &x) {
    return x.attrs().HasAny(
        {semantics::Attr::POINTER, semantics::Attr::TARGET});
  })};
  return iter == end ? nullptr : &**iter;
}

struct CollectSymbolsHelper
    : public SetTraverse<CollectSymbolsHelper, semantics::UnorderedSymbolSet> {
  using Base = SetTraverse<CollectSymbolsHelper, semantics::UnorderedSymbolSet>;
  CollectSymbolsHelper() : Base{*this} {}
  using Base::operator();
  semantics::UnorderedSymbolSet operator()(const Symbol &symbol) const {
    return {symbol};
  }
};
template <typename A> semantics::UnorderedSymbolSet CollectSymbols(const A &x) {
  return CollectSymbolsHelper{}(x);
}
template semantics::UnorderedSymbolSet CollectSymbols(const Expr<SomeType> &);
template semantics::UnorderedSymbolSet CollectSymbols(
    const Expr<SomeInteger> &);
template semantics::UnorderedSymbolSet CollectSymbols(
    const Expr<SubscriptInteger> &);

// HasVectorSubscript()
struct HasVectorSubscriptHelper
    : public AnyTraverse<HasVectorSubscriptHelper, bool,
          /*TraverseAssocEntityDetails=*/false> {
  using Base = AnyTraverse<HasVectorSubscriptHelper, bool, false>;
  HasVectorSubscriptHelper() : Base{*this} {}
  using Base::operator();
  bool operator()(const Subscript &ss) const {
    return !std::holds_alternative<Triplet>(ss.u) && ss.Rank() > 0;
  }
  bool operator()(const ProcedureRef &) const {
    return false; // don't descend into function call arguments
  }
};

bool HasVectorSubscript(const Expr<SomeType> &expr) {
  return HasVectorSubscriptHelper{}(expr);
}

parser::Message *AttachDeclaration(
    parser::Message &message, const Symbol &symbol) {
  const Symbol *unhosted{&symbol};
  while (
      const auto *assoc{unhosted->detailsIf<semantics::HostAssocDetails>()}) {
    unhosted = &assoc->symbol();
  }
  if (const auto *binding{
          unhosted->detailsIf<semantics::ProcBindingDetails>()}) {
    if (binding->symbol().name() != symbol.name()) {
      message.Attach(binding->symbol().name(),
          "Procedure '%s' of type '%s' is bound to '%s'"_en_US, symbol.name(),
          symbol.owner().GetName().value(), binding->symbol().name());
      return &message;
    }
    unhosted = &binding->symbol();
  }
  if (const auto *use{symbol.detailsIf<semantics::UseDetails>()}) {
    message.Attach(use->location(),
        "'%s' is USE-associated with '%s' in module '%s'"_en_US, symbol.name(),
        unhosted->name(), GetUsedModule(*use).name());
  } else {
    message.Attach(
        unhosted->name(), "Declaration of '%s'"_en_US, unhosted->name());
  }
  return &message;
}

parser::Message *AttachDeclaration(
    parser::Message *message, const Symbol &symbol) {
  return message ? AttachDeclaration(*message, symbol) : nullptr;
}

class FindImpureCallHelper
    : public AnyTraverse<FindImpureCallHelper, std::optional<std::string>,
          /*TraverseAssocEntityDetails=*/false> {
  using Result = std::optional<std::string>;
  using Base = AnyTraverse<FindImpureCallHelper, Result, false>;

public:
  explicit FindImpureCallHelper(FoldingContext &c) : Base{*this}, context_{c} {}
  using Base::operator();
  Result operator()(const ProcedureRef &call) const {
    if (auto chars{characteristics::Procedure::Characterize(
            call.proc(), context_, /*emitError=*/false)}) {
      if (chars->attrs.test(characteristics::Procedure::Attr::Pure)) {
        return (*this)(call.arguments());
      }
    }
    return call.proc().GetName();
  }

private:
  FoldingContext &context_;
};

std::optional<std::string> FindImpureCall(
    FoldingContext &context, const Expr<SomeType> &expr) {
  return FindImpureCallHelper{context}(expr);
}
std::optional<std::string> FindImpureCall(
    FoldingContext &context, const ProcedureRef &proc) {
  return FindImpureCallHelper{context}(proc);
}

// Common handling for procedure pointer compatibility of left- and right-hand
// sides.  Returns nullopt if they're compatible.  Otherwise, it returns a
// message that needs to be augmented by the names of the left and right sides
// and the content of the "whyNotCompatible" string.
std::optional<parser::MessageFixedText> CheckProcCompatibility(bool isCall,
    const std::optional<characteristics::Procedure> &lhsProcedure,
    const characteristics::Procedure *rhsProcedure,
    const SpecificIntrinsic *specificIntrinsic, std::string &whyNotCompatible,
    std::optional<std::string> &warning, bool ignoreImplicitVsExplicit) {
  std::optional<parser::MessageFixedText> msg;
  if (!lhsProcedure) {
    msg = "In assignment to object %s, the target '%s' is a procedure"
          " designator"_err_en_US;
  } else if (!rhsProcedure) {
    msg = "In assignment to procedure %s, the characteristics of the target"
          " procedure '%s' could not be determined"_err_en_US;
  } else if (!isCall && lhsProcedure->functionResult &&
      rhsProcedure->functionResult &&
      !lhsProcedure->functionResult->IsCompatibleWith(
          *rhsProcedure->functionResult, &whyNotCompatible)) {
    msg =
        "Function %s associated with incompatible function designator '%s': %s"_err_en_US;
  } else if (lhsProcedure->IsCompatibleWith(*rhsProcedure,
                 ignoreImplicitVsExplicit, &whyNotCompatible, specificIntrinsic,
                 &warning)) {
    // OK
  } else if (isCall) {
    msg = "Procedure %s associated with result of reference to function '%s'"
          " that is an incompatible procedure pointer: %s"_err_en_US;
  } else if (lhsProcedure->IsPure() && !rhsProcedure->IsPure()) {
    msg = "PURE procedure %s may not be associated with non-PURE"
          " procedure designator '%s'"_err_en_US;
  } else if (lhsProcedure->IsFunction() && rhsProcedure->IsSubroutine()) {
    msg = "Function %s may not be associated with subroutine"
          " designator '%s'"_err_en_US;
  } else if (lhsProcedure->IsSubroutine() && rhsProcedure->IsFunction()) {
    msg = "Subroutine %s may not be associated with function"
          " designator '%s'"_err_en_US;
  } else if (lhsProcedure->HasExplicitInterface() &&
      !rhsProcedure->HasExplicitInterface()) {
    // Section 10.2.2.4, paragraph 3 prohibits associating a procedure pointer
    // that has an explicit interface with a procedure whose characteristics
    // don't match.  That's the case if the target procedure has an implicit
    // interface.  But this case is allowed by several other compilers as long
    // as the explicit interface can be called via an implicit interface.
    if (!lhsProcedure->CanBeCalledViaImplicitInterface()) {
      msg = "Procedure %s with explicit interface that cannot be called via "
            "an implicit interface cannot be associated with procedure "
            "designator with an implicit interface"_err_en_US;
    }
  } else if (!lhsProcedure->HasExplicitInterface() &&
      rhsProcedure->HasExplicitInterface()) {
    // OK if the target can be called via an implicit interface
    if (!rhsProcedure->CanBeCalledViaImplicitInterface() &&
        !specificIntrinsic) {
      msg = "Procedure %s with implicit interface may not be associated "
            "with procedure designator '%s' with explicit interface that "
            "cannot be called via an implicit interface"_err_en_US;
    }
  } else {
    msg = "Procedure %s associated with incompatible procedure"
          " designator '%s': %s"_err_en_US;
  }
  return msg;
}

// GetLastPointerSymbol()
static const Symbol *GetLastPointerSymbol(const Symbol &symbol) {
  return IsPointer(GetAssociationRoot(symbol)) ? &symbol : nullptr;
}
static const Symbol *GetLastPointerSymbol(const SymbolRef &symbol) {
  return GetLastPointerSymbol(*symbol);
}
static const Symbol *GetLastPointerSymbol(const Component &x) {
  const Symbol &c{x.GetLastSymbol()};
  return IsPointer(c) ? &c : GetLastPointerSymbol(x.base());
}
static const Symbol *GetLastPointerSymbol(const NamedEntity &x) {
  const auto *c{x.UnwrapComponent()};
  return c ? GetLastPointerSymbol(*c) : GetLastPointerSymbol(x.GetLastSymbol());
}
static const Symbol *GetLastPointerSymbol(const ArrayRef &x) {
  return GetLastPointerSymbol(x.base());
}
static const Symbol *GetLastPointerSymbol(const CoarrayRef &x) {
  return nullptr;
}
const Symbol *GetLastPointerSymbol(const DataRef &x) {
  return common::visit(
      [](const auto &y) { return GetLastPointerSymbol(y); }, x.u);
}

template <TypeCategory TO, TypeCategory FROM>
static std::optional<Expr<SomeType>> DataConstantConversionHelper(
    FoldingContext &context, const DynamicType &toType,
    const Expr<SomeType> &expr) {
  DynamicType sizedType{FROM, toType.kind()};
  if (auto sized{
          Fold(context, ConvertToType(sizedType, Expr<SomeType>{expr}))}) {
    if (const auto *someExpr{UnwrapExpr<Expr<SomeKind<FROM>>>(*sized)}) {
      return common::visit(
          [](const auto &w) -> std::optional<Expr<SomeType>> {
            using FromType = ResultType<decltype(w)>;
            static constexpr int kind{FromType::kind};
            if constexpr (IsValidKindOfIntrinsicType(TO, kind)) {
              if (const auto *fromConst{UnwrapExpr<Constant<FromType>>(w)}) {
                using FromWordType = typename FromType::Scalar;
                using LogicalType = value::Logical<FromWordType::bits>;
                using ElementType =
                    std::conditional_t<TO == TypeCategory::Logical, LogicalType,
                        typename LogicalType::Word>;
                std::vector<ElementType> values;
                auto at{fromConst->lbounds()};
                auto shape{fromConst->shape()};
                for (auto n{GetSize(shape)}; n-- > 0;
                     fromConst->IncrementSubscripts(at)) {
                  auto elt{fromConst->At(at)};
                  if constexpr (TO == TypeCategory::Logical) {
                    values.emplace_back(std::move(elt));
                  } else {
                    values.emplace_back(elt.word());
                  }
                }
                return {AsGenericExpr(AsExpr(Constant<Type<TO, kind>>{
                    std::move(values), std::move(shape)}))};
              }
            }
            return std::nullopt;
          },
          someExpr->u);
    }
  }
  return std::nullopt;
}

std::optional<Expr<SomeType>> DataConstantConversionExtension(
    FoldingContext &context, const DynamicType &toType,
    const Expr<SomeType> &expr0) {
  Expr<SomeType> expr{Fold(context, Expr<SomeType>{expr0})};
  if (!IsActuallyConstant(expr)) {
    return std::nullopt;
  }
  if (auto fromType{expr.GetType()}) {
    if (toType.category() == TypeCategory::Logical &&
        fromType->category() == TypeCategory::Integer) {
      return DataConstantConversionHelper<TypeCategory::Logical,
          TypeCategory::Integer>(context, toType, expr);
    }
    if (toType.category() == TypeCategory::Integer &&
        fromType->category() == TypeCategory::Logical) {
      return DataConstantConversionHelper<TypeCategory::Integer,
          TypeCategory::Logical>(context, toType, expr);
    }
  }
  return std::nullopt;
}

bool IsAllocatableOrPointerObject(const Expr<SomeType> &expr) {
  const semantics::Symbol *sym{UnwrapWholeSymbolOrComponentDataRef(expr)};
  return (sym &&
             semantics::IsAllocatableOrObjectPointer(&sym->GetUltimate())) ||
      evaluate::IsObjectPointer(expr);
}

bool IsAllocatableDesignator(const Expr<SomeType> &expr) {
  // Allocatable sub-objects are not themselves allocatable (9.5.3.1 NOTE 2).
  if (const semantics::Symbol *
      sym{UnwrapWholeSymbolOrComponentOrCoarrayRef(expr)}) {
    return semantics::IsAllocatable(sym->GetUltimate());
  }
  return false;
}

bool MayBePassedAsAbsentOptional(const Expr<SomeType> &expr) {
  const semantics::Symbol *sym{UnwrapWholeSymbolOrComponentDataRef(expr)};
  // 15.5.2.12 1. is pretty clear that an unallocated allocatable/pointer actual
  // may be passed to a non-allocatable/non-pointer optional dummy. Note that
  // other compilers (like nag, nvfortran, ifort, gfortran and xlf) seems to
  // ignore this point in intrinsic contexts (e.g CMPLX argument).
  return (sym && semantics::IsOptional(*sym)) ||
      IsAllocatableOrPointerObject(expr);
}

std::optional<Expr<SomeType>> HollerithToBOZ(FoldingContext &context,
    const Expr<SomeType> &expr, const DynamicType &type) {
  if (std::optional<std::string> chValue{GetScalarConstantValue<Ascii>(expr)}) {
    // Pad on the right with spaces when short, truncate the right if long.
    // TODO: big-endian targets
    auto bytes{static_cast<std::size_t>(
        ToInt64(type.MeasureSizeInBytes(context, false)).value())};
    BOZLiteralConstant bits{0};
    for (std::size_t j{0}; j < bytes; ++j) {
      char ch{j >= chValue->size() ? ' ' : chValue->at(j)};
      BOZLiteralConstant chBOZ{static_cast<unsigned char>(ch)};
      bits = bits.IOR(chBOZ.SHIFTL(8 * j));
    }
    return ConvertToType(type, Expr<SomeType>{bits});
  } else {
    return std::nullopt;
  }
}

// Extracts a whole symbol being used as a bound of a dummy argument,
// possibly wrapped with parentheses or MAX(0, ...).
template <int KIND>
static const Symbol *GetBoundSymbol(
    const Expr<Type<TypeCategory::Integer, KIND>> &expr) {
  using T = Type<TypeCategory::Integer, KIND>;
  return common::visit(
      common::visitors{
          [](const Extremum<T> &max) -> const Symbol * {
            if (max.ordering == Ordering::Greater) {
              if (auto zero{ToInt64(max.left())}; zero && *zero == 0) {
                return GetBoundSymbol(max.right());
              }
            }
            return nullptr;
          },
          [](const Parentheses<T> &x) { return GetBoundSymbol(x.left()); },
          [](const Designator<T> &x) -> const Symbol * {
            if (const auto *ref{std::get_if<SymbolRef>(&x.u)}) {
              return &**ref;
            }
            return nullptr;
          },
          [](const Convert<T, TypeCategory::Integer> &x) {
            return common::visit(
                [](const auto &y) -> const Symbol * {
                  using yType = std::decay_t<decltype(y)>;
                  using yResult = typename yType::Result;
                  if constexpr (yResult::kind <= KIND) {
                    return GetBoundSymbol(y);
                  } else {
                    return nullptr;
                  }
                },
                x.left().u);
          },
          [](const auto &) -> const Symbol * { return nullptr; },
      },
      expr.u);
}

std::optional<bool> AreEquivalentInInterface(
    const Expr<SubscriptInteger> &x, const Expr<SubscriptInteger> &y) {
  auto xVal{ToInt64(x)};
  auto yVal{ToInt64(y)};
  if (xVal && yVal) {
    return *xVal == *yVal;
  } else if (xVal || yVal) {
    return false;
  }
  const Symbol *xSym{GetBoundSymbol(x)};
  const Symbol *ySym{GetBoundSymbol(y)};
  if (xSym && ySym) {
    if (&xSym->GetUltimate() == &ySym->GetUltimate()) {
      return true; // USE/host associated same symbol
    }
    auto xNum{semantics::GetDummyArgumentNumber(xSym)};
    auto yNum{semantics::GetDummyArgumentNumber(ySym)};
    if (xNum && yNum) {
      if (*xNum == *yNum) {
        auto xType{DynamicType::From(*xSym)};
        auto yType{DynamicType::From(*ySym)};
        return xType && yType && xType->IsEquivalentTo(*yType);
      }
    }
    return false;
  } else if (xSym || ySym) {
    return false;
  }
  // Neither expression is an integer constant or a whole symbol.
  if (x == y) {
    return true;
  } else {
    return std::nullopt; // not sure
  }
}

bool CheckForCoindexedObject(parser::ContextualMessages &messages,
    const std::optional<ActualArgument> &arg, const std::string &procName,
    const std::string &argName) {
  if (arg && ExtractCoarrayRef(arg->UnwrapExpr())) {
    messages.Say(arg->sourceLocation(),
        "'%s' argument to '%s' may not be a coindexed object"_err_en_US,
        argName, procName);
    return false;
  } else {
    return true;
  }
}

} // namespace Fortran::evaluate

namespace Fortran::semantics {

const Symbol &ResolveAssociations(const Symbol &original) {
  const Symbol &symbol{original.GetUltimate()};
  if (const auto *details{symbol.detailsIf<AssocEntityDetails>()}) {
    if (!details->rank()) { // Not RANK(n) or RANK(*)
      if (const Symbol * nested{UnwrapWholeSymbolDataRef(details->expr())}) {
        return ResolveAssociations(*nested);
      }
    }
  }
  return symbol;
}

// When a construct association maps to a variable, and that variable
// is not an array with a vector-valued subscript, return the base
// Symbol of that variable, else nullptr.  Descends into other construct
// associations when one associations maps to another.
static const Symbol *GetAssociatedVariable(const AssocEntityDetails &details) {
  if (const auto &expr{details.expr()}) {
    if (IsVariable(*expr) && !HasVectorSubscript(*expr)) {
      if (const Symbol * varSymbol{GetFirstSymbol(*expr)}) {
        return &GetAssociationRoot(*varSymbol);
      }
    }
  }
  return nullptr;
}

const Symbol &GetAssociationRoot(const Symbol &original) {
  const Symbol &symbol{ResolveAssociations(original)};
  if (const auto *details{symbol.detailsIf<AssocEntityDetails>()}) {
    if (const Symbol * root{GetAssociatedVariable(*details)}) {
      return *root;
    }
  }
  return symbol;
}

const Symbol *GetMainEntry(const Symbol *symbol) {
  if (symbol) {
    if (const auto *subpDetails{symbol->detailsIf<SubprogramDetails>()}) {
      if (const Scope * scope{subpDetails->entryScope()}) {
        if (const Symbol * main{scope->symbol()}) {
          return main;
        }
      }
    }
  }
  return symbol;
}

bool IsVariableName(const Symbol &original) {
  const Symbol &ultimate{original.GetUltimate()};
  return !IsNamedConstant(ultimate) &&
      (ultimate.has<ObjectEntityDetails>() ||
          ultimate.has<AssocEntityDetails>());
}

static bool IsPureProcedureImpl(
    const Symbol &original, semantics::UnorderedSymbolSet &set) {
  // An ENTRY is pure if its containing subprogram is
  const Symbol &symbol{DEREF(GetMainEntry(&original.GetUltimate()))};
  if (set.find(symbol) != set.end()) {
    return true;
  }
  set.emplace(symbol);
  if (const auto *procDetails{symbol.detailsIf<ProcEntityDetails>()}) {
    if (procDetails->procInterface()) {
      // procedure with a pure interface
      return IsPureProcedureImpl(*procDetails->procInterface(), set);
    }
  } else if (const auto *details{symbol.detailsIf<ProcBindingDetails>()}) {
    return IsPureProcedureImpl(details->symbol(), set);
  } else if (!IsProcedure(symbol)) {
    return false;
  }
  if (IsStmtFunction(symbol)) {
    // Section 15.7(1) states that a statement function is PURE if it does not
    // reference an IMPURE procedure or a VOLATILE variable
    if (const auto &expr{symbol.get<SubprogramDetails>().stmtFunction()}) {
      for (const SymbolRef &ref : evaluate::CollectSymbols(*expr)) {
        if (&*ref == &symbol) {
          return false; // error recovery, recursion is caught elsewhere
        }
        if (IsFunction(*ref) && !IsPureProcedureImpl(*ref, set)) {
          return false;
        }
        if (ref->GetUltimate().attrs().test(Attr::VOLATILE)) {
          return false;
        }
      }
    }
    return true; // statement function was not found to be impure
  }
  return symbol.attrs().test(Attr::PURE) ||
      (symbol.attrs().test(Attr::ELEMENTAL) &&
          !symbol.attrs().test(Attr::IMPURE));
}

bool IsPureProcedure(const Symbol &original) {
  semantics::UnorderedSymbolSet set;
  return IsPureProcedureImpl(original, set);
}

bool IsPureProcedure(const Scope &scope) {
  const Symbol *symbol{scope.GetSymbol()};
  return symbol && IsPureProcedure(*symbol);
}

bool IsExplicitlyImpureProcedure(const Symbol &original) {
  // An ENTRY is IMPURE if its containing subprogram is so
  return DEREF(GetMainEntry(&original.GetUltimate()))
      .attrs()
      .test(Attr::IMPURE);
}

bool IsElementalProcedure(const Symbol &original) {
  // An ENTRY is elemental if its containing subprogram is
  const Symbol &symbol{DEREF(GetMainEntry(&original.GetUltimate()))};
  if (IsProcedure(symbol)) {
    auto &foldingContext{symbol.owner().context().foldingContext()};
    auto restorer{foldingContext.messages().DiscardMessages()};
    auto proc{evaluate::characteristics::Procedure::Characterize(
        symbol, foldingContext)};
    return proc &&
        proc->attrs.test(evaluate::characteristics::Procedure::Attr::Elemental);
  } else {
    return false;
  }
}

bool IsFunction(const Symbol &symbol) {
  const Symbol &ultimate{symbol.GetUltimate()};
  return ultimate.test(Symbol::Flag::Function) ||
      (!ultimate.test(Symbol::Flag::Subroutine) &&
          common::visit(
              common::visitors{
                  [](const SubprogramDetails &x) { return x.isFunction(); },
                  [](const ProcEntityDetails &x) {
                    const Symbol *ifc{x.procInterface()};
                    return x.type() || (ifc && IsFunction(*ifc));
                  },
                  [](const ProcBindingDetails &x) {
                    return IsFunction(x.symbol());
                  },
                  [](const auto &) { return false; },
              },
              ultimate.details()));
}

bool IsFunction(const Scope &scope) {
  const Symbol *symbol{scope.GetSymbol()};
  return symbol && IsFunction(*symbol);
}

bool IsProcedure(const Symbol &symbol) {
  return common::visit(common::visitors{
                           [&symbol](const SubprogramDetails &) {
                             const Scope *scope{symbol.scope()};
                             // Main programs & BLOCK DATA are not procedures.
                             return !scope ||
                                 scope->kind() == Scope::Kind::Subprogram;
                           },
                           [](const SubprogramNameDetails &) { return true; },
                           [](const ProcEntityDetails &) { return true; },
                           [](const GenericDetails &) { return true; },
                           [](const ProcBindingDetails &) { return true; },
                           [](const auto &) { return false; },
                       },
      symbol.GetUltimate().details());
}

bool IsProcedure(const Scope &scope) {
  const Symbol *symbol{scope.GetSymbol()};
  return symbol && IsProcedure(*symbol);
}

bool IsProcedurePointer(const Symbol &original) {
  const Symbol &symbol{GetAssociationRoot(original)};
  return IsPointer(symbol) && IsProcedure(symbol);
}

bool IsProcedurePointer(const Symbol *symbol) {
  return symbol && IsProcedurePointer(*symbol);
}

bool IsObjectPointer(const Symbol *original) {
  if (original) {
    const Symbol &symbol{GetAssociationRoot(*original)};
    return IsPointer(symbol) && !IsProcedure(symbol);
  } else {
    return false;
  }
}

bool IsAllocatableOrObjectPointer(const Symbol *original) {
  if (original) {
    const Symbol &ultimate{original->GetUltimate()};
    if (const auto *assoc{ultimate.detailsIf<AssocEntityDetails>()}) {
      // Only SELECT RANK construct entities can be ALLOCATABLE/POINTER.
      return (assoc->rank() || assoc->IsAssumedSize() ||
                 assoc->IsAssumedRank()) &&
          IsAllocatableOrObjectPointer(UnwrapWholeSymbolDataRef(assoc->expr()));
    } else {
      return IsAllocatable(ultimate) ||
          (IsPointer(ultimate) && !IsProcedure(ultimate));
    }
  } else {
    return false;
  }
}

const Symbol *FindCommonBlockContaining(const Symbol &original) {
  const Symbol &root{GetAssociationRoot(original)};
  const auto *details{root.detailsIf<ObjectEntityDetails>()};
  return details ? details->commonBlock() : nullptr;
}

// 3.11 automatic data object
bool IsAutomatic(const Symbol &original) {
  const Symbol &symbol{original.GetUltimate()};
  if (const auto *object{symbol.detailsIf<ObjectEntityDetails>()}) {
    if (!object->isDummy() && !IsAllocatable(symbol) && !IsPointer(symbol)) {
      if (const DeclTypeSpec * type{symbol.GetType()}) {
        // If a type parameter value is not a constant expression, the
        // object is automatic.
        if (type->category() == DeclTypeSpec::Character) {
          if (const auto &length{
                  type->characterTypeSpec().length().GetExplicit()}) {
            if (!evaluate::IsConstantExpr(*length)) {
              return true;
            }
          }
        } else if (const DerivedTypeSpec * derived{type->AsDerived()}) {
          for (const auto &pair : derived->parameters()) {
            if (const auto &value{pair.second.GetExplicit()}) {
              if (!evaluate::IsConstantExpr(*value)) {
                return true;
              }
            }
          }
        }
      }
      // If an array bound is not a constant expression, the object is
      // automatic.
      for (const ShapeSpec &dim : object->shape()) {
        if (const auto &lb{dim.lbound().GetExplicit()}) {
          if (!evaluate::IsConstantExpr(*lb)) {
            return true;
          }
        }
        if (const auto &ub{dim.ubound().GetExplicit()}) {
          if (!evaluate::IsConstantExpr(*ub)) {
            return true;
          }
        }
      }
    }
  }
  return false;
}

bool IsSaved(const Symbol &original) {
  const Symbol &symbol{GetAssociationRoot(original)};
  const Scope &scope{symbol.owner()};
  const common::LanguageFeatureControl &features{
      scope.context().languageFeatures()};
  auto scopeKind{scope.kind()};
  if (symbol.has<AssocEntityDetails>()) {
    return false; // ASSOCIATE(non-variable)
  } else if (scopeKind == Scope::Kind::DerivedType) {
    return false; // this is a component
  } else if (symbol.attrs().test(Attr::SAVE)) {
    return true; // explicit SAVE attribute
  } else if (IsDummy(symbol) || IsFunctionResult(symbol) ||
      IsAutomatic(symbol) || IsNamedConstant(symbol)) {
    return false;
  } else if (scopeKind == Scope::Kind::Module ||
      (scopeKind == Scope::Kind::MainProgram &&
          (symbol.attrs().test(Attr::TARGET) || evaluate::IsCoarray(symbol)))) {
    // 8.5.16p4
    // In main programs, implied SAVE matters only for pointer
    // initialization targets and coarrays.
    return true;
  } else if (scopeKind == Scope::Kind::MainProgram &&
      (features.IsEnabled(common::LanguageFeature::SaveMainProgram) ||
          (features.IsEnabled(
               common::LanguageFeature::SaveBigMainProgramVariables) &&
              symbol.size() > 32))) {
    // With SaveBigMainProgramVariables, keeping all unsaved main program
    // variables of 32 bytes or less on the stack allows keeping numerical and
    // logical scalars, small scalar characters or derived, small arrays, and
    // scalar descriptors on the stack. This leaves more room for lower level
    // optimizers to do register promotion or get easy aliasing information.
    return true;
  } else if (features.IsEnabled(common::LanguageFeature::DefaultSave) &&
      (scopeKind == Scope::Kind::MainProgram ||
          (scope.kind() == Scope::Kind::Subprogram &&
              !(scope.symbol() &&
                  scope.symbol()->attrs().test(Attr::RECURSIVE))))) {
    // -fno-automatic/-save/-Msave option applies to all objects in executable
    // main programs and subprograms unless they are explicitly RECURSIVE.
    return true;
  } else if (symbol.test(Symbol::Flag::InDataStmt)) {
    return true;
  } else if (const auto *object{symbol.detailsIf<ObjectEntityDetails>()};
             object && object->init()) {
    return true;
  } else if (IsProcedurePointer(symbol) && symbol.has<ProcEntityDetails>() &&
      symbol.get<ProcEntityDetails>().init()) {
    return true;
  } else if (scope.hasSAVE()) {
    return true; // bare SAVE statement
  } else if (const Symbol * block{FindCommonBlockContaining(symbol)};
             block && block->attrs().test(Attr::SAVE)) {
    return true; // in COMMON with SAVE
  } else {
    return false;
  }
}

bool IsDummy(const Symbol &symbol) {
  return common::visit(
      common::visitors{[](const EntityDetails &x) { return x.isDummy(); },
          [](const ObjectEntityDetails &x) { return x.isDummy(); },
          [](const ProcEntityDetails &x) { return x.isDummy(); },
          [](const SubprogramDetails &x) { return x.isDummy(); },
          [](const auto &) { return false; }},
      ResolveAssociations(symbol).details());
}

bool IsAssumedShape(const Symbol &symbol) {
  const Symbol &ultimate{ResolveAssociations(symbol)};
  const auto *object{ultimate.detailsIf<ObjectEntityDetails>()};
  return object && object->IsAssumedShape() &&
      !semantics::IsAllocatableOrObjectPointer(&ultimate);
}

bool IsDeferredShape(const Symbol &symbol) {
  const Symbol &ultimate{ResolveAssociations(symbol)};
  const auto *object{ultimate.detailsIf<ObjectEntityDetails>()};
  return object && object->CanBeDeferredShape() &&
      semantics::IsAllocatableOrObjectPointer(&ultimate);
}

bool IsFunctionResult(const Symbol &original) {
  const Symbol &symbol{GetAssociationRoot(original)};
  return common::visit(
      common::visitors{
          [](const EntityDetails &x) { return x.isFuncResult(); },
          [](const ObjectEntityDetails &x) { return x.isFuncResult(); },
          [](const ProcEntityDetails &x) { return x.isFuncResult(); },
          [](const auto &) { return false; },
      },
      symbol.details());
}

bool IsKindTypeParameter(const Symbol &symbol) {
  const auto *param{symbol.GetUltimate().detailsIf<TypeParamDetails>()};
  return param && param->attr() == common::TypeParamAttr::Kind;
}

bool IsLenTypeParameter(const Symbol &symbol) {
  const auto *param{symbol.GetUltimate().detailsIf<TypeParamDetails>()};
  return param && param->attr() == common::TypeParamAttr::Len;
}

bool IsExtensibleType(const DerivedTypeSpec *derived) {
  return !IsSequenceOrBindCType(derived) && !IsIsoCType(derived);
}

bool IsSequenceOrBindCType(const DerivedTypeSpec *derived) {
  return derived &&
      (derived->typeSymbol().attrs().test(Attr::BIND_C) ||
          derived->typeSymbol().get<DerivedTypeDetails>().sequence());
}

bool IsBuiltinDerivedType(const DerivedTypeSpec *derived, const char *name) {
  if (!derived) {
    return false;
  } else {
    const auto &symbol{derived->typeSymbol()};
    return &symbol.owner() == symbol.owner().context().GetBuiltinsScope() &&
        symbol.name() == "__builtin_"s + name;
  }
}

bool IsBuiltinCPtr(const Symbol &symbol) {
  if (const DeclTypeSpec *declType = symbol.GetType()) {
    if (const DerivedTypeSpec *derived = declType->AsDerived()) {
      return IsIsoCType(derived);
    }
  }
  return false;
}

bool IsIsoCType(const DerivedTypeSpec *derived) {
  return IsBuiltinDerivedType(derived, "c_ptr") ||
      IsBuiltinDerivedType(derived, "c_funptr");
}

bool IsEventType(const DerivedTypeSpec *derived) {
  return IsBuiltinDerivedType(derived, "event_type");
}

bool IsLockType(const DerivedTypeSpec *derived) {
  return IsBuiltinDerivedType(derived, "lock_type");
}

bool IsNotifyType(const DerivedTypeSpec *derived) {
  return IsBuiltinDerivedType(derived, "notify_type");
}

bool IsTeamType(const DerivedTypeSpec *derived) {
  return IsBuiltinDerivedType(derived, "team_type");
}

bool IsBadCoarrayType(const DerivedTypeSpec *derived) {
  return IsTeamType(derived) || IsIsoCType(derived);
}

bool IsEventTypeOrLockType(const DerivedTypeSpec *derivedTypeSpec) {
  return IsEventType(derivedTypeSpec) || IsLockType(derivedTypeSpec);
}

int CountLenParameters(const DerivedTypeSpec &type) {
  return llvm::count_if(
      type.parameters(), [](const auto &pair) { return pair.second.isLen(); });
}

int CountNonConstantLenParameters(const DerivedTypeSpec &type) {
  return llvm::count_if(type.parameters(), [](const auto &pair) {
    if (!pair.second.isLen()) {
      return false;
    } else if (const auto &expr{pair.second.GetExplicit()}) {
      return !IsConstantExpr(*expr);
    } else {
      return true;
    }
  });
}

const Symbol &GetUsedModule(const UseDetails &details) {
  return DEREF(details.symbol().owner().symbol());
}

static const Symbol *FindFunctionResult(
    const Symbol &original, UnorderedSymbolSet &seen) {
  const Symbol &root{GetAssociationRoot(original)};
  ;
  if (!seen.insert(root).second) {
    return nullptr; // don't loop
  }
  return common::visit(
      common::visitors{[](const SubprogramDetails &subp) {
                         return subp.isFunction() ? &subp.result() : nullptr;
                       },
          [&](const ProcEntityDetails &proc) {
            const Symbol *iface{proc.procInterface()};
            return iface ? FindFunctionResult(*iface, seen) : nullptr;
          },
          [&](const ProcBindingDetails &binding) {
            return FindFunctionResult(binding.symbol(), seen);
          },
          [](const auto &) -> const Symbol * { return nullptr; }},
      root.details());
}

const Symbol *FindFunctionResult(const Symbol &symbol) {
  UnorderedSymbolSet seen;
  return FindFunctionResult(symbol, seen);
}

// These are here in Evaluate/tools.cpp so that Evaluate can use
// them; they cannot be defined in symbol.h due to the dependence
// on Scope.

bool SymbolSourcePositionCompare::operator()(
    const SymbolRef &x, const SymbolRef &y) const {
  return x->GetSemanticsContext().allCookedSources().Precedes(
      x->name(), y->name());
}
bool SymbolSourcePositionCompare::operator()(
    const MutableSymbolRef &x, const MutableSymbolRef &y) const {
  return x->GetSemanticsContext().allCookedSources().Precedes(
      x->name(), y->name());
}

SemanticsContext &Symbol::GetSemanticsContext() const {
  return DEREF(owner_).context();
}

bool AreTkCompatibleTypes(const DeclTypeSpec *x, const DeclTypeSpec *y) {
  if (x && y) {
    if (auto xDt{evaluate::DynamicType::From(*x)}) {
      if (auto yDt{evaluate::DynamicType::From(*y)}) {
        return xDt->IsTkCompatibleWith(*yDt);
      }
    }
  }
  return false;
}

common::IgnoreTKRSet GetIgnoreTKR(const Symbol &symbol) {
  common::IgnoreTKRSet result;
  if (const auto *object{symbol.detailsIf<ObjectEntityDetails>()}) {
    result = object->ignoreTKR();
    if (const Symbol * ownerSymbol{symbol.owner().symbol()}) {
      if (const auto *ownerSubp{ownerSymbol->detailsIf<SubprogramDetails>()}) {
        if (ownerSubp->defaultIgnoreTKR()) {
          result |= common::ignoreTKRAll;
        }
      }
    }
  }
  return result;
}

std::optional<int> GetDummyArgumentNumber(const Symbol *symbol) {
  if (symbol) {
    if (IsDummy(*symbol)) {
      if (const Symbol * subpSym{symbol->owner().symbol()}) {
        if (const auto *subp{subpSym->detailsIf<SubprogramDetails>()}) {
          int j{0};
          for (const Symbol *dummy : subp->dummyArgs()) {
            if (dummy == symbol) {
              return j;
            }
            ++j;
          }
        }
      }
    }
  }
  return std::nullopt;
}

} // namespace Fortran::semantics
