/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst or https://cmake.org/licensing for details.  */
#include "cmGeneratorExpressionNode.h"

#include <algorithm>
#include <cassert>
#include <cerrno>
#include <cstdlib>
#include <cstring>
#include <exception>
#include <functional>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <stdexcept>
#include <unordered_map>
#include <utility>

#include <cm/iterator>
#include <cm/optional>
#include <cm/string_view>
#include <cmext/algorithm>
#include <cmext/string_view>

#include "cmsys/RegularExpression.hxx"
#include "cmsys/String.h"

#include "cmCMakePath.h"
#include "cmCMakeString.hxx"
#include "cmComputeLinkInformation.h"
#include "cmGenExContext.h"
#include "cmGenExEvaluation.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorExpressionDAGChecker.h"
#include "cmGeneratorExpressionEvaluator.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmLinkItem.h"
#include "cmList.h"
#include "cmListFileCache.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmOutputConverter.h"
#include "cmPolicies.h"
#include "cmRange.h"
#include "cmStandardLevelResolver.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmValue.h"
#include "cmake.h"

namespace {

bool HasKnownObjectFileLocation(cm::GenEx::Evaluation* eval,
                                GeneratorExpressionContent const* content,
                                std::string const& genex,
                                cmGeneratorTarget const* target)
{
  std::string reason;
  if (!eval->EvaluateForBuildsystem &&
      !target->Target->HasKnownObjectFileLocation(&reason)) {
    std::ostringstream e;
    e << "The evaluation of the " << genex
      << " generator expression "
         "is only suitable for consumption by CMake (limited"
      << reason
      << ").  "
         "It is not suitable for writing out elsewhere.";
    reportError(eval, content->GetOriginalExpression(), e.str());
    return false;
  }
  return true;
}

} // namespace

std::string cmGeneratorExpressionNode::EvaluateDependentExpression(
  std::string const& prop, cm::GenEx::Evaluation* eval,
  cmGeneratorTarget const* headTarget,
  cmGeneratorExpressionDAGChecker* dagChecker,
  cmGeneratorTarget const* currentTarget)
{
  cmGeneratorExpression ge(*eval->Context.LG->GetCMakeInstance(),
                           eval->Backtrace);
  std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
  cge->SetEvaluateForBuildsystem(eval->EvaluateForBuildsystem);
  cge->SetQuiet(eval->Quiet);
  std::string result =
    cge->Evaluate(eval->Context, dagChecker, headTarget, currentTarget);
  if (cge->GetHadContextSensitiveCondition()) {
    eval->HadContextSensitiveCondition = true;
  }
  if (cge->GetHadHeadSensitiveCondition()) {
    eval->HadHeadSensitiveCondition = true;
  }
  if (cge->GetHadLinkLanguageSensitiveCondition()) {
    eval->HadLinkLanguageSensitiveCondition = true;
  }
  return result;
}

static const struct ZeroNode : public cmGeneratorExpressionNode
{
  ZeroNode() {} // NOLINT(modernize-use-equals-default)

  bool GeneratesContent() const override { return false; }

  bool AcceptsArbitraryContentParameter() const override { return true; }

  std::string Evaluate(
    std::vector<std::string> const& /*parameters*/,
    cm::GenEx::Evaluation* /*eval*/,
    GeneratorExpressionContent const* /*content*/,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    return std::string();
  }
} zeroNode;

static const struct OneNode : public cmGeneratorExpressionNode
{
  OneNode() {} // NOLINT(modernize-use-equals-default)

  bool AcceptsArbitraryContentParameter() const override { return true; }

  std::string Evaluate(
    std::vector<std::string> const& parameters,
    cm::GenEx::Evaluation* /*eval*/,
    GeneratorExpressionContent const* /*content*/,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    return parameters.front();
  }
} oneNode;

static const struct OneNode buildInterfaceNode;

static const struct ZeroNode installInterfaceNode;

static const struct OneNode buildLocalInterfaceNode;

struct BooleanOpNode : public cmGeneratorExpressionNode
{
  BooleanOpNode(char const* op_, char const* successVal_,
                char const* failureVal_)
    : op(op_)
    , successVal(successVal_)
    , failureVal(failureVal_)
  {
  }

  int NumExpectedParameters() const override { return OneOrMoreParameters; }

  bool ShouldEvaluateNextParameter(std::vector<std::string> const& parameters,
                                   std::string& def_value) const override
  {
    if (!parameters.empty() && parameters.back() == failureVal) {
      def_value = failureVal;
      return false;
    }
    return true;
  }

  std::string Evaluate(std::vector<std::string> const& parameters,
                       cm::GenEx::Evaluation* eval,
                       GeneratorExpressionContent const* content,
                       cmGeneratorExpressionDAGChecker*) const override
  {
    for (std::string const& param : parameters) {
      if (param == this->failureVal) {
        return this->failureVal;
      }
      if (param != this->successVal) {
        std::ostringstream e;
        e << "Parameters to $<" << this->op;
        e << "> must resolve to either '0' or '1'.";
        reportError(eval, content->GetOriginalExpression(), e.str());
        return std::string();
      }
    }
    return this->successVal;
  }

  char const *const op, *const successVal, *const failureVal;
};

static BooleanOpNode const andNode("AND", "1", "0"), orNode("OR", "0", "1");

static const struct NotNode : public cmGeneratorExpressionNode
{
  NotNode() {} // NOLINT(modernize-use-equals-default)

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    if (parameters.front() != "0" && parameters.front() != "1") {
      reportError(
        eval, content->GetOriginalExpression(),
        "$<NOT> parameter must resolve to exactly one '0' or '1' value.");
      return std::string();
    }
    return parameters.front() == "0" ? "1" : "0";
  }
} notNode;

static const struct BoolNode : public cmGeneratorExpressionNode
{
  BoolNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 1; }

  std::string Evaluate(
    std::vector<std::string> const& parameters,
    cm::GenEx::Evaluation* /*eval*/,
    GeneratorExpressionContent const* /*content*/,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    return !cmIsOff(parameters.front()) ? "1" : "0";
  }
} boolNode;

static const struct IfNode : public cmGeneratorExpressionNode
{
  IfNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 3; }

  bool ShouldEvaluateNextParameter(std::vector<std::string> const& parameters,
                                   std::string&) const override
  {
    return (parameters.empty() ||
            parameters[0] != cmStrCat(parameters.size() - 1, ""));
  }

  std::string Evaluate(std::vector<std::string> const& parameters,
                       cm::GenEx::Evaluation* eval,
                       GeneratorExpressionContent const* content,
                       cmGeneratorExpressionDAGChecker*) const override
  {
    if (parameters[0] != "1" && parameters[0] != "0") {
      reportError(eval, content->GetOriginalExpression(),
                  "First parameter to $<IF> must resolve to exactly one '0' "
                  "or '1' value.");
      return std::string();
    }
    return parameters[0] == "1" ? parameters[1] : parameters[2];
  }
} ifNode;

static const struct StrEqualNode : public cmGeneratorExpressionNode
{
  StrEqualNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 2; }

  std::string Evaluate(
    std::vector<std::string> const& parameters,
    cm::GenEx::Evaluation* /*eval*/,
    GeneratorExpressionContent const* /*content*/,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    return cm::CMakeString{ parameters.front() }.Compare(
             cm::CMakeString::CompOperator::EQUAL, parameters[1])
      ? "1"
      : "0";
  }
} strEqualNode;
static const struct StrLessNode : public cmGeneratorExpressionNode
{
  StrLessNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 2; }

  std::string Evaluate(
    std::vector<std::string> const& parameters,
    cm::GenEx::Evaluation* /*eval*/,
    GeneratorExpressionContent const* /*content*/,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    return cm::CMakeString{ parameters.front() }.Compare(
             cm::CMakeString::CompOperator::LESS, parameters[1])
      ? "1"
      : "0";
  }
} strLessNode;
static const struct StrLessEqualNode : public cmGeneratorExpressionNode
{
  StrLessEqualNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 2; }

  std::string Evaluate(
    std::vector<std::string> const& parameters,
    cm::GenEx::Evaluation* /*eval*/,
    GeneratorExpressionContent const* /*content*/,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    return cm::CMakeString{ parameters.front() }.Compare(
             cm::CMakeString::CompOperator::LESS_EQUAL, parameters[1])
      ? "1"
      : "0";
  }
} strLessEqualNode;
static const struct StrGreaterNode : public cmGeneratorExpressionNode
{
  StrGreaterNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 2; }

  std::string Evaluate(
    std::vector<std::string> const& parameters,
    cm::GenEx::Evaluation* /*eval*/,
    GeneratorExpressionContent const* /*content*/,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    return cm::CMakeString{ parameters.front() }.Compare(
             cm::CMakeString::CompOperator::GREATER, parameters[1])
      ? "1"
      : "0";
  }
} strGreaterNode;
static const struct StrGreaterEqualNode : public cmGeneratorExpressionNode
{
  StrGreaterEqualNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 2; }

  std::string Evaluate(
    std::vector<std::string> const& parameters,
    cm::GenEx::Evaluation* /*eval*/,
    GeneratorExpressionContent const* /*content*/,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    return cm::CMakeString{ parameters.front() }.Compare(
             cm::CMakeString::CompOperator::GREATER_EQUAL, parameters[1])
      ? "1"
      : "0";
  }
} strGreaterEqualNode;

static const struct EqualNode : public cmGeneratorExpressionNode
{
  EqualNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 2; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    long numbers[2];
    for (int i = 0; i < 2; ++i) {
      if (!ParameterToLong(parameters[i].c_str(), &numbers[i])) {
        reportError(eval, content->GetOriginalExpression(),
                    "$<EQUAL> parameter " + parameters[i] +
                      " is not a valid integer.");
        return {};
      }
    }
    return numbers[0] == numbers[1] ? "1" : "0";
  }

  static bool ParameterToLong(char const* param, long* outResult)
  {
    char const isNegative = param[0] == '-';

    int base = 0;
    if (cmHasLiteralPrefix(param, "0b") || cmHasLiteralPrefix(param, "0B")) {
      base = 2;
      param += 2;
    } else if (cmHasLiteralPrefix(param, "-0b") ||
               cmHasLiteralPrefix(param, "-0B") ||
               cmHasLiteralPrefix(param, "+0b") ||
               cmHasLiteralPrefix(param, "+0B")) {
      base = 2;
      param += 3;
    }

    char* pEnd;
    long result = strtol(param, &pEnd, base);
    if (pEnd == param || *pEnd != '\0' || errno == ERANGE) {
      return false;
    }
    if (isNegative && result > 0) {
      result *= -1;
    }
    *outResult = result;
    return true;
  }
} equalNode;

static const struct InListNode : public cmGeneratorExpressionNode
{
  InListNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 2; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* /*content*/,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    cmList values;
    cmList checkValues;
    bool check = false;
    switch (eval->Context.LG->GetPolicyStatus(cmPolicies::CMP0085)) {
      case cmPolicies::WARN:
        if (parameters.front().empty()) {
          check = true;
          checkValues.assign(parameters[1], cmList::EmptyElements::Yes);
        }
        CM_FALLTHROUGH;
      case cmPolicies::OLD:
        values.assign(parameters[1]);
        if (check && values != checkValues) {
          std::ostringstream e;
          e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0085)
            << "\nSearch Item:\n  \"" << parameters.front()
            << "\"\nList:\n  \"" << parameters[1] << "\"\n";
          eval->Context.LG->GetCMakeInstance()->IssueMessage(
            MessageType ::AUTHOR_WARNING, e.str(), eval->Backtrace);
          return "0";
        }
        if (values.empty()) {
          return "0";
        }
        break;
      case cmPolicies::NEW:
        values.assign(parameters[1], cmList::EmptyElements::Yes);
        break;
    }

    return values.find(parameters.front()) != cmList::npos ? "1" : "0";
  }
} inListNode;

static const struct FilterNode : public cmGeneratorExpressionNode
{
  FilterNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 3; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    if (parameters.size() != 3) {
      reportError(eval, content->GetOriginalExpression(),
                  "$<FILTER:...> expression requires three parameters");
      return {};
    }

    if (parameters[1] != "INCLUDE" && parameters[1] != "EXCLUDE") {
      reportError(
        eval, content->GetOriginalExpression(),
        "$<FILTER:...> second parameter must be either INCLUDE or EXCLUDE");
      return {};
    }

    try {
      return cmList{ parameters.front(), cmList::EmptyElements::Yes }
        .filter(parameters[2],
                parameters[1] == "EXCLUDE" ? cmList::FilterMode::EXCLUDE
                                           : cmList::FilterMode::INCLUDE)
        .to_string();
    } catch (std::invalid_argument&) {
      reportError(eval, content->GetOriginalExpression(),
                  "$<FILTER:...> failed to compile regex");
      return {};
    }
  }
} filterNode;

static const struct RemoveDuplicatesNode : public cmGeneratorExpressionNode
{
  RemoveDuplicatesNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 1; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    if (parameters.size() != 1) {
      reportError(
        eval, content->GetOriginalExpression(),
        "$<REMOVE_DUPLICATES:...> expression requires one parameter");
    }

    return cmList{ parameters.front(), cmList::EmptyElements::Yes }
      .remove_duplicates()
      .to_string();
  }

} removeDuplicatesNode;

static const struct TargetExistsNode : public cmGeneratorExpressionNode
{
  TargetExistsNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 1; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    if (parameters.size() != 1) {
      reportError(eval, content->GetOriginalExpression(),
                  "$<TARGET_EXISTS:...> expression requires one parameter");
      return std::string();
    }

    std::string const& targetName = parameters.front();
    if (targetName.empty() ||
        !cmGeneratorExpression::IsValidTargetName(targetName)) {
      reportError(eval, content->GetOriginalExpression(),
                  "$<TARGET_EXISTS:tgt> expression requires a non-empty "
                  "valid target name.");
      return std::string();
    }

    return eval->Context.LG->GetMakefile()->FindTargetToUse(targetName) ? "1"
                                                                        : "0";
  }
} targetExistsNode;

static const struct TargetNameIfExistsNode : public cmGeneratorExpressionNode
{
  TargetNameIfExistsNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 1; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    if (parameters.size() != 1) {
      reportError(eval, content->GetOriginalExpression(),
                  "$<TARGET_NAME_IF_EXISTS:...> expression requires one "
                  "parameter");
      return std::string();
    }

    std::string const& targetName = parameters.front();
    if (targetName.empty() ||
        !cmGeneratorExpression::IsValidTargetName(targetName)) {
      reportError(eval, content->GetOriginalExpression(),
                  "$<TARGET_NAME_IF_EXISTS:tgt> expression requires a "
                  "non-empty valid target name.");
      return std::string();
    }

    return eval->Context.LG->GetMakefile()->FindTargetToUse(targetName)
      ? targetName
      : std::string();
  }
} targetNameIfExistsNode;

struct GenexEvaluator : public cmGeneratorExpressionNode
{
  GenexEvaluator() {} // NOLINT(modernize-use-equals-default)

protected:
  std::string EvaluateExpression(
    std::string const& genexOperator, std::string const& expression,
    cm::GenEx::Evaluation* eval, GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagCheckerParent) const
  {
    if (eval->HeadTarget) {
      cmGeneratorExpressionDAGChecker dagChecker{
        eval->HeadTarget, genexOperator + ":" + expression,
        content,          dagCheckerParent,
        eval->Context,    eval->Backtrace,
      };
      switch (dagChecker.Check()) {
        case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
        case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: {
          dagChecker.ReportError(eval, content->GetOriginalExpression());
          return std::string();
        }
        case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
        case cmGeneratorExpressionDAGChecker::DAG:
          break;
      }

      return this->EvaluateDependentExpression(
        expression, eval, eval->HeadTarget, &dagChecker, eval->CurrentTarget);
    }

    return this->EvaluateDependentExpression(
      expression, eval, eval->HeadTarget, dagCheckerParent,
      eval->CurrentTarget);
  }
};

static const struct TargetGenexEvalNode : public GenexEvaluator
{
  TargetGenexEvalNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 2; }

  bool AcceptsArbitraryContentParameter() const override { return true; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagCheckerParent) const override
  {
    std::string const& targetName = parameters.front();
    if (targetName.empty() ||
        !cmGeneratorExpression::IsValidTargetName(targetName)) {
      reportError(eval, content->GetOriginalExpression(),
                  "$<TARGET_GENEX_EVAL:tgt, ...> expression requires a "
                  "non-empty valid target name.");
      return std::string();
    }

    auto const* target =
      eval->Context.LG->FindGeneratorTargetToUse(targetName);
    if (!target) {
      std::ostringstream e;
      e << "$<TARGET_GENEX_EVAL:tgt, ...> target \"" << targetName
        << "\" not found.";
      reportError(eval, content->GetOriginalExpression(), e.str());
      return std::string();
    }

    std::string const& expression = parameters[1];
    if (expression.empty()) {
      return expression;
    }

    // Replace the surrounding context with the named target.
    cm::GenEx::Evaluation targetEval(eval->Context, eval->Quiet, target,
                                     target, eval->EvaluateForBuildsystem,
                                     eval->Backtrace);

    return this->EvaluateExpression("TARGET_GENEX_EVAL", expression,
                                    &targetEval, content, dagCheckerParent);
  }
} targetGenexEvalNode;

static const struct GenexEvalNode : public GenexEvaluator
{
  GenexEvalNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 1; }

  bool AcceptsArbitraryContentParameter() const override { return true; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagCheckerParent) const override
  {
    std::string const& expression = parameters[0];
    if (expression.empty()) {
      return expression;
    }

    return this->EvaluateExpression("GENEX_EVAL", expression, eval, content,
                                    dagCheckerParent);
  }
} genexEvalNode;

static const struct LowerCaseNode : public cmGeneratorExpressionNode
{
  LowerCaseNode() {} // NOLINT(modernize-use-equals-default)

  bool AcceptsArbitraryContentParameter() const override { return true; }

  std::string Evaluate(
    std::vector<std::string> const& parameters,
    cm::GenEx::Evaluation* /*eval*/,
    GeneratorExpressionContent const* /*content*/,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    return cmSystemTools::LowerCase(parameters.front());
  }
} lowerCaseNode;

static const struct UpperCaseNode : public cmGeneratorExpressionNode
{
  UpperCaseNode() {} // NOLINT(modernize-use-equals-default)

  bool AcceptsArbitraryContentParameter() const override { return true; }

  std::string Evaluate(
    std::vector<std::string> const& parameters,
    cm::GenEx::Evaluation* /*eval*/,
    GeneratorExpressionContent const* /*content*/,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    return cmSystemTools::UpperCase(parameters.front());
  }
} upperCaseNode;

namespace {
template <typename Container>
class Range : public cmRange<typename Container::const_iterator>
{
private:
  using Base = cmRange<typename Container::const_iterator>;

public:
  using const_iterator = typename Container::const_iterator;
  using value_type = typename Container::value_type;
  using size_type = typename Container::size_type;
  using difference_type = typename Container::difference_type;
  using const_reference = typename Container::const_reference;

  Range(Container const& container)
    : Base(container.begin(), container.end())
  {
  }

  const_reference operator[](size_type pos) const
  {
    return *(this->begin() + pos);
  }

  const_reference front() const { return *this->begin(); }
  const_reference back() const { return *std::prev(this->end()); }

  Range& advance(difference_type amount) &
  {
    Base::advance(amount);
    return *this;
  }
  Range advance(difference_type amount) &&
  {
    Base::advance(amount);
    return std::move(*this);
  }
};

using Arguments = Range<std::vector<std::string>>;

bool CheckGenExParameters(cm::GenEx::Evaluation* eval,
                          GeneratorExpressionContent const* cnt,
                          cm::string_view genex, cm::string_view option,
                          std::size_t count, int required = 1,
                          bool exactly = true)
{
  if (static_cast<int>(count) < required ||
      (exactly && static_cast<int>(count) > required)) {
    std::string nbParameters;
    switch (required) {
      case 1:
        nbParameters = "one parameter";
        break;
      case 2:
        nbParameters = "two parameters";
        break;
      case 3:
        nbParameters = "three parameters";
        break;
      case 4:
        nbParameters = "four parameters";
        break;
      default:
        nbParameters = cmStrCat(required, " parameters");
    }
    reportError(eval, cnt->GetOriginalExpression(),
                cmStrCat("$<", genex, ':', option, "> expression requires ",
                         (exactly ? "exactly" : "at least"), ' ', nbParameters,
                         '.'));
    return false;
  }
  return true;
};

template <typename IndexType>
bool GetNumericArgument(std::string const& arg, IndexType& value)
{
  try {
    std::size_t pos;

    if (sizeof(IndexType) == sizeof(long)) {
      value = std::stol(arg, &pos);
    } else {
      value = std::stoll(arg, &pos);
    }

    if (pos != arg.length()) {
      // this is not a number
      return false;
    }
  } catch (std::invalid_argument const&) {
    return false;
  }

  return true;
}

template <typename IndexType>
bool GetNumericArguments(
  cm::GenEx::Evaluation* eval, GeneratorExpressionContent const* cnt,
  Arguments args, std::vector<IndexType>& indexes,
  cmList::ExpandElements expandElements = cmList::ExpandElements::No)
{
  using IndexRange = cmRange<Arguments::const_iterator>;
  IndexRange arguments(args.begin(), args.end());
  cmList list;
  if (expandElements == cmList::ExpandElements::Yes) {
    list = cmList{ args.begin(), args.end(), expandElements };
    arguments = IndexRange{ list.begin(), list.end() };
  }

  for (auto const& value : arguments) {
    IndexType index;
    if (!GetNumericArgument(value, index)) {
      reportError(eval, cnt->GetOriginalExpression(),
                  cmStrCat("index: \"", value, "\" is not a valid index"));
      return false;
    }
    indexes.push_back(index);
  }
  return true;
}

bool CheckPathParametersEx(cm::GenEx::Evaluation* eval,
                           GeneratorExpressionContent const* cnt,
                           cm::string_view option, std::size_t count,
                           int required = 1, bool exactly = true)
{
  return CheckGenExParameters(eval, cnt, "PATH"_s, option, count, required,
                              exactly);
}
bool CheckPathParameters(cm::GenEx::Evaluation* eval,
                         GeneratorExpressionContent const* cnt,
                         cm::string_view option, Arguments args,
                         int required = 1)
{
  return CheckPathParametersEx(eval, cnt, option, args.size(), required);
};

std::string ToString(bool isTrue)
{
  return isTrue ? "1" : "0";
};
}

static const struct PathNode : public cmGeneratorExpressionNode
{
  PathNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return TwoOrMoreParameters; }

  bool AcceptsArbitraryContentParameter() const override { return true; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    static auto processList =
      [](std::string const& arg,
         std::function<void(std::string&)> transform) -> std::string {
      cmList list{ arg };
      std::for_each(list.begin(), list.end(), std::move(transform));
      return list.to_string();
    };

    static std::unordered_map<
      cm::string_view,
      std::function<std::string(cm::GenEx::Evaluation*,
                                GeneratorExpressionContent const*,
                                Arguments&)>>
      pathCommands{
        { "GET_ROOT_NAME"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckPathParameters(ev, cnt, "GET_ROOT_NAME"_s, args) &&
                !args.front().empty()) {
              return processList(args.front(), [](std::string& value) {
                value = cmCMakePath{ value }.GetRootName().String();
              });
            }
            return std::string{};
          } },
        { "GET_ROOT_DIRECTORY"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckPathParameters(ev, cnt, "GET_ROOT_DIRECTORY"_s, args) &&
                !args.front().empty()) {
              return processList(args.front(), [](std::string& value) {
                value = cmCMakePath{ value }.GetRootDirectory().String();
              });
            }
            return std::string{};
          } },
        { "GET_ROOT_PATH"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckPathParameters(ev, cnt, "GET_ROOT_PATH"_s, args) &&
                !args.front().empty()) {
              return processList(args.front(), [](std::string& value) {
                value = cmCMakePath{ value }.GetRootPath().String();
              });
            }
            return std::string{};
          } },
        { "GET_FILENAME"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckPathParameters(ev, cnt, "GET_FILENAME"_s, args) &&
                !args.front().empty()) {
              return processList(args.front(), [](std::string& value) {
                value = cmCMakePath{ value }.GetFileName().String();
              });
            }
            return std::string{};
          } },
        { "GET_EXTENSION"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            bool lastOnly = args.front() == "LAST_ONLY"_s;
            if (lastOnly) {
              args.advance(1);
            }
            if (CheckPathParametersEx(ev, cnt,
                                      lastOnly ? "GET_EXTENSION,LAST_ONLY"_s
                                               : "GET_EXTENSION"_s,
                                      args.size())) {
              if (args.front().empty()) {
                return std::string{};
              }
              if (lastOnly) {
                return processList(args.front(), [](std::string& value) {
                  value = cmCMakePath{ value }.GetExtension().String();
                });
              }
              return processList(args.front(), [](std::string& value) {
                value = cmCMakePath{ value }.GetWideExtension().String();
              });
            }
            return std::string{};
          } },
        { "GET_STEM"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            bool lastOnly = args.front() == "LAST_ONLY"_s;
            if (lastOnly) {
              args.advance(1);
            }
            if (CheckPathParametersEx(
                  ev, cnt, lastOnly ? "GET_STEM,LAST_ONLY"_s : "GET_STEM"_s,
                  args.size())) {
              if (args.front().empty()) {
                return std::string{};
              }
              if (lastOnly) {
                return processList(args.front(), [](std::string& value) {
                  value = cmCMakePath{ value }.GetStem().String();
                });
              }
              return processList(args.front(), [](std::string& value) {
                value = cmCMakePath{ value }.GetNarrowStem().String();
              });
            }
            return std::string{};
          } },
        { "GET_RELATIVE_PART"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckPathParameters(ev, cnt, "GET_RELATIVE_PART"_s, args) &&
                !args.front().empty()) {
              return processList(args.front(), [](std::string& value) {
                value = cmCMakePath{ value }.GetRelativePath().String();
              });
            }
            return std::string{};
          } },
        { "GET_PARENT_PATH"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckPathParameters(ev, cnt, "GET_PARENT_PATH"_s, args)) {
              return processList(args.front(), [](std::string& value) {
                value = cmCMakePath{ value }.GetParentPath().String();
              });
            }
            return std::string{};
          } },
        { "HAS_ROOT_NAME"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            return CheckPathParameters(ev, cnt, "HAS_ROOT_NAME"_s, args)
              ? ToString(cmCMakePath{ args.front() }.HasRootName())
              : std::string{ "0" };
          } },
        { "HAS_ROOT_DIRECTORY"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            return CheckPathParameters(ev, cnt, "HAS_ROOT_DIRECTORY"_s, args)
              ? ToString(cmCMakePath{ args.front() }.HasRootDirectory())
              : std::string{ "0" };
          } },
        { "HAS_ROOT_PATH"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            return CheckPathParameters(ev, cnt, "HAS_ROOT_PATH"_s, args)
              ? ToString(cmCMakePath{ args.front() }.HasRootPath())
              : std::string{ "0" };
          } },
        { "HAS_FILENAME"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            return CheckPathParameters(ev, cnt, "HAS_FILENAME"_s, args)
              ? ToString(cmCMakePath{ args.front() }.HasFileName())
              : std::string{ "0" };
          } },
        { "HAS_EXTENSION"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            return CheckPathParameters(ev, cnt, "HAS_EXTENSION"_s, args) &&
                !args.front().empty()
              ? ToString(cmCMakePath{ args.front() }.HasExtension())
              : std::string{ "0" };
          } },
        { "HAS_STEM"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            return CheckPathParameters(ev, cnt, "HAS_STEM"_s, args)
              ? ToString(cmCMakePath{ args.front() }.HasStem())
              : std::string{ "0" };
          } },
        { "HAS_RELATIVE_PART"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            return CheckPathParameters(ev, cnt, "HAS_RELATIVE_PART"_s, args)
              ? ToString(cmCMakePath{ args.front() }.HasRelativePath())
              : std::string{ "0" };
          } },
        { "HAS_PARENT_PATH"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            return CheckPathParameters(ev, cnt, "HAS_PARENT_PATH"_s, args)
              ? ToString(cmCMakePath{ args.front() }.HasParentPath())
              : std::string{ "0" };
          } },
        { "IS_ABSOLUTE"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            return CheckPathParameters(ev, cnt, "IS_ABSOLUTE"_s, args)
              ? ToString(cmCMakePath{ args.front() }.IsAbsolute())
              : std::string{ "0" };
          } },
        { "IS_RELATIVE"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            return CheckPathParameters(ev, cnt, "IS_RELATIVE"_s, args)
              ? ToString(cmCMakePath{ args.front() }.IsRelative())
              : std::string{ "0" };
          } },
        { "IS_PREFIX"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            bool normalize = args.front() == "NORMALIZE"_s;
            if (normalize) {
              args.advance(1);
            }
            if (CheckPathParametersEx(
                  ev, cnt, normalize ? "IS_PREFIX,NORMALIZE"_s : "IS_PREFIX"_s,
                  args.size(), 2)) {
              if (normalize) {
                return ToString(cmCMakePath{ args[0] }.Normal().IsPrefix(
                  cmCMakePath{ args[1] }.Normal()));
              }
              return ToString(
                cmCMakePath{ args[0] }.IsPrefix(cmCMakePath{ args[1] }));
            }
            return std::string{};
          } },
        { "CMAKE_PATH"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            bool normalize = args.front() == "NORMALIZE"_s;
            if (normalize) {
              args.advance(1);
            }
            if (CheckPathParametersEx(ev, cnt,
                                      normalize ? "CMAKE_PATH,NORMALIZE"_s
                                                : "CMAKE_PATH"_s,
                                      args.size(), 1)) {
              return processList(
                args.front(), [normalize](std::string& value) {
                  auto path = cmCMakePath{ value, cmCMakePath::auto_format };
                  value = normalize ? path.Normal().GenericString()
                                    : path.GenericString();
                });
            }
            return std::string{};
          } },
        { "NATIVE_PATH"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            bool normalize = args.front() == "NORMALIZE"_s;
            if (normalize) {
              args.advance(1);
            }
            if (CheckPathParametersEx(ev, cnt,
                                      normalize ? "NATIVE_PATH,NORMALIZE"_s
                                                : "NATIVE_PATH"_s,
                                      args.size(), 1)) {
              return processList(
                args.front(), [normalize](std::string& value) {
                  auto path = cmCMakePath{ value };
                  value = normalize ? path.Normal().NativeString()
                                    : path.NativeString();
                });
            }
            return std::string{};
          } },
        { "APPEND"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckPathParametersEx(ev, cnt, "APPEND"_s, args.size(), 1,
                                      false)) {
              auto const& list = args.front();
              args.advance(1);

              return processList(list, [&args](std::string& value) {
                cmCMakePath path{ value };
                for (auto const& p : args) {
                  path /= p;
                }
                value = path.String();
              });
            }
            return std::string{};
          } },
        { "REMOVE_FILENAME"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckPathParameters(ev, cnt, "REMOVE_FILENAME"_s, args) &&
                !args.front().empty()) {
              return processList(args.front(), [](std::string& value) {
                value = cmCMakePath{ value }.RemoveFileName().String();
              });
            }
            return std::string{};
          } },
        { "REPLACE_FILENAME"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckPathParameters(ev, cnt, "REPLACE_FILENAME"_s, args, 2)) {
              return processList(args.front(), [&args](std::string& value) {
                value = cmCMakePath{ value }
                          .ReplaceFileName(cmCMakePath{ args[1] })
                          .String();
              });
            }
            return std::string{};
          } },
        { "REMOVE_EXTENSION"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            bool lastOnly = args.front() == "LAST_ONLY"_s;
            if (lastOnly) {
              args.advance(1);
            }
            if (CheckPathParametersEx(ev, cnt,
                                      lastOnly ? "REMOVE_EXTENSION,LAST_ONLY"_s
                                               : "REMOVE_EXTENSION"_s,
                                      args.size())) {
              if (args.front().empty()) {
                return std::string{};
              }
              if (lastOnly) {
                return processList(args.front(), [](std::string& value) {
                  value = cmCMakePath{ value }.RemoveExtension().String();
                });
              }
              return processList(args.front(), [](std::string& value) {
                value = cmCMakePath{ value }.RemoveWideExtension().String();
              });
            }
            return std::string{};
          } },
        { "REPLACE_EXTENSION"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            bool lastOnly = args.front() == "LAST_ONLY"_s;
            if (lastOnly) {
              args.advance(1);
            }
            if (CheckPathParametersEx(ev, cnt,
                                      lastOnly
                                        ? "REPLACE_EXTENSION,LAST_ONLY"_s
                                        : "REPLACE_EXTENSION"_s,
                                      args.size(), 2)) {
              if (lastOnly) {
                return processList(args.front(), [&args](std::string& value) {
                  value = cmCMakePath{ value }
                            .ReplaceExtension(cmCMakePath{ args[1] })
                            .String();
                });
              }
              return processList(args.front(), [&args](std::string& value) {
                value = cmCMakePath{ value }
                          .ReplaceWideExtension(cmCMakePath{ args[1] })
                          .String();
              });
            }
            return std::string{};
          } },
        { "NORMAL_PATH"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckPathParameters(ev, cnt, "NORMAL_PATH"_s, args) &&
                !args.front().empty()) {
              return processList(args.front(), [](std::string& value) {
                value = cmCMakePath{ value }.Normal().String();
              });
            }
            return std::string{};
          } },
        { "RELATIVE_PATH"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckPathParameters(ev, cnt, "RELATIVE_PATH"_s, args, 2)) {
              return processList(args.front(), [&args](std::string& value) {
                value = cmCMakePath{ value }.Relative(args[1]).String();
              });
            }
            return std::string{};
          } },
        { "ABSOLUTE_PATH"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            bool normalize = args.front() == "NORMALIZE"_s;
            if (normalize) {
              args.advance(1);
            }
            if (CheckPathParametersEx(ev, cnt,
                                      normalize ? "ABSOLUTE_PATH,NORMALIZE"_s
                                                : "ABSOLUTE_PATH"_s,
                                      args.size(), 2)) {
              return processList(
                args.front(), [&args, normalize](std::string& value) {
                  auto path = cmCMakePath{ value }.Absolute(args[1]);
                  value = normalize ? path.Normal().String() : path.String();
                });
            }
            return std::string{};
          } }
      };

    if (cm::contains(pathCommands, parameters.front())) {
      auto args = Arguments{ parameters }.advance(1);
      return pathCommands[parameters.front()](eval, content, args);
    }

    reportError(eval, content->GetOriginalExpression(),
                cmStrCat(parameters.front(), ": invalid option."));
    return std::string{};
  }
} pathNode;

static const struct PathEqualNode : public cmGeneratorExpressionNode
{
  PathEqualNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 2; }

  std::string Evaluate(
    std::vector<std::string> const& parameters,
    cm::GenEx::Evaluation* /*eval*/,
    GeneratorExpressionContent const* /*content*/,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    return cmCMakePath{ parameters[0] } == cmCMakePath{ parameters[1] } ? "1"
                                                                        : "0";
  }
} pathEqualNode;

namespace {
inline bool CheckStringParametersEx(cm::GenEx::Evaluation* eval,
                                    GeneratorExpressionContent const* cnt,
                                    cm::string_view option, std::size_t count,
                                    int required = 1, bool exactly = true)
{
  return CheckGenExParameters(eval, cnt, "STRING"_s, option, count, required,
                              exactly);
}
inline bool CheckStringParameters(cm::GenEx::Evaluation* eval,
                                  GeneratorExpressionContent const* cnt,
                                  cm::string_view option, Arguments args,
                                  int required = 1)
{
  return CheckStringParametersEx(eval, cnt, option, args.size(), required);
};
}

static const struct StringNode : public cmGeneratorExpressionNode
{
  StringNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return OneOrMoreParameters; }

  bool AcceptsArbitraryContentParameter() const override { return true; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    static std::unordered_map<
      cm::string_view,
      std::function<std::string(cm::GenEx::Evaluation*,
                                GeneratorExpressionContent const*,
                                Arguments&)>>
      stringCommands{
        { "LENGTH"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckStringParameters(ev, cnt, "LENGTH"_s, args)) {
              return std::to_string(cm::CMakeString{ args.front() }.Length());
            }
            return std::string{};
          } },
        { "SUBSTRING"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckStringParameters(ev, cnt, "SUBSTRING"_s, args, 3)) {
              cm::CMakeString str{ args.front() };
              std::vector<long> indexes;
              if (GetNumericArguments(ev, cnt, args.advance(1), indexes)) {
                try {
                  return str.Substring(indexes.front(), indexes.back());
                } catch (std::out_of_range const& e) {
                  reportError(ev, cnt->GetOriginalExpression(), e.what());
                  return std::string{};
                }
              }
            }
            return std::string{};
          } },
        { "FIND"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckStringParametersEx(ev, cnt, "FIND"_s, args.size(), 2,
                                        false)) {
              if (args.size() > 3) {
                reportError(ev, cnt->GetOriginalExpression(),
                            "$<STRING:FIND> expression expects at "
                            "most three parameters.");
                return std::string{};
              }

              auto const FROM = "FROM:"_s;

              cm::CMakeString str{ args.front() };
              cm::CMakeString::FindFrom from =
                cm::CMakeString::FindFrom::Begin;
              cm::string_view substring;

              args.advance(1);
              if (args.size() == 2) {
                cm::CMakeString::FindFrom opt =
                  static_cast<cm::CMakeString::FindFrom>(-1);

                for (auto const& arg : args) {
                  if (cmHasPrefix(arg, FROM)) {
                    if (arg != "FROM:BEGIN"_s && arg != "FROM:END"_s) {
                      reportError(
                        ev, cnt->GetOriginalExpression(),
                        cmStrCat("Invalid value for '", FROM,
                                 "' option. 'BEGIN' or 'END' expected."));
                      return std::string{};
                    }
                    opt = arg == "FROM:BEGIN"_s
                      ? cm::CMakeString::FindFrom::Begin
                      : cm::CMakeString::FindFrom::End;
                  } else {
                    substring = arg;
                  }
                }
                if (opt == static_cast<cm::CMakeString::FindFrom>(-1)) {
                  reportError(
                    ev, cnt->GetOriginalExpression(),
                    cmStrCat("Expected option '", FROM, "' is missing."));
                  return std::string{};
                }
                from = opt;
              } else {
                substring = args.front();
              }
              auto pos = str.Find(substring, from);
              return pos == cm::CMakeString::npos ? "-1" : std::to_string(pos);
            }
            return std::string{};
          } },
        { "MATCH"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckStringParametersEx(ev, cnt, "MATCH"_s, args.size(), 2,
                                        false)) {
              if (args.size() > 3) {
                reportError(ev, cnt->GetOriginalExpression(),
                            "$<STRING:MATCH> expression expects at "
                            "most three parameters.");
                return std::string{};
              }

              auto const SEEK = "SEEK:"_s;

              cm::CMakeString str{ args.front() };
              cm::CMakeString::MatchItems seek =
                cm::CMakeString::MatchItems::Once;
              auto const* regex = &args[1];

              args.advance(1);
              if (args.size() == 2) {
                cm::CMakeString::MatchItems opt =
                  static_cast<cm::CMakeString::MatchItems>(-1);

                for (auto const& arg : args) {
                  if (cmHasPrefix(arg, SEEK)) {
                    if (arg != "SEEK:ONCE"_s && arg != "SEEK:ALL"_s) {
                      reportError(
                        ev, cnt->GetOriginalExpression(),
                        cmStrCat("Invalid value for '", SEEK,
                                 "' option. 'ONCE' or 'ALL' expected."));
                      return std::string{};
                    }
                    opt = arg == "SEEK:ONCE"_s
                      ? cm::CMakeString::MatchItems::Once
                      : cm::CMakeString::MatchItems::All;
                  } else {
                    regex = &arg;
                  }
                }
                if (opt == static_cast<cm::CMakeString::MatchItems>(-1)) {
                  reportError(
                    ev, cnt->GetOriginalExpression(),
                    cmStrCat("Expected option '", SEEK, "' is missing."));
                  return std::string{};
                }
                seek = opt;
              }

              try {
                return str.Match(*regex, seek).to_string();
              } catch (std::invalid_argument const& e) {
                reportError(ev, cnt->GetOriginalExpression(), e.what());
                return std::string{};
              }
            }
            return std::string{};
          } },
        { "JOIN"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckStringParametersEx(ev, cnt, "JOIN"_s, args.size(), 2,
                                        false)) {
              auto const& glue = args.front();
              return cm::CMakeString{ args.advance(1), glue };
            }
            return std::string{};
          } },
        { "ASCII"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckStringParametersEx(ev, cnt, "ASCII"_s, args.size(), 1,
                                        false)) {
              try {
                return cm::CMakeString{}.FromASCII(args);
              } catch (std::invalid_argument const& e) {
                reportError(ev, cnt->GetOriginalExpression(), e.what());
                return std::string{};
              }
            }
            return std::string{};
          } },
        { "TIMESTAMP"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            cm::string_view format;
            cm::CMakeString::UTC utc = cm::CMakeString::UTC::No;

            if (args.size() == 2 && args.front() != "UTC"_s &&
                args.back() != "UTC"_s) {
              reportError(ev, cnt->GetOriginalExpression(),
                          "'UTC' option is expected.");
              return std::string{};
            }
            if (args.size() > 2) {
              reportError(ev, cnt->GetOriginalExpression(),
                          "$<STRING:TIMESTAMP> expression expects at most two "
                          "parameters.");
              return std::string{};
            }

            for (auto const& arg : args) {
              if (arg == "UTC"_s) {
                utc = cm::CMakeString::UTC::Yes;
              } else {
                format = arg;
              }
            }
            return cm::CMakeString{}.Timestamp(format, utc);
          } },
        { "RANDOM"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            auto const ALPHABET = "ALPHABET:"_s;
            auto const LENGTH = "LENGTH:"_s;
            auto const RANDOM_SEED = "RANDOM_SEED:"_s;

            if (args.size() > 3) {
              reportError(ev, cnt->GetOriginalExpression(),
                          "$<STRING:RANDOM> expression expects at most three "
                          "parameters.");
              return std::string{};
            }

            cm::string_view alphabet;
            std::size_t length = 5;
            bool seed_specified = false;
            unsigned int seed = 0;
            for (auto const& arg : args) {
              if (cmHasPrefix(arg, ALPHABET)) {
                alphabet = cm::string_view{ arg.c_str() + ALPHABET.length() };
                continue;
              }
              if (cmHasPrefix(arg, LENGTH)) {
                try {
                  length = std::stoul(arg.substr(LENGTH.size()));
                } catch (std::exception const&) {
                  reportError(ev, cnt->GetOriginalExpression(),
                              cmStrCat(arg, ": invalid numeric value for '",
                                       LENGTH, "' option."));
                  return std::string{};
                }
                continue;
              }
              if (cmHasPrefix(arg, RANDOM_SEED)) {
                try {
                  seed_specified = true;
                  seed = static_cast<unsigned int>(
                    std::stoul(arg.substr(RANDOM_SEED.size())));
                } catch (std::exception const&) {
                  reportError(ev, cnt->GetOriginalExpression(),
                              cmStrCat(arg, ": invalid numeric value for '",
                                       RANDOM_SEED, "' option."));
                  return std::string{};
                }
                continue;
              }
              reportError(ev, cnt->GetOriginalExpression(),
                          cmStrCat(arg, ": invalid parameter."));
              return std::string{};
            }

            try {
              if (seed_specified) {
                return cm::CMakeString{}.Random(seed, length, alphabet);
              }
              return cm::CMakeString{}.Random(length, alphabet);
            } catch (std::exception const& e) {
              reportError(ev, cnt->GetOriginalExpression(), e.what());
              return std::string{};
            }
          } },
        { "UUID"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckStringParametersEx(ev, cnt, "UUID"_s, args.size(), 2,
                                        false)) {
              auto const NAMESPACE = "NAMESPACE:"_s;
              auto const NAME = "NAME:"_s;
              auto const TYPE = "TYPE:"_s;
              auto const CASE = "CASE:"_s;

              if (args.size() > 4) {
                reportError(ev, cnt->GetOriginalExpression(),
                            "$<STRING:UUID> expression expects at most four "
                            "parameters.");
                return std::string{};
              }

              cm::string_view nameSpace;
              cm::string_view name;
              cm::CMakeString::UUIDType type =
                static_cast<cm::CMakeString::UUIDType>(-1);
              cm::CMakeString::Case uuidCase = cm::CMakeString::Case::Lower;
              for (auto const& arg : args) {
                if (cmHasPrefix(arg, NAMESPACE)) {
                  nameSpace =
                    cm::string_view{ arg.c_str() + NAMESPACE.length() };
                  if (nameSpace.empty()) {
                    reportError(
                      ev, cnt->GetOriginalExpression(),
                      cmStrCat("Invalid value for '", NAMESPACE, "' option."));
                    return std::string{};
                  }
                  continue;
                }
                if (cmHasPrefix(arg, NAME)) {
                  name = cm::string_view{ arg.c_str() + NAME.length() };
                  continue;
                }
                if (cmHasPrefix(arg, TYPE)) {
                  auto value = cm::string_view{ arg.c_str() + TYPE.length() };
                  if (value != "MD5"_s && value != "SHA1"_s) {
                    reportError(
                      ev, cnt->GetOriginalExpression(),
                      cmStrCat("Invalid value for '", TYPE,
                               "' option. 'MD5' or 'SHA1' expected."));
                    return std::string{};
                  }
                  type = value == "MD5"_s ? cm::CMakeString::UUIDType::MD5
                                          : cm::CMakeString::UUIDType::SHA1;
                  continue;
                }
                if (cmHasPrefix(arg, CASE)) {
                  auto value = cm::string_view{ arg.c_str() + CASE.length() };
                  if (value != "UPPER"_s && value != "LOWER"_s) {
                    reportError(
                      ev, cnt->GetOriginalExpression(),
                      cmStrCat("Invalid value for '", CASE,
                               "' option. 'UPPER' or 'LOWER' expected."));
                    return std::string{};
                  }
                  uuidCase = value == "UPPER"_s ? cm::CMakeString::Case::Upper
                                                : cm::CMakeString::Case::Lower;
                  continue;
                }
                reportError(ev, cnt->GetOriginalExpression(),
                            cmStrCat(arg, ": invalid parameter."));
                return std::string{};
              }
              if (nameSpace.empty()) {
                reportError(
                  ev, cnt->GetOriginalExpression(),
                  cmStrCat("Required option '", NAMESPACE, "' is missing."));
                return std::string{};
              }
              if (type == static_cast<cm::CMakeString::UUIDType>(-1)) {
                reportError(
                  ev, cnt->GetOriginalExpression(),
                  cmStrCat("Required option '", TYPE, "' is missing."));
                return std::string{};
              }

              try {
                return cm::CMakeString{}.UUID(nameSpace, name, type, uuidCase);
              } catch (std::exception const& e) {
                reportError(ev, cnt->GetOriginalExpression(), e.what());
                return std::string{};
              }
            }
            return std::string{};
          } },
        { "REPLACE"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckStringParametersEx(ev, cnt, "REPLACE"_s, args.size(), 3,
                                        false)) {
              if (args.size() > 4) {
                reportError(ev, cnt->GetOriginalExpression(),
                            "$<STRING:REPLACE> expression expects at "
                            "most four parameters.");
                return std::string{};
              }

              cm::CMakeString::Regex isRegex = cm::CMakeString::Regex::No;
              if (args.size() == 4) {
                cm::string_view type = args.front();
                if (type != "STRING"_s && type != "REGEX"_s) {
                  reportError(
                    ev, cnt->GetOriginalExpression(),
                    cmStrCat(
                      '\'', type,
                      "' is unexpected. 'STRING' or 'REGEX' expected."));
                  return std::string{};
                }
                isRegex = type == "STRING"_s ? cm::CMakeString::Regex::No
                                             : cm::CMakeString::Regex::Yes;
                args.advance(1);
              }

              try {
                return cm::CMakeString{ args.front() }.Replace(
                  args[1], args[2], isRegex);
              } catch (std::invalid_argument const& e) {
                reportError(ev, cnt->GetOriginalExpression(), e.what());
                return std::string{};
              }
            }
            return std::string{};
          } },
        { "APPEND"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckStringParametersEx(ev, cnt, "APPEND"_s, args.size(), 2,
                                        false)) {
              cm::CMakeString data{ args.front() };
              return data.Append(args.advance(1));
            }
            return std::string{};
          } },
        { "PREPEND"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckStringParametersEx(ev, cnt, "PREPEND "_s, args.size(), 2,
                                        false)) {
              cm::CMakeString data{ args.front() };
              return data.Prepend(args.advance(1));
            }
            return std::string{};
          } },
        { "TOLOWER"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckStringParameters(ev, cnt, "TOLOWER"_s, args, 1)) {
              return cm::CMakeString{}.ToLower(args.front());
            }
            return std::string{};
          } },
        { "TOUPPER"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckStringParameters(ev, cnt, "TOUPPER"_s, args, 1)) {
              return cm::CMakeString{}.ToUpper(args.front());
            }
            return std::string{};
          } },
        { "STRIP"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckStringParameters(ev, cnt, "STRIP"_s, args, 2)) {
              if (args.front() != "SPACES"_s) {
                reportError(ev, cnt->GetOriginalExpression(),
                            cmStrCat('\'', args.front(),
                                     "' is unexpected. 'SPACES' expected."));
                return std::string{};
              }

              return cm::CMakeString{ args[1] }.Strip();
            }
            return std::string{};
          } },
        { "QUOTE"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckStringParameters(ev, cnt, "QUOTE"_s, args, 2)) {
              if (args.front() != "REGEX"_s) {
                reportError(ev, cnt->GetOriginalExpression(),
                            cmStrCat('\'', args.front(),
                                     "' is unexpected. 'REGEX' expected."));
                return std::string{};
              }

              return cm::CMakeString{ args[1] }.Quote();
            }
            return std::string{};
          } },
        { "HEX"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckStringParameters(ev, cnt, "HEX"_s, args, 1)) {
              return cm::CMakeString{ args.front() }.ToHexadecimal();
            }
            return std::string{};
          } },
        { "HASH"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckStringParameters(ev, cnt, "HASH"_s, args, 2)) {
              auto const ALGORITHM = "ALGORITHM:"_s;

              if (cmHasPrefix(args[1], ALGORITHM)) {
                try {
                  auto const algo =
                    cm::string_view{ args[1].c_str() + ALGORITHM.length() };
                  if (algo.empty()) {
                    reportError(
                      ev, cnt->GetOriginalExpression(),
                      cmStrCat("Missing value for '", ALGORITHM, "' option."));
                    return std::string{};
                  }
                  return cm::CMakeString{ args.front() }.Hash(algo);
                } catch (std::exception const& e) {
                  reportError(ev, cnt->GetOriginalExpression(), e.what());
                  return std::string{};
                }
              }
              reportError(ev, cnt->GetOriginalExpression(),
                          cmStrCat(args[1], ": invalid parameter. Option '",
                                   ALGORITHM, "' expected."));
            }
            return std::string{};
          } },
        { "MAKE_C_IDENTIFIER"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckStringParameters(ev, cnt, "MAKE_C_IDENTIFIER"_s, args,
                                      1)) {
              return cm::CMakeString{ args.front() }.MakeCIdentifier();
            }
            return std::string{};
          } }
      };

    if (parameters.front().empty()) {
      reportError(eval, content->GetOriginalExpression(),
                  "$<STRING> expression requires at least one parameter.");
      return std::string{};
    }

    if (cm::contains(stringCommands, parameters.front())) {
      auto args = Arguments{ parameters }.advance(1);
      return stringCommands[parameters.front()](eval, content, args);
    }

    reportError(eval, content->GetOriginalExpression(),
                cmStrCat(parameters.front(), ": invalid option."));
    return std::string{};
  }
} stringNode;

namespace {
inline bool CheckListParametersEx(cm::GenEx::Evaluation* eval,
                                  GeneratorExpressionContent const* cnt,
                                  cm::string_view option, std::size_t count,
                                  int required = 1, bool exactly = true)
{
  return CheckGenExParameters(eval, cnt, "LIST"_s, option, count, required,
                              exactly);
}
inline bool CheckListParameters(cm::GenEx::Evaluation* eval,
                                GeneratorExpressionContent const* cnt,
                                cm::string_view option, Arguments args,
                                int required = 1)
{
  return CheckListParametersEx(eval, cnt, option, args.size(), required);
};

inline cmList GetList(std::string const& list)
{
  return list.empty() ? cmList{} : cmList{ list, cmList::EmptyElements::Yes };
}
}

static const struct ListNode : public cmGeneratorExpressionNode
{
  ListNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return TwoOrMoreParameters; }

  bool AcceptsArbitraryContentParameter() const override { return true; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    static std::unordered_map<
      cm::string_view,
      std::function<std::string(cm::GenEx::Evaluation*,
                                GeneratorExpressionContent const*,
                                Arguments&)>>
      listCommands{
        { "LENGTH"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckListParameters(ev, cnt, "LENGTH"_s, args)) {
              return std::to_string(GetList(args.front()).size());
            }
            return std::string{};
          } },
        { "GET"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckListParametersEx(ev, cnt, "GET"_s, args.size(), 2,
                                      false)) {
              auto list = GetList(args.front());
              if (list.empty()) {
                reportError(ev, cnt->GetOriginalExpression(),
                            "given empty list");
                return std::string{};
              }

              std::vector<cmList::index_type> indexes;
              if (!GetNumericArguments(ev, cnt, args.advance(1), indexes,
                                       cmList::ExpandElements::Yes)) {
                return std::string{};
              }
              try {
                return list.get_items(indexes.begin(), indexes.end())
                  .to_string();
              } catch (std::out_of_range& e) {
                reportError(ev, cnt->GetOriginalExpression(), e.what());
                return std::string{};
              }
            }
            return std::string{};
          } },
        { "JOIN"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckListParameters(ev, cnt, "JOIN"_s, args, 2)) {
              return GetList(args.front()).join(args[1]);
            }
            return std::string{};
          } },
        { "SUBLIST"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckListParameters(ev, cnt, "SUBLIST"_s, args, 3)) {
              auto list = GetList(args.front());
              if (!list.empty()) {
                std::vector<cmList::index_type> indexes;
                if (!GetNumericArguments(ev, cnt, args.advance(1), indexes)) {
                  return std::string{};
                }
                if (indexes[0] < 0) {
                  reportError(ev, cnt->GetOriginalExpression(),
                              cmStrCat("begin index: ", indexes[0],
                                       " is out of range 0 - ",
                                       list.size() - 1));
                  return std::string{};
                }
                if (indexes[1] < -1) {
                  reportError(ev, cnt->GetOriginalExpression(),
                              cmStrCat("length: ", indexes[1],
                                       " should be -1 or greater"));
                  return std::string{};
                }
                try {
                  return list
                    .sublist(static_cast<cmList::size_type>(indexes[0]),
                             static_cast<cmList::size_type>(indexes[1]))
                    .to_string();
                } catch (std::out_of_range& e) {
                  reportError(ev, cnt->GetOriginalExpression(), e.what());
                  return std::string{};
                }
              }
            }
            return std::string{};
          } },
        { "FIND"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckListParameters(ev, cnt, "FIND"_s, args, 2)) {
              auto list = GetList(args.front());
              auto index = list.find(args[1]);
              return index == cmList::npos ? "-1" : std::to_string(index);
            }
            return std::string{};
          } },
        { "APPEND"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckListParametersEx(ev, cnt, "APPEND"_s, args.size(), 2,
                                      false)) {
              auto list = args.front();
              args.advance(1);
              return cmList::append(list, args.begin(), args.end());
            }
            return std::string{};
          } },
        { "PREPEND"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckListParametersEx(ev, cnt, "PREPEND"_s, args.size(), 2,
                                      false)) {
              auto list = args.front();
              args.advance(1);
              return cmList::prepend(list, args.begin(), args.end());
            }
            return std::string{};
          } },
        { "INSERT"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckListParametersEx(ev, cnt, "INSERT"_s, args.size(), 3,
                                      false)) {
              cmList::index_type index;
              if (!GetNumericArgument(args[1], index)) {
                reportError(
                  ev, cnt->GetOriginalExpression(),
                  cmStrCat("index: \"", args[1], "\" is not a valid index"));
                return std::string{};
              }
              try {
                auto list = GetList(args.front());
                args.advance(2);
                list.insert_items(index, args.begin(), args.end(),
                                  cmList::ExpandElements::No,
                                  cmList::EmptyElements::Yes);
                return list.to_string();
              } catch (std::out_of_range& e) {
                reportError(ev, cnt->GetOriginalExpression(), e.what());
                return std::string{};
              }
            }
            return std::string{};
          } },
        { "POP_BACK"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckListParameters(ev, cnt, "POP_BACK"_s, args)) {
              auto list = GetList(args.front());
              if (!list.empty()) {
                list.pop_back();
                return list.to_string();
              }
            }
            return std::string{};
          } },
        { "POP_FRONT"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckListParameters(ev, cnt, "POP_FRONT"_s, args)) {
              auto list = GetList(args.front());
              if (!list.empty()) {
                list.pop_front();
                return list.to_string();
              }
            }
            return std::string{};
          } },
        { "REMOVE_DUPLICATES"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckListParameters(ev, cnt, "REMOVE_DUPLICATES"_s, args)) {
              return GetList(args.front()).remove_duplicates().to_string();
            }
            return std::string{};
          } },
        { "REMOVE_ITEM"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckListParametersEx(ev, cnt, "REMOVE_ITEM"_s, args.size(), 2,
                                      false)) {
              auto list = GetList(args.front());
              args.advance(1);
              cmList items{ args.begin(), args.end(),
                            cmList::ExpandElements::Yes };
              return list.remove_items(items.begin(), items.end()).to_string();
            }
            return std::string{};
          } },
        { "REMOVE_AT"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckListParametersEx(ev, cnt, "REMOVE_AT"_s, args.size(), 2,
                                      false)) {
              auto list = GetList(args.front());
              std::vector<cmList::index_type> indexes;
              if (!GetNumericArguments(ev, cnt, args.advance(1), indexes,
                                       cmList::ExpandElements::Yes)) {
                return std::string{};
              }
              try {
                return list.remove_items(indexes.begin(), indexes.end())
                  .to_string();
              } catch (std::out_of_range& e) {
                reportError(ev, cnt->GetOriginalExpression(), e.what());
                return std::string{};
              }
            }
            return std::string{};
          } },
        { "FILTER"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckListParameters(ev, cnt, "FILTER"_s, args, 3)) {
              auto const& op = args[1];
              if (op != "INCLUDE"_s && op != "EXCLUDE"_s) {
                reportError(
                  ev, cnt->GetOriginalExpression(),
                  cmStrCat("sub-command FILTER does not recognize operator \"",
                           op, "\". It must be either INCLUDE or EXCLUDE."));
                return std::string{};
              }
              try {
                return GetList(args.front())
                  .filter(args[2],
                          op == "INCLUDE"_s ? cmList::FilterMode::INCLUDE
                                            : cmList::FilterMode::EXCLUDE)
                  .to_string();
              } catch (std::invalid_argument&) {
                reportError(
                  ev, cnt->GetOriginalExpression(),
                  cmStrCat("sub-command FILTER, failed to compile regex \"",
                           args[2], "\"."));
                return std::string{};
              }
            }
            return std::string{};
          } },
        { "TRANSFORM"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckListParametersEx(ev, cnt, "TRANSFORM"_s, args.size(), 2,
                                      false)) {
              auto list = GetList(args.front());
              if (!list.empty()) {
                struct ActionDescriptor
                {
                  ActionDescriptor(std::string name)
                    : Name(std::move(name))
                  {
                  }
                  ActionDescriptor(std::string name,
                                   cmList::TransformAction action, int arity)
                    : Name(std::move(name))
                    , Action(action)
                    , Arity(arity)
                  {
                  }

                  operator std::string const&() const { return this->Name; }

                  std::string Name;
                  cmList::TransformAction Action;
                  int Arity = 0;
                };

                static std::set<
                  ActionDescriptor,
                  std::function<bool(std::string const&, std::string const&)>>
                  descriptors{
                    { { "APPEND", cmList::TransformAction::APPEND, 1 },
                      { "PREPEND", cmList::TransformAction::PREPEND, 1 },
                      { "TOUPPER", cmList::TransformAction::TOUPPER, 0 },
                      { "TOLOWER", cmList::TransformAction::TOLOWER, 0 },
                      { "STRIP", cmList::TransformAction::STRIP, 0 },
                      { "REPLACE", cmList::TransformAction::REPLACE, 2 } },
                    [](std::string const& x, std::string const& y) {
                      return x < y;
                    }
                  };

                auto descriptor = descriptors.find(args.advance(1).front());
                if (descriptor == descriptors.end()) {
                  reportError(ev, cnt->GetOriginalExpression(),
                              cmStrCat(" sub-command TRANSFORM, ",
                                       args.front(), " invalid action."));
                  return std::string{};
                }

                // Action arguments
                args.advance(1);
                if (args.size() < descriptor->Arity) {
                  reportError(ev, cnt->GetOriginalExpression(),
                              cmStrCat("sub-command TRANSFORM, action ",
                                       descriptor->Name, " expects ",
                                       descriptor->Arity, " argument(s)."));
                  return std::string{};
                }
                std::vector<std::string> arguments;
                if (descriptor->Arity > 0) {
                  arguments = std::vector<std::string>(
                    args.begin(), args.begin() + descriptor->Arity);
                  args.advance(descriptor->Arity);
                }

                std::string const REGEX{ "REGEX" };
                std::string const AT{ "AT" };
                std::string const FOR{ "FOR" };
                std::unique_ptr<cmList::TransformSelector> selector;

                try {
                  // handle optional arguments
                  while (!args.empty()) {
                    if ((args.front() == REGEX || args.front() == AT ||
                         args.front() == FOR) &&
                        selector) {
                      reportError(ev, cnt->GetOriginalExpression(),
                                  cmStrCat("sub-command TRANSFORM, selector "
                                           "already specified (",
                                           selector->GetTag(), ")."));

                      return std::string{};
                    }

                    // REGEX selector
                    if (args.front() == REGEX) {
                      if (args.advance(1).empty()) {
                        reportError(
                          ev, cnt->GetOriginalExpression(),
                          "sub-command TRANSFORM, selector REGEX expects "
                          "'regular expression' argument.");
                        return std::string{};
                      }

                      selector = cmList::TransformSelector::New<
                        cmList::TransformSelector::REGEX>(args.front());

                      args.advance(1);
                      continue;
                    }

                    // AT selector
                    if (args.front() == AT) {
                      args.advance(1);
                      // get all specified indexes
                      std::vector<cmList::index_type> indexes;
                      while (!args.empty()) {
                        cmList indexList{ args.front() };
                        for (auto const& index : indexList) {
                          cmList::index_type value;

                          if (!GetNumericArgument(index, value)) {
                            // this is not a number, stop processing
                            reportError(
                              ev, cnt->GetOriginalExpression(),
                              cmStrCat("sub-command TRANSFORM, selector AT: '",
                                       index, "': unexpected argument."));
                            return std::string{};
                          }
                          indexes.push_back(value);
                        }
                        args.advance(1);
                      }

                      if (indexes.empty()) {
                        reportError(ev, cnt->GetOriginalExpression(),
                                    "sub-command TRANSFORM, selector AT "
                                    "expects at least one "
                                    "numeric value.");
                        return std::string{};
                      }

                      selector = cmList::TransformSelector::New<
                        cmList::TransformSelector::AT>(std::move(indexes));

                      continue;
                    }

                    // FOR selector
                    if (args.front() == FOR) {
                      if (args.advance(1).size() < 2) {
                        reportError(ev, cnt->GetOriginalExpression(),
                                    "sub-command TRANSFORM, selector FOR "
                                    "expects, at least,"
                                    " two arguments.");
                        return std::string{};
                      }

                      cmList::index_type start = 0;
                      cmList::index_type stop = 0;
                      cmList::index_type step = 1;
                      bool valid = false;

                      if (GetNumericArgument(args.front(), start) &&
                          GetNumericArgument(args.advance(1).front(), stop)) {
                        valid = true;
                      }

                      if (!valid) {
                        reportError(
                          ev, cnt->GetOriginalExpression(),
                          "sub-command TRANSFORM, selector FOR expects, "
                          "at least, two numeric values.");
                        return std::string{};
                      }
                      // try to read a third numeric value for step
                      if (!args.advance(1).empty()) {
                        if (!GetNumericArgument(args.front(), step)) {
                          // this is not a number
                          step = -1;
                        }
                        args.advance(1);
                      }

                      if (step <= 0) {
                        reportError(
                          ev, cnt->GetOriginalExpression(),
                          "sub-command TRANSFORM, selector FOR expects "
                          "positive numeric value for <step>.");
                        return std::string{};
                      }

                      selector = cmList::TransformSelector::New<
                        cmList::TransformSelector::FOR>({ start, stop, step });
                      continue;
                    }

                    reportError(ev, cnt->GetOriginalExpression(),
                                cmStrCat("sub-command TRANSFORM, '",
                                         cmJoin(args, ", "),
                                         "': unexpected argument(s)."));
                    return std::string{};
                  }

                  if (!selector) {
                    selector = cmList::TransformSelector::New();
                  }
                  selector->Makefile = ev->Context.LG->GetMakefile();

                  return list
                    .transform(descriptor->Action, arguments,
                               std::move(selector))
                    .to_string();
                } catch (cmList::transform_error& e) {
                  reportError(ev, cnt->GetOriginalExpression(), e.what());
                  return std::string{};
                }
              }
            }
            return std::string{};
          } },
        { "REVERSE"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckListParameters(ev, cnt, "REVERSE"_s, args)) {
              return GetList(args.front()).reverse().to_string();
            }
            return std::string{};
          } },
        { "SORT"_s,
          [](cm::GenEx::Evaluation* ev, GeneratorExpressionContent const* cnt,
             Arguments& args) -> std::string {
            if (CheckListParametersEx(ev, cnt, "SORT"_s, args.size(), 1,
                                      false)) {
              auto list = GetList(args.front());
              args.advance(1);
              auto const COMPARE = "COMPARE:"_s;
              auto const CASE = "CASE:"_s;
              auto const ORDER = "ORDER:"_s;
              using SortConfig = cmList::SortConfiguration;
              SortConfig sortConfig;
              for (auto const& arg : args) {
                if (cmHasPrefix(arg, COMPARE)) {
                  if (sortConfig.Compare !=
                      SortConfig::CompareMethod::DEFAULT) {
                    reportError(ev, cnt->GetOriginalExpression(),
                                "sub-command SORT, COMPARE option has been "
                                "specified multiple times.");
                    return std::string{};
                  }
                  auto option =
                    cm::string_view{ arg.c_str() + COMPARE.length() };
                  if (option == "STRING"_s) {
                    sortConfig.Compare = SortConfig::CompareMethod::STRING;
                    continue;
                  }
                  if (option == "FILE_BASENAME"_s) {
                    sortConfig.Compare =
                      SortConfig::CompareMethod::FILE_BASENAME;
                    continue;
                  }
                  if (option == "NATURAL"_s) {
                    sortConfig.Compare = SortConfig::CompareMethod::NATURAL;
                    continue;
                  }
                  reportError(
                    ev, cnt->GetOriginalExpression(),
                    cmStrCat(
                      "sub-command SORT, an invalid COMPARE option has been "
                      "specified: \"",
                      option, "\"."));
                  return std::string{};
                }
                if (cmHasPrefix(arg, CASE)) {
                  if (sortConfig.Case !=
                      SortConfig::CaseSensitivity::DEFAULT) {
                    reportError(ev, cnt->GetOriginalExpression(),
                                "sub-command SORT, CASE option has been "
                                "specified multiple times.");
                    return std::string{};
                  }
                  auto option = cm::string_view{ arg.c_str() + CASE.length() };
                  if (option == "SENSITIVE"_s) {
                    sortConfig.Case = SortConfig::CaseSensitivity::SENSITIVE;
                    continue;
                  }
                  if (option == "INSENSITIVE"_s) {
                    sortConfig.Case = SortConfig::CaseSensitivity::INSENSITIVE;
                    continue;
                  }
                  reportError(
                    ev, cnt->GetOriginalExpression(),
                    cmStrCat(
                      "sub-command SORT, an invalid CASE option has been "
                      "specified: \"",
                      option, "\"."));
                  return std::string{};
                }
                if (cmHasPrefix(arg, ORDER)) {
                  if (sortConfig.Order != SortConfig::OrderMode::DEFAULT) {
                    reportError(ev, cnt->GetOriginalExpression(),
                                "sub-command SORT, ORDER option has been "
                                "specified multiple times.");
                    return std::string{};
                  }
                  auto option =
                    cm::string_view{ arg.c_str() + ORDER.length() };
                  if (option == "ASCENDING"_s) {
                    sortConfig.Order = SortConfig::OrderMode::ASCENDING;
                    continue;
                  }
                  if (option == "DESCENDING"_s) {
                    sortConfig.Order = SortConfig::OrderMode::DESCENDING;
                    continue;
                  }
                  reportError(
                    ev, cnt->GetOriginalExpression(),
                    cmStrCat(
                      "sub-command SORT, an invalid ORDER option has been "
                      "specified: \"",
                      option, "\"."));
                  return std::string{};
                }
                reportError(ev, cnt->GetOriginalExpression(),
                            cmStrCat("sub-command SORT, option \"", arg,
                                     "\" is invalid."));
                return std::string{};
              }

              return list.sort(sortConfig).to_string();
            }
            return std::string{};
          } }
      };

    if (cm::contains(listCommands, parameters.front())) {
      auto args = Arguments{ parameters }.advance(1);
      return listCommands[parameters.front()](eval, content, args);
    }

    reportError(eval, content->GetOriginalExpression(),
                cmStrCat(parameters.front(), ": invalid option."));
    return std::string{};
  }
} listNode;

static const struct MakeCIdentifierNode : public cmGeneratorExpressionNode
{
  MakeCIdentifierNode() {} // NOLINT(modernize-use-equals-default)

  bool AcceptsArbitraryContentParameter() const override { return true; }

  std::string Evaluate(
    std::vector<std::string> const& parameters,
    cm::GenEx::Evaluation* /*eval*/,
    GeneratorExpressionContent const* /*content*/,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    return cmSystemTools::MakeCidentifier(parameters.front());
  }
} makeCIdentifierNode;

template <char C>
struct CharacterNode : public cmGeneratorExpressionNode
{
  CharacterNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 0; }

  std::string Evaluate(
    std::vector<std::string> const& /*parameters*/,
    cm::GenEx::Evaluation* /*eval*/,
    GeneratorExpressionContent const* /*content*/,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    return { C };
  }
};
static CharacterNode<'>'> const angle_rNode;
static CharacterNode<','> const commaNode;
static CharacterNode<';'> const semicolonNode;
static CharacterNode<'"'> const quoteNode;

struct CompilerIdNode : public cmGeneratorExpressionNode
{
  CompilerIdNode(char const* compilerLang)
    : CompilerLanguage(compilerLang)
  {
  }

  int NumExpectedParameters() const override { return ZeroOrMoreParameters; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagChecker) const override
  {
    if (!eval->HeadTarget) {
      std::ostringstream e;
      e << "$<" << this->CompilerLanguage
        << "_COMPILER_ID> may only be used with binary targets.  It may "
           "not be used with add_custom_command or add_custom_target.";
      reportError(eval, content->GetOriginalExpression(), e.str());
      return {};
    }
    return this->EvaluateWithLanguage(parameters, eval, content, dagChecker,
                                      this->CompilerLanguage);
  }

  std::string EvaluateWithLanguage(std::vector<std::string> const& parameters,
                                   cm::GenEx::Evaluation* eval,
                                   GeneratorExpressionContent const* content,
                                   cmGeneratorExpressionDAGChecker* /*unused*/,
                                   std::string const& lang) const
  {
    std::string const& compilerId =
      eval->Context.LG->GetMakefile()->GetSafeDefinition("CMAKE_" + lang +
                                                         "_COMPILER_ID");
    if (parameters.empty()) {
      return compilerId;
    }
    if (compilerId.empty()) {
      return parameters.front().empty() ? "1" : "0";
    }
    static cmsys::RegularExpression compilerIdValidator("^[A-Za-z0-9_]*$");

    for (auto const& param : parameters) {
      if (!compilerIdValidator.find(param)) {
        reportError(eval, content->GetOriginalExpression(),
                    "Expression syntax not recognized.");
        return std::string();
      }

      if (strcmp(param.c_str(), compilerId.c_str()) == 0) {
        return "1";
      }
    }
    return "0";
  }

  char const* const CompilerLanguage;
};

static CompilerIdNode const cCompilerIdNode("C"), cxxCompilerIdNode("CXX"),
  cudaCompilerIdNode("CUDA"), objcCompilerIdNode("OBJC"),
  objcxxCompilerIdNode("OBJCXX"), fortranCompilerIdNode("Fortran"),
  hipCompilerIdNode("HIP"), ispcCompilerIdNode("ISPC");

struct CompilerVersionNode : public cmGeneratorExpressionNode
{
  CompilerVersionNode(char const* compilerLang)
    : CompilerLanguage(compilerLang)
  {
  }

  int NumExpectedParameters() const override { return OneOrZeroParameters; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagChecker) const override
  {
    if (!eval->HeadTarget) {
      std::ostringstream e;
      e << "$<" << this->CompilerLanguage
        << "_COMPILER_VERSION> may only be used with binary targets.  It "
           "may not be used with add_custom_command or add_custom_target.";
      reportError(eval, content->GetOriginalExpression(), e.str());
      return {};
    }
    return this->EvaluateWithLanguage(parameters, eval, content, dagChecker,
                                      this->CompilerLanguage);
  }

  std::string EvaluateWithLanguage(std::vector<std::string> const& parameters,
                                   cm::GenEx::Evaluation* eval,
                                   GeneratorExpressionContent const* content,
                                   cmGeneratorExpressionDAGChecker* /*unused*/,
                                   std::string const& lang) const
  {
    std::string const& compilerVersion =
      eval->Context.LG->GetMakefile()->GetSafeDefinition("CMAKE_" + lang +
                                                         "_COMPILER_VERSION");
    if (parameters.empty()) {
      return compilerVersion;
    }

    static cmsys::RegularExpression compilerIdValidator("^[0-9\\.]*$");
    if (!compilerIdValidator.find(parameters.front())) {
      reportError(eval, content->GetOriginalExpression(),
                  "Expression syntax not recognized.");
      return {};
    }
    if (compilerVersion.empty()) {
      return parameters.front().empty() ? "1" : "0";
    }

    return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL,
                                         parameters.front(), compilerVersion)
      ? "1"
      : "0";
  }

  char const* const CompilerLanguage;
};

static CompilerVersionNode const cCompilerVersionNode("C"),
  cxxCompilerVersionNode("CXX"), cudaCompilerVersionNode("CUDA"),
  objcCompilerVersionNode("OBJC"), objcxxCompilerVersionNode("OBJCXX"),
  fortranCompilerVersionNode("Fortran"), ispcCompilerVersionNode("ISPC"),
  hipCompilerVersionNode("HIP");

struct CompilerFrontendVariantNode : public cmGeneratorExpressionNode
{
  CompilerFrontendVariantNode(char const* compilerLang)
    : CompilerLanguage(compilerLang)
  {
  }

  int NumExpectedParameters() const override { return ZeroOrMoreParameters; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagChecker) const override
  {
    if (!eval->HeadTarget) {
      std::ostringstream e;
      e << "$<" << this->CompilerLanguage
        << "_COMPILER_FRONTEND_VARIANT> may only be used with binary targets. "
           " It may not be used with add_custom_command or add_custom_target.";
      reportError(eval, content->GetOriginalExpression(), e.str());
      return {};
    }
    return this->EvaluateWithLanguage(parameters, eval, content, dagChecker,
                                      this->CompilerLanguage);
  }

  std::string EvaluateWithLanguage(std::vector<std::string> const& parameters,
                                   cm::GenEx::Evaluation* eval,
                                   GeneratorExpressionContent const* content,
                                   cmGeneratorExpressionDAGChecker* /*unused*/,
                                   std::string const& lang) const
  {
    std::string const& compilerFrontendVariant =
      eval->Context.LG->GetMakefile()->GetSafeDefinition(
        "CMAKE_" + lang + "_COMPILER_FRONTEND_VARIANT");
    if (parameters.empty()) {
      return compilerFrontendVariant;
    }
    if (compilerFrontendVariant.empty()) {
      return parameters.front().empty() ? "1" : "0";
    }
    static cmsys::RegularExpression compilerFrontendVariantValidator(
      "^[A-Za-z0-9_]*$");

    for (auto const& param : parameters) {
      if (!compilerFrontendVariantValidator.find(param)) {
        reportError(eval, content->GetOriginalExpression(),
                    "Expression syntax not recognized.");
        return {};
      }
      if (strcmp(param.c_str(), compilerFrontendVariant.c_str()) == 0) {
        return "1";
      }
    }
    return "0";
  }

  char const* const CompilerLanguage;
};

static CompilerFrontendVariantNode const cCompilerFrontendVariantNode("C"),
  cxxCompilerFrontendVariantNode("CXX"),
  cudaCompilerFrontendVariantNode("CUDA"),
  objcCompilerFrontendVariantNode("OBJC"),
  objcxxCompilerFrontendVariantNode("OBJCXX"),
  fortranCompilerFrontendVariantNode("Fortran"),
  hipCompilerFrontendVariantNode("HIP"),
  ispcCompilerFrontendVariantNode("ISPC");

struct PlatformIdNode : public cmGeneratorExpressionNode
{
  PlatformIdNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return ZeroOrMoreParameters; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* /*content*/,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    std::string const& platformId =
      eval->Context.LG->GetMakefile()->GetSafeDefinition("CMAKE_SYSTEM_NAME");
    if (parameters.empty()) {
      return platformId;
    }

    if (platformId.empty()) {
      return parameters.front().empty() ? "1" : "0";
    }

    for (auto const& param : parameters) {
      if (param == platformId) {
        return "1";
      }
    }
    return "0";
  }
};
static struct PlatformIdNode platformIdNode;

template <cmSystemTools::CompareOp Op>
struct VersionNode : public cmGeneratorExpressionNode
{
  VersionNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 2; }

  std::string Evaluate(
    std::vector<std::string> const& parameters,
    cm::GenEx::Evaluation* /*eval*/,
    GeneratorExpressionContent const* /*content*/,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    return cmSystemTools::VersionCompare(Op, parameters.front(), parameters[1])
      ? "1"
      : "0";
  }
};

static VersionNode<cmSystemTools::OP_GREATER> const versionGreaterNode;
static VersionNode<cmSystemTools::OP_GREATER_EQUAL> const versionGreaterEqNode;
static VersionNode<cmSystemTools::OP_LESS> const versionLessNode;
static VersionNode<cmSystemTools::OP_LESS_EQUAL> const versionLessEqNode;
static VersionNode<cmSystemTools::OP_EQUAL> const versionEqualNode;

static const struct CompileOnlyNode : public cmGeneratorExpressionNode
{
  CompileOnlyNode() {} // NOLINT(modernize-use-equals-default)

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagChecker) const override
  {
    if (!dagChecker) {
      reportError(eval, content->GetOriginalExpression(),
                  "$<COMPILE_ONLY:...> may only be used for linking");
      return std::string();
    }
    if (dagChecker->GetTransitivePropertiesOnly()) {
      return parameters.front();
    }
    return std::string{};
  }
} compileOnlyNode;

static const struct LinkOnlyNode : public cmGeneratorExpressionNode
{
  LinkOnlyNode() {} // NOLINT(modernize-use-equals-default)

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagChecker) const override
  {
    if (!dagChecker) {
      reportError(eval, content->GetOriginalExpression(),
                  "$<LINK_ONLY:...> may only be used for linking");
      return std::string();
    }
    if (!dagChecker->GetTransitivePropertiesOnlyCMP0131()) {
      return parameters.front();
    }
    return std::string();
  }
} linkOnlyNode;

static const struct ConfigurationNode : public cmGeneratorExpressionNode
{
  ConfigurationNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 0; }

  std::string Evaluate(
    std::vector<std::string> const& /*parameters*/,
    cm::GenEx::Evaluation* eval, GeneratorExpressionContent const* /*content*/,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    eval->HadContextSensitiveCondition = true;
    return eval->Context.Config;
  }
} configurationNode;

static const struct ConfigurationTestNode : public cmGeneratorExpressionNode
{
  ConfigurationTestNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return ZeroOrMoreParameters; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    if (parameters.empty()) {
      return configurationNode.Evaluate(parameters, eval, content, nullptr);
    }

    eval->HadContextSensitiveCondition = true;

    // First, validate our arguments.
    static cmsys::RegularExpression configValidator("^[A-Za-z0-9_]*$");
    bool firstParam = true;
    for (auto const& param : parameters) {
      if (!configValidator.find(param)) {
        if (firstParam) {
          reportError(eval, content->GetOriginalExpression(),
                      "Expression syntax not recognized.");
          return std::string();
        }
        // for backwards compat invalid config names are only errors as
        // the first parameter
        std::ostringstream e;
        /* clang-format off */
        e << "Warning evaluating generator expression:\n"
          << "  " << content->GetOriginalExpression() << "\n"
          << "The config name of \"" << param << "\" is invalid";
        /* clang-format on */
        eval->Context.LG->GetCMakeInstance()->IssueMessage(
          MessageType::WARNING, e.str(), eval->Backtrace);
      }
      firstParam = false;
    }

    // Determine the context(s) in which the expression should be evaluated. If
    // CMPxxxx is NEW, the context is exactly one of the imported target's
    // selected configuration, if applicable, or the consuming target's
    // configuration, otherwise.
    //
    // If CMPxxxx is OLD, we evaluate first in the context of the consuming
    // target, then, if the consumed target is imported, we evaluate based on
    // the mapped configurations (this logic is... problematic; see comment
    // below), then finally based on the selected configuration of the imported
    // target.
    bool const targetIsImported =
      (eval->CurrentTarget && eval->CurrentTarget->IsImported());
    bool const oldPolicy = [&] {
      if (!targetIsImported) {
        // For non-imported targets, there is no behavior difference between
        // the OLD and NEW policy.
        return false;
      }
      cmTarget const* const t = eval->CurrentTarget->Target;
      if (t->GetOrigin() == cmTarget::Origin::Cps) {
        // Generator expressions appearing on targets imported from CPS should
        // always be evaluated according to the selected configuration of the
        // imported target, i.e. the NEW policy.
        return false;
      }
      switch (eval->HeadTarget->GetPolicyStatusCMP0199()) {
        case cmPolicies::WARN:
          if (eval->Context.LG->GetMakefile()->PolicyOptionalWarningEnabled(
                "CMAKE_POLICY_WARNING_CMP0199")) {
            std::string const err =
              cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0199),
                       "\nEvaluation of $<CONFIG> for imported target  \"",
                       eval->CurrentTarget->GetName(), "\", used by \"",
                       eval->HeadTarget->GetName(),
                       "\", may match multiple configurations.\n");
            eval->Context.LG->GetCMakeInstance()->IssueMessage(
              MessageType ::AUTHOR_WARNING, err, eval->Backtrace);
          }
          CM_FALLTHROUGH;
        case cmPolicies::OLD:
          return true;
        case cmPolicies::NEW:
          return false;
      }

      // Should be unreachable
      assert(false);
      return false;
    }();

    if (!targetIsImported || oldPolicy) {
      // Does the consuming target's configuration match any of the arguments?
      for (auto const& param : parameters) {
        if (eval->Context.Config.empty()) {
          if (param.empty()) {
            return "1";
          }
        } else if (cmsysString_strcasecmp(param.c_str(),
                                          eval->Context.Config.c_str()) == 0) {
          return "1";
        }
      }
    }

    if (targetIsImported) {
      cmValue loc = nullptr;
      cmValue imp = nullptr;
      std::string suffix;
      if (eval->CurrentTarget->Target->GetMappedConfig(eval->Context.Config,
                                                       loc, imp, suffix)) {
        if (oldPolicy) {
          // If the target has a MAP_IMPORTED_CONFIG_<CONFIG> property for the
          // consumer's <CONFIG>, match *any* config in that list, regardless
          // of whether it's valid or of what GetMappedConfig actually picked.
          // This will result in $<CONFIG> producing '1' for multiple configs,
          // and is almost certainly wrong, but it's what CMake did for a very
          // long time, and... Hyrum's Law.
          cmList mappedConfigs;
          std::string mapProp =
            cmStrCat("MAP_IMPORTED_CONFIG_",
                     cmSystemTools::UpperCase(eval->Context.Config));
          if (cmValue mapValue = eval->CurrentTarget->GetProperty(mapProp)) {
            mappedConfigs.assign(cmSystemTools::UpperCase(*mapValue));

            for (auto const& param : parameters) {
              if (cm::contains(mappedConfigs,
                               cmSystemTools::UpperCase(param))) {
                return "1";
              }
            }

            return "0";
          }
        }

        // This imported target has an appropriate location for this (possibly
        // mapped) config.
        if (!suffix.empty()) {
          // Use the (possibly mapped) configuration of the imported location
          // that was selected.
          for (auto const& param : parameters) {
            if (cmStrCat('_', cmSystemTools::UpperCase(param)) == suffix) {
              return "1";
            }
          }
        }
      }
    }

    return "0";
  }
} configurationTestNode;

static const struct JoinNode : public cmGeneratorExpressionNode
{
  JoinNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 2; }

  bool AcceptsArbitraryContentParameter() const override { return true; }

  std::string Evaluate(
    std::vector<std::string> const& parameters,
    cm::GenEx::Evaluation* /*eval*/,
    GeneratorExpressionContent const* /*content*/,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    return cmList{ parameters.front() }.join(parameters[1]);
  }
} joinNode;

static const struct CompileLanguageNode : public cmGeneratorExpressionNode
{
  CompileLanguageNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return ZeroOrMoreParameters; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagChecker) const override
  {
    if (eval->Context.Language.empty() &&
        (!dagChecker || !dagChecker->EvaluatingCompileExpression())) {
      reportError(
        eval, content->GetOriginalExpression(),
        "$<COMPILE_LANGUAGE:...> may only be used to specify include "
        "directories, compile definitions, compile options, and to evaluate "
        "components of the file(GENERATE) command.");
      return std::string();
    }

    cmGlobalGenerator const* gg = eval->Context.LG->GetGlobalGenerator();
    std::string genName = gg->GetName();
    if (genName.find("Makefiles") == std::string::npos &&
        genName.find("Ninja") == std::string::npos &&
        genName.find("Visual Studio") == std::string::npos &&
        genName.find("Xcode") == std::string::npos &&
        genName.find("Watcom WMake") == std::string::npos &&
        genName.find("FASTBuild") == std::string::npos &&
        genName.find("Green Hills MULTI") == std::string::npos) {
      reportError(eval, content->GetOriginalExpression(),
                  "$<COMPILE_LANGUAGE:...> not supported for this generator.");
      return std::string();
    }
    if (parameters.empty()) {
      return eval->Context.Language;
    }

    for (auto const& param : parameters) {
      if (eval->Context.Language == param) {
        return "1";
      }
    }
    return "0";
  }
} languageNode;

static const struct CompileLanguageAndIdNode : public cmGeneratorExpressionNode
{
  CompileLanguageAndIdNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return TwoOrMoreParameters; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagChecker) const override
  {
    if (!eval->HeadTarget ||
        (eval->Context.Language.empty() &&
         (!dagChecker || !dagChecker->EvaluatingCompileExpression()))) {
      // reportError(eval, content->GetOriginalExpression(), "");
      reportError(
        eval, content->GetOriginalExpression(),
        "$<COMPILE_LANG_AND_ID:lang,id> may only be used with binary "
        "targets "
        "to specify include directories, compile definitions, and compile "
        "options.  It may not be used with the add_custom_command, "
        "add_custom_target, or file(GENERATE) commands.");
      return std::string();
    }
    cmGlobalGenerator const* gg = eval->Context.LG->GetGlobalGenerator();
    std::string genName = gg->GetName();
    if (genName.find("Makefiles") == std::string::npos &&
        genName.find("Ninja") == std::string::npos &&
        genName.find("FASTBuild") == std::string::npos &&
        genName.find("Visual Studio") == std::string::npos &&
        genName.find("Xcode") == std::string::npos &&
        genName.find("Watcom WMake") == std::string::npos &&
        genName.find("Green Hills MULTI") == std::string::npos) {
      reportError(
        eval, content->GetOriginalExpression(),
        "$<COMPILE_LANG_AND_ID:lang,id> not supported for this generator.");
      return std::string();
    }

    std::string const& lang = eval->Context.Language;
    if (lang == parameters.front()) {
      std::vector<std::string> idParameter((parameters.cbegin() + 1),
                                           parameters.cend());
      return CompilerIdNode{ lang.c_str() }.EvaluateWithLanguage(
        idParameter, eval, content, dagChecker, lang);
    }
    return "0";
  }
} languageAndIdNode;

static const struct LinkLanguageNode : public cmGeneratorExpressionNode
{
  LinkLanguageNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return ZeroOrMoreParameters; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagChecker) const override
  {
    if (!eval->HeadTarget || !dagChecker ||
        !(dagChecker->EvaluatingLinkExpression() ||
          dagChecker->EvaluatingLinkLibraries() ||
          dagChecker->EvaluatingLinkerLauncher())) {
      reportError(eval, content->GetOriginalExpression(),
                  "$<LINK_LANGUAGE:...> may only be used with binary targets "
                  "to specify link libraries, link directories, link options "
                  "and link depends.");
      return std::string();
    }
    if (dagChecker->EvaluatingLinkLibraries() && parameters.empty()) {
      reportError(
        eval, content->GetOriginalExpression(),
        "$<LINK_LANGUAGE> is not supported in link libraries expression.");
      return std::string();
    }

    cmGlobalGenerator const* gg = eval->Context.LG->GetGlobalGenerator();
    std::string genName = gg->GetName();
    if (genName.find("Makefiles") == std::string::npos &&
        genName.find("Ninja") == std::string::npos &&
        genName.find("FASTBuild") == std::string::npos &&
        genName.find("Visual Studio") == std::string::npos &&
        genName.find("Xcode") == std::string::npos &&
        genName.find("Watcom WMake") == std::string::npos &&
        genName.find("Green Hills MULTI") == std::string::npos) {
      reportError(eval, content->GetOriginalExpression(),
                  "$<LINK_LANGUAGE:...> not supported for this generator.");
      return std::string();
    }

    if (dagChecker->EvaluatingLinkLibraries()) {
      eval->HadHeadSensitiveCondition = true;
      eval->HadLinkLanguageSensitiveCondition = true;
    }

    if (parameters.empty()) {
      return eval->Context.Language;
    }

    for (auto const& param : parameters) {
      if (eval->Context.Language == param) {
        return "1";
      }
    }
    return "0";
  }
} linkLanguageNode;

namespace {
struct LinkerId
{
  static std::string Evaluate(std::vector<std::string> const& parameters,
                              cm::GenEx::Evaluation* eval,
                              GeneratorExpressionContent const* content,
                              std::string const& lang)
  {
    std::string const& linkerId =
      eval->Context.LG->GetMakefile()->GetSafeDefinition("CMAKE_" + lang +
                                                         "_COMPILER_ID");
    if (parameters.empty()) {
      return linkerId;
    }
    if (linkerId.empty()) {
      return parameters.front().empty() ? "1" : "0";
    }
    static cmsys::RegularExpression linkerIdValidator("^[A-Za-z0-9_]*$");

    for (auto const& param : parameters) {
      if (!linkerIdValidator.find(param)) {
        reportError(eval, content->GetOriginalExpression(),
                    "Expression syntax not recognized.");
        return std::string();
      }

      if (param == linkerId) {
        return "1";
      }
    }
    return "0";
  }
};
}

static const struct LinkLanguageAndIdNode : public cmGeneratorExpressionNode
{
  LinkLanguageAndIdNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return TwoOrMoreParameters; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagChecker) const override
  {
    if (!eval->HeadTarget || !dagChecker ||
        !(dagChecker->EvaluatingLinkExpression() ||
          dagChecker->EvaluatingLinkLibraries() ||
          dagChecker->EvaluatingLinkerLauncher())) {
      reportError(
        eval, content->GetOriginalExpression(),
        "$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets "
        "to specify link libraries, link directories, link options, and "
        "link "
        "depends.");
      return std::string();
    }

    cmGlobalGenerator const* gg = eval->Context.LG->GetGlobalGenerator();
    std::string genName = gg->GetName();
    if (genName.find("Makefiles") == std::string::npos &&
        genName.find("Ninja") == std::string::npos &&
        genName.find("FASTBuild") == std::string::npos &&
        genName.find("Visual Studio") == std::string::npos &&
        genName.find("Xcode") == std::string::npos &&
        genName.find("Watcom WMake") == std::string::npos &&
        genName.find("Green Hills MULTI") == std::string::npos) {
      reportError(
        eval, content->GetOriginalExpression(),
        "$<LINK_LANG_AND_ID:lang,id> not supported for this generator.");
      return std::string();
    }

    if (dagChecker->EvaluatingLinkLibraries()) {
      eval->HadHeadSensitiveCondition = true;
      eval->HadLinkLanguageSensitiveCondition = true;
    }

    std::string const& lang = eval->Context.Language;
    if (lang == parameters.front()) {
      std::vector<std::string> idParameter((parameters.cbegin() + 1),
                                           parameters.cend());
      return LinkerId::Evaluate(idParameter, eval, content, lang);
    }
    return "0";
  }
} linkLanguageAndIdNode;

struct CompilerLinkerIdNode : public cmGeneratorExpressionNode
{
  CompilerLinkerIdNode(char const* lang)
    : Language(lang)
  {
  }

  int NumExpectedParameters() const override { return ZeroOrMoreParameters; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagChecker) const override
  {
    if (!eval->HeadTarget) {
      reportError(
        eval, content->GetOriginalExpression(),
        cmStrCat(
          "$<", this->Language,
          "_COMPILER_LINKER_ID> may only be used with binary targets. It may "
          "not be used with add_custom_command or add_custom_target."));
      return {};
    }
    return this->EvaluateWithLanguage(parameters, eval, content, dagChecker,
                                      this->Language);
  }

  std::string EvaluateWithLanguage(std::vector<std::string> const& parameters,
                                   cm::GenEx::Evaluation* eval,
                                   GeneratorExpressionContent const* content,
                                   cmGeneratorExpressionDAGChecker* /*unused*/,
                                   std::string const& lang) const
  {
    std::string const& compilerLinkerId =
      eval->Context.LG->GetMakefile()->GetSafeDefinition(
        cmStrCat("CMAKE_", lang, "_COMPILER_LINKER_ID"));
    if (parameters.empty()) {
      return compilerLinkerId;
    }
    if (compilerLinkerId.empty()) {
      return parameters.front().empty() ? "1" : "0";
    }
    static cmsys::RegularExpression compilerLinkerIdValidator(
      "^[A-Za-z0-9_]*$");

    for (auto const& param : parameters) {
      if (!compilerLinkerIdValidator.find(param)) {
        reportError(eval, content->GetOriginalExpression(),
                    "Expression syntax not recognized.");
        return std::string();
      }

      if (param == compilerLinkerId) {
        return "1";
      }
    }
    return "0";
  }

  char const* const Language;
};

static CompilerLinkerIdNode const cCompilerLinkerIdNode("C"),
  cxxCompilerLinkerIdNode("CXX"), cudaCompilerLinkerIdNode("CUDA"),
  objcCompilerLinkerIdNode("OBJC"), objcxxCompilerLinkerIdNode("OBJCXX"),
  fortranCompilerLinkerIdNode("Fortran"), hipCompilerLinkerIdNode("HIP");

struct CompilerLinkerFrontendVariantNode : public cmGeneratorExpressionNode
{
  CompilerLinkerFrontendVariantNode(char const* lang)
    : Language(lang)
  {
  }

  int NumExpectedParameters() const override { return ZeroOrMoreParameters; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagChecker) const override
  {
    if (!eval->HeadTarget) {
      reportError(
        eval, content->GetOriginalExpression(),
        cmStrCat(
          "$<", this->Language,
          "_COMPILER_LINKER_FRONTEND_VARIANT> may only be used with binary "
          "targets. It may not be used with add_custom_command or "
          "add_custom_target."));
      return {};
    }
    return this->EvaluateWithLanguage(parameters, eval, content, dagChecker,
                                      this->Language);
  }

  std::string EvaluateWithLanguage(std::vector<std::string> const& parameters,
                                   cm::GenEx::Evaluation* eval,
                                   GeneratorExpressionContent const* content,
                                   cmGeneratorExpressionDAGChecker* /*unused*/,
                                   std::string const& lang) const
  {
    std::string const& compilerLinkerFrontendVariant =
      eval->Context.LG->GetMakefile()->GetSafeDefinition(
        cmStrCat("CMAKE_", lang, "_COMPILER_LINKER_FRONTEND_VARIANT"));
    if (parameters.empty()) {
      return compilerLinkerFrontendVariant;
    }
    if (compilerLinkerFrontendVariant.empty()) {
      return parameters.front().empty() ? "1" : "0";
    }
    static cmsys::RegularExpression compilerLinkerFrontendVariantValidator(
      "^[A-Za-z0-9_]*$");

    for (auto const& param : parameters) {
      if (!compilerLinkerFrontendVariantValidator.find(param)) {
        reportError(eval, content->GetOriginalExpression(),
                    "Expression syntax not recognized.");
        return {};
      }
      if (param == compilerLinkerFrontendVariant) {
        return "1";
      }
    }
    return "0";
  }

  char const* const Language;
};

static CompilerLinkerFrontendVariantNode const
  cCompilerLinkerFrontendVariantNode("C"),
  cxxCompilerLinkerFrontendVariantNode("CXX"),
  cudaCompilerLinkerFrontendVariantNode("CUDA"),
  objcCompilerLinkerFrontendVariantNode("OBJC"),
  objcxxCompilerLinkerFrontendVariantNode("OBJCXX"),
  fortranCompilerLinkerFrontendVariantNode("Fortran"),
  hipCompilerLinkerFrontendVariantNode("HIP");

static const struct LinkLibraryNode : public cmGeneratorExpressionNode
{
  LinkLibraryNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return OneOrMoreParameters; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagChecker) const override
  {
    using ForGenex = cmGeneratorExpressionDAGChecker::ForGenex;

    if (!eval->HeadTarget || !dagChecker ||
        !dagChecker->EvaluatingLinkLibraries(nullptr,
                                             ForGenex::LINK_LIBRARY)) {
      reportError(eval, content->GetOriginalExpression(),
                  "$<LINK_LIBRARY:...> may only be used with binary targets "
                  "to specify link libraries through 'LINK_LIBRARIES', "
                  "'INTERFACE_LINK_LIBRARIES', and "
                  "'INTERFACE_LINK_LIBRARIES_DIRECT' properties.");
      return std::string();
    }

    cmList list{ parameters.begin(), parameters.end() };
    if (list.empty()) {
      reportError(
        eval, content->GetOriginalExpression(),
        "$<LINK_LIBRARY:...> expects a feature name as first argument.");
      return std::string();
    }
    if (list.size() == 1) {
      // no libraries specified, ignore this genex
      return std::string();
    }

    static cmsys::RegularExpression featureNameValidator("^[A-Za-z0-9_]+$");
    auto const& feature = list.front();
    if (!featureNameValidator.find(feature)) {
      reportError(eval, content->GetOriginalExpression(),
                  cmStrCat("The feature name '", feature,
                           "' contains invalid characters."));
      return std::string();
    }

    auto const LL_BEGIN = cmStrCat("<LINK_LIBRARY:", feature, '>');
    auto const LL_END = cmStrCat("</LINK_LIBRARY:", feature, '>');

    // filter out $<LINK_LIBRARY:..> tags with same feature
    // and raise an error for any different feature
    cm::erase_if(list, [&](std::string const& item) -> bool {
      return item == LL_BEGIN || item == LL_END;
    });
    auto it =
      std::find_if(list.cbegin() + 1, list.cend(),
                   [&feature](std::string const& item) -> bool {
                     return cmHasPrefix(item, "<LINK_LIBRARY:"_s) &&
                       item.substr(14, item.find('>', 14) - 14) != feature;
                   });
    if (it != list.cend()) {
      reportError(
        eval, content->GetOriginalExpression(),
        "$<LINK_LIBRARY:...> with different features cannot be nested.");
      return std::string();
    }
    // $<LINK_GROUP:...> must not appear as part of $<LINK_LIBRARY:...>
    it = std::find_if(list.cbegin() + 1, list.cend(),
                      [](std::string const& item) -> bool {
                        return cmHasPrefix(item, "<LINK_GROUP:"_s);
                      });
    if (it != list.cend()) {
      reportError(eval, content->GetOriginalExpression(),
                  "$<LINK_GROUP:...> cannot be nested inside a "
                  "$<LINK_LIBRARY:...> expression.");
      return std::string();
    }

    list.front() = LL_BEGIN;
    list.push_back(LL_END);

    return list.to_string();
  }
} linkLibraryNode;

static const struct LinkGroupNode : public cmGeneratorExpressionNode
{
  LinkGroupNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return OneOrMoreParameters; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagChecker) const override
  {
    using ForGenex = cmGeneratorExpressionDAGChecker::ForGenex;

    if (!eval->HeadTarget || !dagChecker ||
        !dagChecker->EvaluatingLinkLibraries(nullptr, ForGenex::LINK_GROUP)) {
      reportError(
        eval, content->GetOriginalExpression(),
        "$<LINK_GROUP:...> may only be used with binary targets "
        "to specify group of link libraries through 'LINK_LIBRARIES', "
        "'INTERFACE_LINK_LIBRARIES', and "
        "'INTERFACE_LINK_LIBRARIES_DIRECT' properties.");
      return std::string();
    }

    cmList list{ parameters.begin(), parameters.end() };
    if (list.empty()) {
      reportError(
        eval, content->GetOriginalExpression(),
        "$<LINK_GROUP:...> expects a feature name as first argument.");
      return std::string();
    }
    // $<LINK_GROUP:..> cannot be nested
    if (std::find_if(list.cbegin(), list.cend(),
                     [](std::string const& item) -> bool {
                       return cmHasPrefix(item, "<LINK_GROUP"_s);
                     }) != list.cend()) {
      reportError(eval, content->GetOriginalExpression(),
                  "$<LINK_GROUP:...> cannot be nested.");
      return std::string();
    }
    if (list.size() == 1) {
      // no libraries specified, ignore this genex
      return std::string();
    }

    static cmsys::RegularExpression featureNameValidator("^[A-Za-z0-9_]+$");
    auto const& feature = list.front();
    if (!featureNameValidator.find(feature)) {
      reportError(eval, content->GetOriginalExpression(),
                  cmStrCat("The feature name '", feature,
                           "' contains invalid characters."));
      return std::string();
    }

    auto const LG_BEGIN = cmStrCat(
      "<LINK_GROUP:", feature, ':',
      cmJoin(cmRange<decltype(list.cbegin())>(list.cbegin() + 1, list.cend()),
             "|"_s),
      '>');
    auto const LG_END = cmStrCat("</LINK_GROUP:", feature, '>');

    list.front() = LG_BEGIN;
    list.push_back(LG_END);

    return list.to_string();
  }
} linkGroupNode;

static const struct HostLinkNode : public cmGeneratorExpressionNode
{
  HostLinkNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return ZeroOrMoreParameters; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagChecker) const override
  {
    if (!eval->HeadTarget || !dagChecker ||
        !dagChecker->EvaluatingLinkOptionsExpression()) {
      reportError(eval, content->GetOriginalExpression(),
                  "$<HOST_LINK:...> may only be used with binary targets "
                  "to specify link options.");
      return std::string();
    }

    return eval->HeadTarget->IsDeviceLink() ? std::string()
                                            : cmList::to_string(parameters);
  }
} hostLinkNode;

static const struct DeviceLinkNode : public cmGeneratorExpressionNode
{
  DeviceLinkNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return ZeroOrMoreParameters; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagChecker) const override
  {
    if (!eval->HeadTarget || !dagChecker ||
        !dagChecker->EvaluatingLinkOptionsExpression()) {
      reportError(eval, content->GetOriginalExpression(),
                  "$<DEVICE_LINK:...> may only be used with binary targets "
                  "to specify link options.");
      return std::string();
    }

    if (eval->HeadTarget->IsDeviceLink()) {
      cmList list{ parameters.begin(), parameters.end() };
      auto const DL_BEGIN = "<DEVICE_LINK>"_s;
      auto const DL_END = "</DEVICE_LINK>"_s;
      cm::erase_if(list, [&](std::string const& item) {
        return item == DL_BEGIN || item == DL_END;
      });

      list.insert(list.begin(), static_cast<std::string>(DL_BEGIN));
      list.push_back(static_cast<std::string>(DL_END));

      return list.to_string();
    }

    return std::string();
  }
} deviceLinkNode;

static std::string getLinkedTargetsContent(
  cmGeneratorTarget const* target, std::string const& prop,
  cm::GenEx::Evaluation* eval, cmGeneratorExpressionDAGChecker* dagChecker,
  cmGeneratorTarget::UseTo usage)
{
  std::string result;
  if (cmLinkImplementationLibraries const* impl =
        target->GetLinkImplementationLibraries(
          eval->Context.Config, cmGeneratorTarget::UseTo::Compile)) {
    for (cmLinkItem const& lib : impl->Libraries) {
      if (lib.Target) {
        // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in our
        // caller's property and hand-evaluate it as if it were compiled.
        // Create a context as cmCompiledGeneratorExpression::Evaluate does.
        cm::GenEx::Context libContext(eval->Context);
        // FIXME: Why have we long used the target's local generator
        // instead of that of the evaluation context?
        libContext.LG = target->GetLocalGenerator();
        cm::GenEx::Evaluation libEval(
          std::move(libContext), eval->Quiet, target, target,
          eval->EvaluateForBuildsystem, lib.Backtrace);
        std::string libResult = lib.Target->EvaluateInterfaceProperty(
          prop, &libEval, dagChecker, usage);
        if (!libResult.empty()) {
          if (result.empty()) {
            result = std::move(libResult);
          } else {
            result.reserve(result.size() + 1 + libResult.size());
            result += ";";
            result += libResult;
          }
        }
      }
    }
  }
  return result;
}

static const struct TargetPropertyNode : public cmGeneratorExpressionNode
{
  TargetPropertyNode() {} // NOLINT(modernize-use-equals-default)

  // This node handles errors on parameter count itself.
  int NumExpectedParameters() const override { return OneOrMoreParameters; }

  static char const* GetErrorText(std::string const& targetName,
                                  std::string const& propertyName)
  {
    static cmsys::RegularExpression propertyNameValidator("^[A-Za-z0-9_]+$");
    if (targetName.empty() && propertyName.empty()) {
      return "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty "
             "target name and property name.";
    }
    if (targetName.empty()) {
      return "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty "
             "target name.";
    }
    if (!cmGeneratorExpression::IsValidTargetName(targetName)) {
      if (!propertyNameValidator.find(propertyName)) {
        return "Target name and property name not supported.";
      }
      return "Target name not supported.";
    }
    return nullptr;
  }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagCheckerParent) const override
  {
    static cmsys::RegularExpression propertyNameValidator("^[A-Za-z0-9_]+$");

    cmGeneratorTarget const* target = nullptr;
    std::string targetName;
    std::string propertyName;

    if (parameters.size() == 2) {
      targetName = parameters[0];
      propertyName = parameters[1];

      if (char const* e = GetErrorText(targetName, propertyName)) {
        reportError(eval, content->GetOriginalExpression(), e);
        return std::string();
      }
      if (propertyName == "ALIASED_TARGET"_s) {
        if (eval->Context.LG->GetMakefile()->IsAlias(targetName)) {
          if (cmGeneratorTarget* tgt =
                eval->Context.LG->FindGeneratorTargetToUse(targetName)) {
            return tgt->GetName();
          }
        }
        return std::string();
      }
      if (propertyName == "ALIAS_GLOBAL"_s) {
        if (eval->Context.LG->GetMakefile()->IsAlias(targetName)) {
          return eval->Context.LG->GetGlobalGenerator()->IsAlias(targetName)
            ? "TRUE"
            : "FALSE";
        }
        return std::string();
      }
      cmLocalGenerator const* lg = eval->CurrentTarget
        ? eval->CurrentTarget->GetLocalGenerator()
        : eval->Context.LG;
      target = lg->FindGeneratorTargetToUse(targetName);

      if (!target) {
        std::ostringstream e;
        e << "Target \"" << targetName << "\" not found.";
        reportError(eval, content->GetOriginalExpression(), e.str());
        return std::string();
      }
      eval->AllTargets.insert(target);

    } else if (parameters.size() == 1) {
      target = eval->HeadTarget;
      propertyName = parameters[0];

      // Keep track of the properties seen while processing.
      // The evaluation of the LINK_LIBRARIES generator expressions
      // will check this to ensure that properties have one consistent
      // value for all evaluations.
      eval->SeenTargetProperties.insert(propertyName);

      eval->HadHeadSensitiveCondition = true;
      if (!target) {
        reportError(
          eval, content->GetOriginalExpression(),
          "$<TARGET_PROPERTY:prop>  may only be used with binary targets.  "
          "It may not be used with add_custom_command or add_custom_target. "
          " "
          " "
          "Specify the target to read a property from using the "
          "$<TARGET_PROPERTY:tgt,prop> signature instead.");
        return std::string();
      }
    } else {
      reportError(
        eval, content->GetOriginalExpression(),
        "$<TARGET_PROPERTY:...> expression requires one or two parameters");
      return std::string();
    }

    if (propertyName == "SOURCES") {
      eval->SourceSensitiveTargets.insert(target);
    }

    if (propertyName.empty()) {
      reportError(
        eval, content->GetOriginalExpression(),
        "$<TARGET_PROPERTY:...> expression requires a non-empty property "
        "name.");
      return std::string();
    }

    if (!propertyNameValidator.find(propertyName)) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "Property name not supported.");
      return std::string();
    }

    assert(target);

    if (propertyName == "LINKER_LANGUAGE") {
      if (target->LinkLanguagePropagatesToDependents() && dagCheckerParent &&
          (dagCheckerParent->EvaluatingLinkLibraries() ||
           dagCheckerParent->EvaluatingSources())) {
        reportError(
          eval, content->GetOriginalExpression(),
          "LINKER_LANGUAGE target property can not be used while evaluating "
          "link libraries for a static library");
        return std::string();
      }
      return target->GetLinkerLanguage(eval->Context.Config);
    }

    bool const evaluatingLinkLibraries =
      dagCheckerParent && dagCheckerParent->EvaluatingLinkLibraries();

    std::string interfacePropertyName;
    bool isInterfaceProperty = false;
    cmGeneratorTarget::UseTo usage = cmGeneratorTarget::UseTo::Compile;

    if (cm::optional<cmGeneratorTarget::TransitiveProperty> transitiveProp =
          target->IsTransitiveProperty(propertyName, eval->Context,
                                       dagCheckerParent)) {
      interfacePropertyName = std::string(transitiveProp->InterfaceName);
      isInterfaceProperty = transitiveProp->InterfaceName == propertyName;
      usage = transitiveProp->Usage;
    }

    if (dagCheckerParent) {
      // This $<TARGET_PROPERTY:...> node has been reached while evaluating
      // another target property value.  Check that the outermost evaluation
      // expects such nested evaluations.
      if (dagCheckerParent->EvaluatingGenexExpression() ||
          dagCheckerParent->EvaluatingPICExpression() ||
          dagCheckerParent->EvaluatingLinkerLauncher()) {
        // No check required.
      } else if (evaluatingLinkLibraries) {
        if (!interfacePropertyName.empty() &&
            interfacePropertyName != "INTERFACE_LINK_LIBRARIES"_s) {
          reportError(
            eval, content->GetOriginalExpression(),
            "$<TARGET_PROPERTY:...> expression in link libraries "
            "evaluation depends on target property which is transitive "
            "over the link libraries, creating a recursion.");
          return std::string();
        }
      } else {
        assert(dagCheckerParent->EvaluatingTransitiveProperty());
      }
    }

    if (isInterfaceProperty) {
      return cmGeneratorExpression::StripEmptyListElements(
        target->EvaluateInterfaceProperty(propertyName, eval, dagCheckerParent,
                                          usage));
    }

    cmGeneratorExpressionDAGChecker dagChecker{
      target,           propertyName,  content,
      dagCheckerParent, eval->Context, eval->Backtrace,
    };

    switch (dagChecker.Check()) {
      case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
        dagChecker.ReportError(eval, content->GetOriginalExpression());
        return std::string();
      case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
        // No error. We just skip cyclic references.
        return std::string();
      case cmGeneratorExpressionDAGChecker::ALREADY_SEEN:
        // We handle transitive properties above.  For non-transitive
        // properties we accept repeats anyway.
      case cmGeneratorExpressionDAGChecker::DAG:
        break;
    }

    std::string result;
    bool haveProp = false;
    if (cmValue p = target->GetProperty(propertyName)) {
      result = *p;
      haveProp = true;
    } else if (evaluatingLinkLibraries) {
      return std::string();
    }

    // Properties named by COMPATIBLE_INTERFACE_ properties combine over
    // the transitive link closure as a single order-independent value.
    // Imported targets do not themselves have a defined value for these
    // properties, but they can contribute to the value of a non-imported
    // dependent.
    //
    // For COMPATIBLE_INTERFACE_{BOOL,STRING}:
    // * If set on this target, use the value directly.  It is checked
    //   elsewhere for consistency over the transitive link closure.
    // * If not set on this target, compute the value from the closure.
    //
    // For COMPATIBLE_INTERFACE_NUMBER_{MAX,MIN} we always compute the value
    // from this target and the transitive link closure to get the max or min.
    if (!haveProp && !target->IsImported()) {
      if (target->IsLinkInterfaceDependentBoolProperty(propertyName,
                                                       eval->Context.Config)) {
        eval->HadContextSensitiveCondition = true;
        return target->GetLinkInterfaceDependentBoolProperty(
                 propertyName, eval->Context.Config)
          ? "1"
          : "0";
      }
      if (target->IsLinkInterfaceDependentStringProperty(
            propertyName, eval->Context.Config)) {
        eval->HadContextSensitiveCondition = true;
        char const* propContent =
          target->GetLinkInterfaceDependentStringProperty(
            propertyName, eval->Context.Config);
        return propContent ? propContent : "";
      }
    }
    if (!evaluatingLinkLibraries && !target->IsImported()) {
      if (target->IsLinkInterfaceDependentNumberMinProperty(
            propertyName, eval->Context.Config)) {
        eval->HadContextSensitiveCondition = true;
        char const* propContent =
          target->GetLinkInterfaceDependentNumberMinProperty(
            propertyName, eval->Context.Config);
        return propContent ? propContent : "";
      }
      if (target->IsLinkInterfaceDependentNumberMaxProperty(
            propertyName, eval->Context.Config)) {
        eval->HadContextSensitiveCondition = true;
        char const* propContent =
          target->GetLinkInterfaceDependentNumberMaxProperty(
            propertyName, eval->Context.Config);
        return propContent ? propContent : "";
      }
    }

    // Some properties, such as usage requirements, combine over the
    // transitive link closure as an ordered list.
    if (!interfacePropertyName.empty()) {
      result = cmGeneratorExpression::StripEmptyListElements(
        this->EvaluateDependentExpression(result, eval, target, &dagChecker,
                                          target));
      std::string linkedTargetsContent = getLinkedTargetsContent(
        target, interfacePropertyName, eval, &dagChecker, usage);
      if (!linkedTargetsContent.empty()) {
        result += (result.empty() ? "" : ";") + linkedTargetsContent;
      }
    }
    return result;
  }
} targetPropertyNode;

static const struct targetIntermediateDirNode
  : public cmGeneratorExpressionNode
{
  targetIntermediateDirNode() {} // NOLINT(modernize-use-equals-default)

  static char const* GetErrorText(std::string const& targetName)
  {
    static cmsys::RegularExpression propertyNameValidator("^[A-Za-z0-9_]+$");
    if (targetName.empty()) {
      return "$<TARGET_INTERMEDIATE_DIR:tgt> expression requires a non-empty "
             "target name.";
    }
    if (!cmGeneratorExpression::IsValidTargetName(targetName)) {
      return "Target name not supported.";
    }
    return nullptr;
  }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    cmGeneratorTarget const* target = nullptr;
    std::string targetName;

    if (parameters.size() == 1) {
      targetName = parameters[0];

      if (char const* e = GetErrorText(targetName)) {
        reportError(eval, content->GetOriginalExpression(), e);
        return std::string();
      }
      cmLocalGenerator const* lg = eval->CurrentTarget
        ? eval->CurrentTarget->GetLocalGenerator()
        : eval->Context.LG;
      target = lg->FindGeneratorTargetToUse(targetName);

      if (!target) {
        std::ostringstream e;
        e << "Target \"" << targetName << "\" not found.";
        reportError(eval, content->GetOriginalExpression(), e.str());
        return std::string();
      }
      eval->AllTargets.insert(target);

    } else {
      reportError(
        eval, content->GetOriginalExpression(),
        "$<TARGET_INTERMEDIATE_DIR:...> expression requires one parameter");
      return std::string();
    }

    assert(target);

    if (!HasKnownObjectFileLocation(eval, content, "TARGET_INTERMEDIATE_DIR",
                                    target)) {
      return std::string();
    }

    return cmSystemTools::CollapseFullPath(
      target->GetObjectDirectory(eval->Context.Config));
  }
} targetIntermediateDirNode;

static const struct TargetNameNode : public cmGeneratorExpressionNode
{
  TargetNameNode() {} // NOLINT(modernize-use-equals-default)

  bool GeneratesContent() const override { return true; }

  bool AcceptsArbitraryContentParameter() const override { return true; }
  bool RequiresLiteralInput() const override { return true; }

  std::string Evaluate(
    std::vector<std::string> const& parameters,
    cm::GenEx::Evaluation* /*eval*/,
    GeneratorExpressionContent const* /*content*/,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    return parameters.front();
  }

  int NumExpectedParameters() const override { return 1; }

} targetNameNode;

static const struct TargetObjectsNode : public cmGeneratorExpressionNode
{
  TargetObjectsNode() {} // NOLINT(modernize-use-equals-default)

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    std::string const& tgtName = parameters.front();
    cmGeneratorTarget* gt =
      eval->Context.LG->FindGeneratorTargetToUse(tgtName);
    if (!gt) {
      std::ostringstream e;
      e << "Objects of target \"" << tgtName
        << "\" referenced but no such target exists.";
      reportError(eval, content->GetOriginalExpression(), e.str());
      return std::string();
    }
    cmStateEnums::TargetType type = gt->GetType();
    if (type != cmStateEnums::EXECUTABLE &&
        type != cmStateEnums::STATIC_LIBRARY &&
        type != cmStateEnums::SHARED_LIBRARY &&
        type != cmStateEnums::MODULE_LIBRARY &&
        type != cmStateEnums::OBJECT_LIBRARY) {
      std::ostringstream e;
      e << "Objects of target \"" << tgtName
        << "\" referenced but is not one of the allowed target types "
        << "(EXECUTABLE, STATIC, SHARED, MODULE, OBJECT).";
      reportError(eval, content->GetOriginalExpression(), e.str());
      return std::string();
    }
    cmGlobalGenerator const* gg = eval->Context.LG->GetGlobalGenerator();
    if (!HasKnownObjectFileLocation(eval, content, "TARGET_OBJECTS", gt)) {
      return std::string();
    }

    cmList objects;

    if (gt->IsImported()) {
      cmValue loc = nullptr;
      cmValue imp = nullptr;
      std::string suffix;
      if (gt->Target->GetMappedConfig(eval->Context.Config, loc, imp,
                                      suffix)) {
        objects.assign(*loc);
      }
      eval->HadContextSensitiveCondition = true;
    } else {
      gt->GetTargetObjectNames(eval->Context.Config, objects);

      std::string obj_dir;
      if (eval->EvaluateForBuildsystem && !gg->SupportsCrossConfigs()) {
        // Use object file directory with buildsystem placeholder.
        obj_dir = gt->ObjectDirectory;
        eval->HadContextSensitiveCondition = gt->HasContextDependentSources();
      } else {
        // Use object file directory with per-config location.
        obj_dir = gt->GetObjectDirectory(eval->Context.Config);
        eval->HadContextSensitiveCondition = true;
      }

      for (auto& o : objects) {
        o = cmStrCat(obj_dir, o);
      }
    }

    // Create the cmSourceFile instances in the referencing directory.
    cmMakefile* mf = eval->Context.LG->GetMakefile();
    for (std::string const& o : objects) {
      mf->AddTargetObject(tgtName, o);
    }

    return objects.to_string();
  }
} targetObjectsNode;

struct TargetRuntimeDllsBaseNode : public cmGeneratorExpressionNode
{
  std::vector<std::string> CollectDlls(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content) const
  {
    std::string const& tgtName = parameters.front();
    cmGeneratorTarget* gt =
      eval->Context.LG->FindGeneratorTargetToUse(tgtName);
    if (!gt) {
      std::ostringstream e;
      e << "Objects of target \"" << tgtName
        << "\" referenced but no such target exists.";
      reportError(eval, content->GetOriginalExpression(), e.str());
      return std::vector<std::string>();
    }
    cmStateEnums::TargetType type = gt->GetType();
    if (type != cmStateEnums::EXECUTABLE &&
        type != cmStateEnums::SHARED_LIBRARY &&
        type != cmStateEnums::MODULE_LIBRARY) {
      std::ostringstream e;
      e << "Objects of target \"" << tgtName
        << "\" referenced but is not one of the allowed target types "
        << "(EXECUTABLE, SHARED, MODULE).";
      reportError(eval, content->GetOriginalExpression(), e.str());
      return std::vector<std::string>();
    }

    if (auto* cli = gt->GetLinkInformation(eval->Context.Config)) {
      std::vector<std::string> dllPaths;
      auto const& dlls = cli->GetRuntimeDLLs();

      for (auto const& dll : dlls) {
        if (auto loc = dll->MaybeGetLocation(eval->Context.Config)) {
          dllPaths.emplace_back(*loc);
        }
      }

      return dllPaths;
    }

    return std::vector<std::string>();
  }
};

static const struct TargetRuntimeDllsNode : public TargetRuntimeDllsBaseNode
{
  TargetRuntimeDllsNode() {} // NOLINT(modernize-use-equals-default)

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    std::vector<std::string> dlls = CollectDlls(parameters, eval, content);
    return cmList::to_string(dlls);
  }
} targetRuntimeDllsNode;

static const struct TargetRuntimeDllDirsNode : public TargetRuntimeDllsBaseNode
{
  TargetRuntimeDllDirsNode() {} // NOLINT(modernize-use-equals-default)

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    std::vector<std::string> dlls = CollectDlls(parameters, eval, content);
    std::vector<std::string> dllDirs;
    for (std::string const& dll : dlls) {
      std::string directory = cmSystemTools::GetFilenamePath(dll);
      if (std::find(dllDirs.begin(), dllDirs.end(), directory) ==
          dllDirs.end()) {
        dllDirs.push_back(directory);
      }
    }
    return cmList::to_string(dllDirs);
  }
} targetRuntimeDllDirsNode;

static const struct CompileFeaturesNode : public cmGeneratorExpressionNode
{
  CompileFeaturesNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return OneOrMoreParameters; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagChecker) const override
  {
    cmGeneratorTarget const* target = eval->HeadTarget;
    if (!target) {
      reportError(
        eval, content->GetOriginalExpression(),
        "$<COMPILE_FEATURE> may only be used with binary targets.  It may "
        "not be used with add_custom_command or add_custom_target.");
      return std::string();
    }
    eval->HadHeadSensitiveCondition = true;

    using LangMap = std::map<std::string, cmList>;
    static LangMap availableFeatures;

    LangMap testedFeatures;
    cmStandardLevelResolver standardResolver(eval->Context.LG->GetMakefile());
    for (std::string const& p : parameters) {
      std::string error;
      std::string lang;
      if (!standardResolver.CompileFeatureKnown(
            eval->HeadTarget->Target->GetName(), p, lang, &error)) {
        reportError(eval, content->GetOriginalExpression(), error);
        return std::string();
      }
      testedFeatures[lang].push_back(p);

      if (availableFeatures.find(lang) == availableFeatures.end()) {
        cmValue featuresKnown =
          standardResolver.CompileFeaturesAvailable(lang, &error);
        if (!featuresKnown) {
          reportError(eval, content->GetOriginalExpression(), error);
          return std::string();
        }
        availableFeatures[lang].assign(featuresKnown);
      }
    }

    bool evalLL = dagChecker && dagChecker->EvaluatingLinkLibraries();

    for (auto const& lit : testedFeatures) {
      std::vector<std::string> const& langAvailable =
        availableFeatures[lit.first];
      cmValue standardDefault = eval->Context.LG->GetMakefile()->GetDefinition(
        "CMAKE_" + lit.first + "_STANDARD_DEFAULT");
      for (std::string const& it : lit.second) {
        if (!cm::contains(langAvailable, it)) {
          return "0";
        }
        if (standardDefault && standardDefault->empty()) {
          // This compiler has no notion of language standard levels.
          // All features known for the language are always available.
          continue;
        }
        if (!standardResolver.HaveStandardAvailable(
              target, lit.first, eval->Context.Config, it)) {
          if (evalLL) {
            cmValue l =
              target->GetLanguageStandard(lit.first, eval->Context.Config);
            if (!l) {
              l = standardDefault;
            }
            assert(l);
            eval->MaxLanguageStandard[target][lit.first] = *l;
          } else {
            return "0";
          }
        }
      }
    }
    return "1";
  }
} compileFeaturesNode;

static char const* targetPolicyWhitelist[] = {
  nullptr
#define TARGET_POLICY_STRING(POLICY) , #POLICY

  CM_FOR_EACH_TARGET_POLICY(TARGET_POLICY_STRING)

#undef TARGET_POLICY_STRING
};

static cmPolicies::PolicyStatus statusForTarget(cmGeneratorTarget const* tgt,
                                                char const* policy)
{
#define RETURN_POLICY(POLICY)                                                 \
  if (strcmp(policy, #POLICY) == 0) {                                         \
    return tgt->GetPolicyStatus##POLICY();                                    \
  }

  CM_FOR_EACH_TARGET_POLICY(RETURN_POLICY)

#undef RETURN_POLICY

  assert(false && "Unreachable code. Not a valid policy");
  return cmPolicies::WARN;
}

static cmPolicies::PolicyID policyForString(char const* policy_id)
{
#define RETURN_POLICY_ID(POLICY_ID)                                           \
  if (strcmp(policy_id, #POLICY_ID) == 0) {                                   \
    return cmPolicies::POLICY_ID;                                             \
  }

  CM_FOR_EACH_TARGET_POLICY(RETURN_POLICY_ID)

#undef RETURN_POLICY_ID

  assert(false && "Unreachable code. Not a valid policy");
  return cmPolicies::CMPCOUNT;
}

static const struct TargetPolicyNode : public cmGeneratorExpressionNode
{
  TargetPolicyNode() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 1; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    if (!eval->HeadTarget) {
      reportError(
        eval, content->GetOriginalExpression(),
        "$<TARGET_POLICY:prop> may only be used with binary targets.  It "
        "may not be used with add_custom_command or add_custom_target.");
      return std::string();
    }

    eval->HadContextSensitiveCondition = true;
    eval->HadHeadSensitiveCondition = true;

    for (size_t i = 1; i < cm::size(targetPolicyWhitelist); ++i) {
      char const* policy = targetPolicyWhitelist[i];
      if (parameters.front() == policy) {
        cmLocalGenerator* lg = eval->HeadTarget->GetLocalGenerator();
        switch (statusForTarget(eval->HeadTarget, policy)) {
          case cmPolicies::WARN:
            lg->IssueMessage(
              MessageType::AUTHOR_WARNING,
              cmPolicies::GetPolicyWarning(policyForString(policy)));
            CM_FALLTHROUGH;
          case cmPolicies::OLD:
            return "0";
          case cmPolicies::NEW:
            return "1";
        }
      }
    }
    reportError(
      eval, content->GetOriginalExpression(),
      "$<TARGET_POLICY:prop> may only be used with a limited number of "
      "policies.  Currently it may be used with the following policies:\n"

#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)

#define TARGET_POLICY_LIST_ITEM(POLICY) " * " STRINGIFY(POLICY) "\n"

      CM_FOR_EACH_TARGET_POLICY(TARGET_POLICY_LIST_ITEM)

#undef TARGET_POLICY_LIST_ITEM
    );
    return std::string();
  }

} targetPolicyNode;

static const struct InstallPrefixNode : public cmGeneratorExpressionNode
{
  InstallPrefixNode() {} // NOLINT(modernize-use-equals-default)

  bool GeneratesContent() const override { return true; }
  int NumExpectedParameters() const override { return 0; }

  std::string Evaluate(
    std::vector<std::string> const& /*parameters*/,
    cm::GenEx::Evaluation* eval, GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    reportError(eval, content->GetOriginalExpression(),
                "INSTALL_PREFIX is a marker for install(EXPORT) only.  It "
                "should never be evaluated.");
    return std::string();
  }

} installPrefixNode;

class ArtifactDirTag;
class ArtifactLinkerTag;
class ArtifactLinkerLibraryTag;
class ArtifactLinkerImportTag;
class ArtifactNameTag;
class ArtifactImportTag;
class ArtifactPathTag;
class ArtifactPdbTag;
class ArtifactSonameTag;
class ArtifactSonameImportTag;
class ArtifactBundleDirTag;
class ArtifactBundleDirNameTag;
class ArtifactBundleContentDirTag;

template <typename ArtifactT, typename ComponentT>
struct TargetFilesystemArtifactDependency
{
  static void AddDependency(cmGeneratorTarget* target,
                            cm::GenEx::Evaluation* eval)
  {
    eval->DependTargets.insert(target);
    eval->AllTargets.insert(target);
  }
};

struct TargetFilesystemArtifactDependencyCMP0112
{
  static void AddDependency(cmGeneratorTarget* target,
                            cm::GenEx::Evaluation* eval)
  {
    eval->AllTargets.insert(target);
    cmLocalGenerator const* lg = eval->Context.LG;
    switch (target->GetPolicyStatusCMP0112()) {
      case cmPolicies::WARN:
        if (lg->GetMakefile()->PolicyOptionalWarningEnabled(
              "CMAKE_POLICY_WARNING_CMP0112")) {
          std::string err =
            cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0112),
                     "\nDependency being added to target:\n  \"",
                     target->GetName(), "\"\n");
          lg->GetCMakeInstance()->IssueMessage(MessageType ::AUTHOR_WARNING,
                                               err, eval->Backtrace);
        }
        CM_FALLTHROUGH;
      case cmPolicies::OLD:
        eval->DependTargets.insert(target);
        break;
      case cmPolicies::NEW:
        break;
    }
  }
};

template <typename ArtifactT>
struct TargetFilesystemArtifactDependency<ArtifactT, ArtifactNameTag>
  : TargetFilesystemArtifactDependencyCMP0112
{
};
template <typename ArtifactT>
struct TargetFilesystemArtifactDependency<ArtifactT, ArtifactDirTag>
  : TargetFilesystemArtifactDependencyCMP0112
{
};
template <>
struct TargetFilesystemArtifactDependency<ArtifactBundleDirTag,
                                          ArtifactPathTag>
  : TargetFilesystemArtifactDependencyCMP0112
{
};
template <>
struct TargetFilesystemArtifactDependency<ArtifactBundleDirNameTag,
                                          ArtifactPathTag>
  : TargetFilesystemArtifactDependencyCMP0112
{
};
template <>
struct TargetFilesystemArtifactDependency<ArtifactBundleContentDirTag,
                                          ArtifactPathTag>
  : TargetFilesystemArtifactDependencyCMP0112
{
};

template <typename ArtifactT>
struct TargetFilesystemArtifactResultCreator
{
  static std::string Create(cmGeneratorTarget* target,
                            cm::GenEx::Evaluation* eval,
                            GeneratorExpressionContent const* content);
};

template <>
struct TargetFilesystemArtifactResultCreator<ArtifactSonameTag>
{
  static std::string Create(cmGeneratorTarget* target,
                            cm::GenEx::Evaluation* eval,
                            GeneratorExpressionContent const* content)
  {
    // The target soname file (.so.1).
    if (target->IsDLLPlatform()) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "TARGET_SONAME_FILE is not allowed "
                    "for DLL target platforms.");
      return std::string();
    }
    if (target->GetType() != cmStateEnums::SHARED_LIBRARY) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "TARGET_SONAME_FILE is allowed only for "
                    "SHARED libraries.");
      return std::string();
    }
    if (target->IsArchivedAIXSharedLibrary()) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "TARGET_SONAME_FILE is not allowed for "
                    "AIX_SHARED_LIBRARY_ARCHIVE libraries.");
      return std::string();
    }
    std::string result =
      cmStrCat(target->GetDirectory(eval->Context.Config), '/',
               target->GetSOName(eval->Context.Config));
    return result;
  }
};

template <>
struct TargetFilesystemArtifactResultCreator<ArtifactSonameImportTag>
{
  static std::string Create(cmGeneratorTarget* target,
                            cm::GenEx::Evaluation* eval,
                            GeneratorExpressionContent const* content)
  {
    // The target soname file (.so.1).
    if (target->IsDLLPlatform()) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "TARGET_SONAME_IMPORT_FILE is not allowed "
                    "for DLL target platforms.");
      return std::string();
    }
    if (target->GetType() != cmStateEnums::SHARED_LIBRARY) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "TARGET_SONAME_IMPORT_FILE is allowed only for "
                    "SHARED libraries.");
      return std::string();
    }
    if (target->IsArchivedAIXSharedLibrary()) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "TARGET_SONAME_IMPORT_FILE is not allowed for "
                    "AIX_SHARED_LIBRARY_ARCHIVE libraries.");
      return std::string();
    }

    if (target->HasImportLibrary(eval->Context.Config)) {
      return cmStrCat(
        target->GetDirectory(eval->Context.Config,
                             cmStateEnums::ImportLibraryArtifact),
        '/',
        target->GetSOName(eval->Context.Config,
                          cmStateEnums::ImportLibraryArtifact));
    }
    return std::string{};
  }
};

template <>
struct TargetFilesystemArtifactResultCreator<ArtifactPdbTag>
{
  static std::string Create(cmGeneratorTarget* target,
                            cm::GenEx::Evaluation* eval,
                            GeneratorExpressionContent const* content)
  {
    if (target->IsImported()) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "TARGET_PDB_FILE not allowed for IMPORTED targets.");
      return std::string();
    }

    std::string language = target->GetLinkerLanguage(eval->Context.Config);

    std::string pdbSupportVar = "CMAKE_" + language + "_LINKER_SUPPORTS_PDB";

    if (!eval->Context.LG->GetMakefile()->IsOn(pdbSupportVar)) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "TARGET_PDB_FILE is not supported by the target linker.");
      return std::string();
    }

    cmStateEnums::TargetType targetType = target->GetType();

    if (targetType != cmStateEnums::SHARED_LIBRARY &&
        targetType != cmStateEnums::MODULE_LIBRARY &&
        targetType != cmStateEnums::EXECUTABLE) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "TARGET_PDB_FILE is allowed only for "
                    "targets with linker created artifacts.");
      return std::string();
    }

    std::string result =
      cmStrCat(target->GetPDBDirectory(eval->Context.Config), '/',
               target->GetPDBName(eval->Context.Config));
    return result;
  }
};

template <>
struct TargetFilesystemArtifactResultCreator<ArtifactLinkerTag>
{
  static std::string Create(cmGeneratorTarget* target,
                            cm::GenEx::Evaluation* eval,
                            GeneratorExpressionContent const* content)
  {
    // The file used to link to the target (.so, .lib, .a) or import file
    // (.lib,  .tbd).
    if (!target->IsLinkable()) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "TARGET_LINKER_FILE is allowed only for libraries and "
                    "executables with ENABLE_EXPORTS.");
      return std::string();
    }
    cmStateEnums::ArtifactType artifact =
      target->HasImportLibrary(eval->Context.Config)
      ? cmStateEnums::ImportLibraryArtifact
      : cmStateEnums::RuntimeBinaryArtifact;
    return target->GetFullPath(eval->Context.Config, artifact);
  }
};

template <>
struct TargetFilesystemArtifactResultCreator<ArtifactLinkerLibraryTag>
{
  static std::string Create(cmGeneratorTarget* target,
                            cm::GenEx::Evaluation* eval,
                            GeneratorExpressionContent const* content)
  {
    // The file used to link to the target (.dylib, .so, .a).
    if (!target->IsLinkable() ||
        target->GetType() == cmStateEnums::EXECUTABLE) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "TARGET_LINKER_LIBRARY_FILE is allowed only for libraries "
                    "with ENABLE_EXPORTS.");
      return std::string();
    }

    if (!target->IsDLLPlatform() ||
        target->GetType() == cmStateEnums::STATIC_LIBRARY) {
      return target->GetFullPath(eval->Context.Config,
                                 cmStateEnums::RuntimeBinaryArtifact);
    }
    return std::string{};
  }
};

template <>
struct TargetFilesystemArtifactResultCreator<ArtifactLinkerImportTag>
{
  static std::string Create(cmGeneratorTarget* target,
                            cm::GenEx::Evaluation* eval,
                            GeneratorExpressionContent const* content)
  {
    // The file used to link to the target (.lib, .tbd).
    if (!target->IsLinkable()) {
      ::reportError(
        eval, content->GetOriginalExpression(),
        "TARGET_LINKER_IMPORT_FILE is allowed only for libraries and "
        "executables with ENABLE_EXPORTS.");
      return std::string();
    }

    if (target->HasImportLibrary(eval->Context.Config)) {
      return target->GetFullPath(eval->Context.Config,
                                 cmStateEnums::ImportLibraryArtifact);
    }
    return std::string{};
  }
};

template <>
struct TargetFilesystemArtifactResultCreator<ArtifactBundleDirTag>
{
  static std::string Create(cmGeneratorTarget* target,
                            cm::GenEx::Evaluation* eval,
                            GeneratorExpressionContent const* content)
  {
    if (target->IsImported()) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "TARGET_BUNDLE_DIR not allowed for IMPORTED targets.");
      return std::string();
    }
    if (!target->IsBundleOnApple()) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "TARGET_BUNDLE_DIR is allowed only for Bundle targets.");
      return std::string();
    }

    std::string outpath = target->GetDirectory(eval->Context.Config) + '/';
    return target->BuildBundleDirectory(outpath, eval->Context.Config,
                                        cmGeneratorTarget::BundleDirLevel);
  }
};

template <>
struct TargetFilesystemArtifactResultCreator<ArtifactBundleDirNameTag>
{
  static std::string Create(cmGeneratorTarget* target,
                            cm::GenEx::Evaluation* eval,
                            GeneratorExpressionContent const* content)
  {
    if (target->IsImported()) {
      ::reportError(
        eval, content->GetOriginalExpression(),
        "TARGET_BUNDLE_DIR_NAME not allowed for IMPORTED targets.");
      return std::string();
    }
    if (!target->IsBundleOnApple()) {
      ::reportError(
        eval, content->GetOriginalExpression(),
        "TARGET_BUNDLE_DIR_NAME is allowed only for Bundle targets.");
      return std::string();
    }

    auto level = cmGeneratorTarget::BundleDirLevel;
    auto config = eval->Context.Config;
    if (target->IsAppBundleOnApple()) {
      return target->GetAppBundleDirectory(config, level);
    }
    if (target->IsFrameworkOnApple()) {
      return target->GetFrameworkDirectory(config, level);
    }
    if (target->IsCFBundleOnApple()) {
      return target->GetCFBundleDirectory(config, level);
    }
    return std::string();
  }
};

template <>
struct TargetFilesystemArtifactResultCreator<ArtifactBundleContentDirTag>
{
  static std::string Create(cmGeneratorTarget* target,
                            cm::GenEx::Evaluation* eval,
                            GeneratorExpressionContent const* content)
  {
    if (target->IsImported()) {
      ::reportError(
        eval, content->GetOriginalExpression(),
        "TARGET_BUNDLE_CONTENT_DIR not allowed for IMPORTED targets.");
      return std::string();
    }
    if (!target->IsBundleOnApple()) {
      ::reportError(
        eval, content->GetOriginalExpression(),
        "TARGET_BUNDLE_CONTENT_DIR is allowed only for Bundle targets.");
      return std::string();
    }

    std::string outpath = target->GetDirectory(eval->Context.Config) + '/';
    return target->BuildBundleDirectory(outpath, eval->Context.Config,
                                        cmGeneratorTarget::ContentLevel);
  }
};

template <>
struct TargetFilesystemArtifactResultCreator<ArtifactNameTag>
{
  static std::string Create(cmGeneratorTarget* target,
                            cm::GenEx::Evaluation* eval,
                            GeneratorExpressionContent const* /*unused*/)
  {
    return target->GetFullPath(eval->Context.Config,
                               cmStateEnums::RuntimeBinaryArtifact, true);
  }
};

template <>
struct TargetFilesystemArtifactResultCreator<ArtifactImportTag>
{
  static std::string Create(cmGeneratorTarget* target,
                            cm::GenEx::Evaluation* eval,
                            GeneratorExpressionContent const* /*unused*/)
  {
    if (target->HasImportLibrary(eval->Context.Config)) {
      return target->GetFullPath(eval->Context.Config,
                                 cmStateEnums::ImportLibraryArtifact, true);
    }
    return std::string{};
  }
};

template <typename ArtifactT>
struct TargetFilesystemArtifactResultGetter
{
  static std::string Get(std::string const& result);
};

template <>
struct TargetFilesystemArtifactResultGetter<ArtifactNameTag>
{
  static std::string Get(std::string const& result)
  {
    return cmSystemTools::GetFilenameName(result);
  }
};

template <>
struct TargetFilesystemArtifactResultGetter<ArtifactDirTag>
{
  static std::string Get(std::string const& result)
  {
    return cmSystemTools::GetFilenamePath(result);
  }
};

template <>
struct TargetFilesystemArtifactResultGetter<ArtifactPathTag>
{
  static std::string Get(std::string const& result) { return result; }
};

struct TargetArtifactBase : public cmGeneratorExpressionNode
{
  TargetArtifactBase() {} // NOLINT(modernize-use-equals-default)

protected:
  cmGeneratorTarget* GetTarget(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagChecker) const
  {
    // Lookup the referenced target.
    std::string const& name = parameters.front();

    if (!cmGeneratorExpression::IsValidTargetName(name)) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "Expression syntax not recognized.");
      return nullptr;
    }
    cmGeneratorTarget* target =
      eval->Context.LG->FindGeneratorTargetToUse(name);
    if (!target) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "No target \"" + name + "\"");
      return nullptr;
    }
    if (target->GetType() >= cmStateEnums::OBJECT_LIBRARY &&
        target->GetType() != cmStateEnums::UNKNOWN_LIBRARY) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "Target \"" + name +
                      "\" is not an executable or library.");
      return nullptr;
    }
    if (dagChecker &&
        (dagChecker->EvaluatingLinkLibraries(target) ||
         (dagChecker->EvaluatingSources() &&
          target == dagChecker->TopTarget()))) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "Expressions which require the linker language may not "
                    "be used while evaluating link libraries");
      return nullptr;
    }

    return target;
  }
};

template <typename ArtifactT, typename ComponentT>
struct TargetFilesystemArtifact : public TargetArtifactBase
{
  TargetFilesystemArtifact() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 1; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagChecker) const override
  {
    cmGeneratorTarget* target =
      this->GetTarget(parameters, eval, content, dagChecker);
    if (!target) {
      return std::string();
    }
    // Not a dependent target if we are querying for ArtifactDirTag,
    // ArtifactNameTag, ArtifactBundleDirTag, ArtifactBundleDirNameTag,
    // and ArtifactBundleContentDirTag
    TargetFilesystemArtifactDependency<ArtifactT, ComponentT>::AddDependency(
      target, eval);

    std::string result =
      TargetFilesystemArtifactResultCreator<ArtifactT>::Create(target, eval,
                                                               content);
    if (eval->HadError) {
      return std::string();
    }
    return TargetFilesystemArtifactResultGetter<ComponentT>::Get(result);
  }
};

template <typename ArtifactT>
struct TargetFilesystemArtifactNodeGroup
{
  TargetFilesystemArtifactNodeGroup() // NOLINT(modernize-use-equals-default)
  {
  }

  TargetFilesystemArtifact<ArtifactT, ArtifactPathTag> File;
  TargetFilesystemArtifact<ArtifactT, ArtifactNameTag> FileName;
  TargetFilesystemArtifact<ArtifactT, ArtifactDirTag> FileDir;
};

static TargetFilesystemArtifactNodeGroup<ArtifactNameTag> const
  targetNodeGroup;

static TargetFilesystemArtifactNodeGroup<ArtifactImportTag> const
  targetImportNodeGroup;

static TargetFilesystemArtifactNodeGroup<ArtifactLinkerTag> const
  targetLinkerNodeGroup;

static TargetFilesystemArtifactNodeGroup<ArtifactLinkerLibraryTag> const
  targetLinkerLibraryNodeGroup;

static TargetFilesystemArtifactNodeGroup<ArtifactLinkerImportTag> const
  targetLinkerImportNodeGroup;

static TargetFilesystemArtifactNodeGroup<ArtifactSonameTag> const
  targetSoNameNodeGroup;

static TargetFilesystemArtifactNodeGroup<ArtifactSonameImportTag> const
  targetSoNameImportNodeGroup;

static TargetFilesystemArtifactNodeGroup<ArtifactPdbTag> const
  targetPdbNodeGroup;

static TargetFilesystemArtifact<ArtifactBundleDirTag, ArtifactPathTag> const
  targetBundleDirNode;

static TargetFilesystemArtifact<ArtifactBundleDirNameTag,
                                ArtifactNameTag> const targetBundleDirNameNode;

static TargetFilesystemArtifact<ArtifactBundleContentDirTag,
                                ArtifactPathTag> const
  targetBundleContentDirNode;

//
// To retrieve base name for various artifacts
//
enum class Postfix
{
  Unspecified,
  Exclude,
  Include
};

template <typename ArtifactT>
struct TargetOutputNameArtifactResultGetter
{
  static std::string Get(cmGeneratorTarget* target,
                         cm::GenEx::Evaluation* eval,
                         GeneratorExpressionContent const* content,
                         Postfix postfix);
};

template <>
struct TargetOutputNameArtifactResultGetter<ArtifactNameTag>
{
  static std::string Get(cmGeneratorTarget* target,
                         cm::GenEx::Evaluation* eval,
                         GeneratorExpressionContent const* /*unused*/,
                         Postfix postfix)
  {
    auto output = target->GetOutputName(eval->Context.Config,
                                        cmStateEnums::RuntimeBinaryArtifact);
    return postfix != Postfix::Exclude
      ? cmStrCat(output, target->GetFilePostfix(eval->Context.Config))
      : output;
  }
};

template <>
struct TargetOutputNameArtifactResultGetter<ArtifactImportTag>
{
  static std::string Get(cmGeneratorTarget* target,
                         cm::GenEx::Evaluation* eval,
                         GeneratorExpressionContent const* /*unused*/,
                         Postfix postfix)
  {
    if (target->HasImportLibrary(eval->Context.Config)) {
      auto output = target->GetOutputName(eval->Context.Config,
                                          cmStateEnums::ImportLibraryArtifact);
      return postfix != Postfix::Exclude
        ? cmStrCat(output, target->GetFilePostfix(eval->Context.Config))
        : output;
    }
    return std::string{};
  }
};

template <>
struct TargetOutputNameArtifactResultGetter<ArtifactLinkerTag>
{
  static std::string Get(cmGeneratorTarget* target,
                         cm::GenEx::Evaluation* eval,
                         GeneratorExpressionContent const* content,
                         Postfix postfix)
  {
    // The library file used to link to the target (.so, .lib, .a) or import
    // file (.lin,  .tbd).
    if (!target->IsLinkable()) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "TARGET_LINKER_FILE_BASE_NAME is allowed only for "
                    "libraries and executables with ENABLE_EXPORTS.");
      return std::string();
    }
    cmStateEnums::ArtifactType artifact =
      target->HasImportLibrary(eval->Context.Config)
      ? cmStateEnums::ImportLibraryArtifact
      : cmStateEnums::RuntimeBinaryArtifact;
    auto output = target->GetOutputName(eval->Context.Config, artifact);
    return postfix != Postfix::Exclude
      ? cmStrCat(output, target->GetFilePostfix(eval->Context.Config))
      : output;
  }
};

template <>
struct TargetOutputNameArtifactResultGetter<ArtifactLinkerLibraryTag>
{
  static std::string Get(cmGeneratorTarget* target,
                         cm::GenEx::Evaluation* eval,
                         GeneratorExpressionContent const* content,
                         Postfix postfix)
  {
    // The library file used to link to the target (.so, .lib, .a).
    if (!target->IsLinkable() ||
        target->GetType() == cmStateEnums::EXECUTABLE) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "TARGET_LINKER_LIBRARY_FILE_BASE_NAME is allowed only for "
                    "libraries with ENABLE_EXPORTS.");
      return std::string();
    }

    if (!target->IsDLLPlatform() ||
        target->GetType() == cmStateEnums::STATIC_LIBRARY) {
      auto output = target->GetOutputName(eval->Context.Config,
                                          cmStateEnums::ImportLibraryArtifact);
      return postfix != Postfix::Exclude
        ? cmStrCat(output, target->GetFilePostfix(eval->Context.Config))
        : output;
    }
    return std::string{};
  }
};

template <>
struct TargetOutputNameArtifactResultGetter<ArtifactLinkerImportTag>
{
  static std::string Get(cmGeneratorTarget* target,
                         cm::GenEx::Evaluation* eval,
                         GeneratorExpressionContent const* content,
                         Postfix postfix)
  {
    // The import file used to link to the target (.lib, .tbd).
    if (!target->IsLinkable()) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "TARGET_LINKER_IMPORT_FILE_BASE_NAME is allowed only for "
                    "libraries and executables with ENABLE_EXPORTS.");
      return std::string();
    }

    if (target->HasImportLibrary(eval->Context.Config)) {
      auto output = target->GetOutputName(eval->Context.Config,
                                          cmStateEnums::ImportLibraryArtifact);
      return postfix != Postfix::Exclude
        ? cmStrCat(output, target->GetFilePostfix(eval->Context.Config))
        : output;
    }
    return std::string{};
  }
};

template <>
struct TargetOutputNameArtifactResultGetter<ArtifactPdbTag>
{
  static std::string Get(cmGeneratorTarget* target,
                         cm::GenEx::Evaluation* eval,
                         GeneratorExpressionContent const* content,
                         Postfix postfix)
  {
    if (target->IsImported()) {
      ::reportError(
        eval, content->GetOriginalExpression(),
        "TARGET_PDB_FILE_BASE_NAME not allowed for IMPORTED targets.");
      return std::string();
    }

    std::string language = target->GetLinkerLanguage(eval->Context.Config);

    std::string pdbSupportVar = "CMAKE_" + language + "_LINKER_SUPPORTS_PDB";

    if (!eval->Context.LG->GetMakefile()->IsOn(pdbSupportVar)) {
      ::reportError(
        eval, content->GetOriginalExpression(),
        "TARGET_PDB_FILE_BASE_NAME is not supported by the target linker.");
      return std::string();
    }

    cmStateEnums::TargetType targetType = target->GetType();

    if (targetType != cmStateEnums::SHARED_LIBRARY &&
        targetType != cmStateEnums::MODULE_LIBRARY &&
        targetType != cmStateEnums::EXECUTABLE) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "TARGET_PDB_FILE_BASE_NAME is allowed only for "
                    "targets with linker created artifacts.");
      return std::string();
    }

    auto output = target->GetPDBOutputName(eval->Context.Config);

    if (target->GetPolicyStatusCMP0202() == cmPolicies::NEW) {
      return postfix != Postfix::Exclude
        ? cmStrCat(output, target->GetFilePostfix(eval->Context.Config))
        : output;
    }

    if (target->GetPolicyStatusCMP0202() == cmPolicies::WARN &&
        postfix != Postfix::Unspecified) {
      eval->Context.LG->GetCMakeInstance()->IssueMessage(
        MessageType::AUTHOR_WARNING,
        cmStrCat(cmPolicies::GetPolicyWarning(cmPolicies::CMP0202),
                 "\n"
                 "\"POSTFIX\" option is recognized only when the policy is "
                 "set to NEW. Since the policy is not set, the OLD behavior "
                 "will be used."),
        eval->Backtrace);
    }

    return output;
  }
};

template <typename ArtifactT>
struct TargetFileBaseNameArtifact : public TargetArtifactBase
{
  TargetFileBaseNameArtifact() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return OneOrMoreParameters; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagChecker) const override
  {
    if (parameters.size() > 2) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "Unexpected parameters, require one or two parameters.");
      return std::string{};
    }

    cmGeneratorTarget* target =
      this->GetTarget(parameters, eval, content, dagChecker);
    if (!target) {
      return std::string();
    }

    Postfix postfix = Postfix::Unspecified;
    if (parameters.size() == 2) {
      if (parameters[1] == "POSTFIX:INCLUDE") {
        postfix = Postfix::Include;
      } else if (parameters[1] == "POSTFIX:EXCLUDE") {
        postfix = Postfix::Exclude;
      } else {
        ::reportError(eval, content->GetOriginalExpression(),
                      "Wrong second parameter: \"POSTFIX:INCLUDE\" or "
                      "\"POSTFIX:EXCLUDE\" is expected");
      }
    }

    std::string result = TargetOutputNameArtifactResultGetter<ArtifactT>::Get(
      target, eval, content, postfix);
    if (eval->HadError) {
      return std::string();
    }
    return result;
  }
};

static TargetFileBaseNameArtifact<ArtifactNameTag> const
  targetFileBaseNameNode;
static TargetFileBaseNameArtifact<ArtifactImportTag> const
  targetImportFileBaseNameNode;
static TargetFileBaseNameArtifact<ArtifactLinkerTag> const
  targetLinkerFileBaseNameNode;
static TargetFileBaseNameArtifact<ArtifactLinkerLibraryTag> const
  targetLinkerLibraryFileBaseNameNode;
static TargetFileBaseNameArtifact<ArtifactLinkerImportTag> const
  targetLinkerImportFileBaseNameNode;
static TargetFileBaseNameArtifact<ArtifactPdbTag> const
  targetPdbFileBaseNameNode;

class ArtifactFilePrefixTag;
class ArtifactImportFilePrefixTag;
class ArtifactLinkerFilePrefixTag;
class ArtifactLinkerLibraryFilePrefixTag;
class ArtifactLinkerImportFilePrefixTag;
class ArtifactFileSuffixTag;
class ArtifactImportFileSuffixTag;
class ArtifactLinkerFileSuffixTag;
class ArtifactLinkerLibraryFileSuffixTag;
class ArtifactLinkerImportFileSuffixTag;

template <typename ArtifactT>
struct TargetFileArtifactResultGetter
{
  static std::string Get(cmGeneratorTarget* target,
                         cm::GenEx::Evaluation* eval,
                         GeneratorExpressionContent const* content);
};

template <>
struct TargetFileArtifactResultGetter<ArtifactFilePrefixTag>
{
  static std::string Get(cmGeneratorTarget* target,
                         cm::GenEx::Evaluation* eval,
                         GeneratorExpressionContent const*)
  {
    return target->GetFilePrefix(eval->Context.Config);
  }
};
template <>
struct TargetFileArtifactResultGetter<ArtifactImportFilePrefixTag>
{
  static std::string Get(cmGeneratorTarget* target,
                         cm::GenEx::Evaluation* eval,
                         GeneratorExpressionContent const*)
  {
    if (target->HasImportLibrary(eval->Context.Config)) {
      return target->GetFilePrefix(eval->Context.Config,
                                   cmStateEnums::ImportLibraryArtifact);
    }
    return std::string{};
  }
};
template <>
struct TargetFileArtifactResultGetter<ArtifactLinkerFilePrefixTag>
{
  static std::string Get(cmGeneratorTarget* target,
                         cm::GenEx::Evaluation* eval,
                         GeneratorExpressionContent const* content)
  {
    if (!target->IsLinkable()) {
      ::reportError(
        eval, content->GetOriginalExpression(),
        "TARGET_LINKER_FILE_PREFIX is allowed only for libraries and "
        "executables with ENABLE_EXPORTS.");
      return std::string();
    }

    cmStateEnums::ArtifactType artifact =
      target->HasImportLibrary(eval->Context.Config)
      ? cmStateEnums::ImportLibraryArtifact
      : cmStateEnums::RuntimeBinaryArtifact;

    return target->GetFilePrefix(eval->Context.Config, artifact);
  }
};
template <>
struct TargetFileArtifactResultGetter<ArtifactLinkerLibraryFilePrefixTag>
{
  static std::string Get(cmGeneratorTarget* target,
                         cm::GenEx::Evaluation* eval,
                         GeneratorExpressionContent const* content)
  {
    if (!target->IsLinkable() ||
        target->GetType() == cmStateEnums::EXECUTABLE) {
      ::reportError(
        eval, content->GetOriginalExpression(),
        "TARGET_LINKER_LIBRARY_FILE_PREFIX is allowed only for libraries "
        "with ENABLE_EXPORTS.");
      return std::string();
    }

    if (!target->IsDLLPlatform() ||
        target->GetType() == cmStateEnums::STATIC_LIBRARY) {
      return target->GetFilePrefix(eval->Context.Config,
                                   cmStateEnums::RuntimeBinaryArtifact);
    }
    return std::string{};
  }
};
template <>
struct TargetFileArtifactResultGetter<ArtifactLinkerImportFilePrefixTag>
{
  static std::string Get(cmGeneratorTarget* target,
                         cm::GenEx::Evaluation* eval,
                         GeneratorExpressionContent const* content)
  {
    if (!target->IsLinkable()) {
      ::reportError(
        eval, content->GetOriginalExpression(),
        "TARGET_LINKER_IMPORT_FILE_PREFIX is allowed only for libraries and "
        "executables with ENABLE_EXPORTS.");
      return std::string();
    }

    if (target->HasImportLibrary(eval->Context.Config)) {
      return target->GetFilePrefix(eval->Context.Config,
                                   cmStateEnums::ImportLibraryArtifact);
    }
    return std::string{};
  }
};
template <>
struct TargetFileArtifactResultGetter<ArtifactFileSuffixTag>
{
  static std::string Get(cmGeneratorTarget* target,
                         cm::GenEx::Evaluation* eval,
                         GeneratorExpressionContent const*)
  {
    return target->GetFileSuffix(eval->Context.Config);
  }
};
template <>
struct TargetFileArtifactResultGetter<ArtifactImportFileSuffixTag>
{
  static std::string Get(cmGeneratorTarget* target,
                         cm::GenEx::Evaluation* eval,
                         GeneratorExpressionContent const*)
  {
    if (target->HasImportLibrary(eval->Context.Config)) {
      return target->GetFileSuffix(eval->Context.Config,
                                   cmStateEnums::ImportLibraryArtifact);
    }
    return std::string{};
  }
};
template <>
struct TargetFileArtifactResultGetter<ArtifactLinkerFileSuffixTag>
{
  static std::string Get(cmGeneratorTarget* target,
                         cm::GenEx::Evaluation* eval,
                         GeneratorExpressionContent const* content)
  {
    if (!target->IsLinkable()) {
      ::reportError(
        eval, content->GetOriginalExpression(),
        "TARGET_LINKER_FILE_SUFFIX is allowed only for libraries and "
        "executables with ENABLE_EXPORTS.");
      return std::string();
    }

    cmStateEnums::ArtifactType artifact =
      target->HasImportLibrary(eval->Context.Config)
      ? cmStateEnums::ImportLibraryArtifact
      : cmStateEnums::RuntimeBinaryArtifact;

    return target->GetFileSuffix(eval->Context.Config, artifact);
  }
};
template <>
struct TargetFileArtifactResultGetter<ArtifactLinkerLibraryFileSuffixTag>
{
  static std::string Get(cmGeneratorTarget* target,
                         cm::GenEx::Evaluation* eval,
                         GeneratorExpressionContent const* content)
  {
    if (!target->IsLinkable() ||
        target->GetType() == cmStateEnums::STATIC_LIBRARY) {
      ::reportError(eval, content->GetOriginalExpression(),
                    "TARGET_LINKER_LIBRARY_FILE_SUFFIX is allowed only for "
                    "libraries with ENABLE_EXPORTS.");
      return std::string();
    }

    if (!target->IsDLLPlatform() ||
        target->GetType() == cmStateEnums::STATIC_LIBRARY) {
      return target->GetFileSuffix(eval->Context.Config,
                                   cmStateEnums::RuntimeBinaryArtifact);
    }
    return std::string{};
  }
};
template <>
struct TargetFileArtifactResultGetter<ArtifactLinkerImportFileSuffixTag>
{
  static std::string Get(cmGeneratorTarget* target,
                         cm::GenEx::Evaluation* eval,
                         GeneratorExpressionContent const* content)
  {
    if (!target->IsLinkable()) {
      ::reportError(
        eval, content->GetOriginalExpression(),
        "TARGET_LINKER_IMPORT_FILE_SUFFIX is allowed only for libraries and "
        "executables with ENABLE_EXPORTS.");
      return std::string();
    }

    if (target->HasImportLibrary(eval->Context.Config)) {
      return target->GetFileSuffix(eval->Context.Config,
                                   cmStateEnums::ImportLibraryArtifact);
    }
    return std::string{};
  }
};

template <typename ArtifactT>
struct TargetFileArtifact : public TargetArtifactBase
{
  TargetFileArtifact() {} // NOLINT(modernize-use-equals-default)

  int NumExpectedParameters() const override { return 1; }

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* dagChecker) const override
  {
    cmGeneratorTarget* target =
      this->GetTarget(parameters, eval, content, dagChecker);
    if (!target) {
      return std::string();
    }

    std::string result =
      TargetFileArtifactResultGetter<ArtifactT>::Get(target, eval, content);
    if (eval->HadError) {
      return std::string();
    }
    return result;
  }
};

static TargetFileArtifact<ArtifactFilePrefixTag> const targetFilePrefixNode;
static TargetFileArtifact<ArtifactImportFilePrefixTag> const
  targetImportFilePrefixNode;
static TargetFileArtifact<ArtifactLinkerFilePrefixTag> const
  targetLinkerFilePrefixNode;
static TargetFileArtifact<ArtifactLinkerLibraryFilePrefixTag> const
  targetLinkerLibraryFilePrefixNode;
static TargetFileArtifact<ArtifactLinkerImportFilePrefixTag> const
  targetLinkerImportFilePrefixNode;
static TargetFileArtifact<ArtifactFileSuffixTag> const targetFileSuffixNode;
static TargetFileArtifact<ArtifactImportFileSuffixTag> const
  targetImportFileSuffixNode;
static TargetFileArtifact<ArtifactLinkerFileSuffixTag> const
  targetLinkerFileSuffixNode;
static TargetFileArtifact<ArtifactLinkerLibraryFileSuffixTag> const
  targetLinkerLibraryFileSuffixNode;
static TargetFileArtifact<ArtifactLinkerImportFileSuffixTag> const
  targetLinkerImportFileSuffixNode;

static const struct ShellPathNode : public cmGeneratorExpressionNode
{
  ShellPathNode() {} // NOLINT(modernize-use-equals-default)

  std::string Evaluate(
    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
    GeneratorExpressionContent const* content,
    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
  {
    cmList list_in{ parameters.front() };
    if (list_in.empty()) {
      reportError(eval, content->GetOriginalExpression(),
                  "\"\" is not an absolute path.");
      return std::string();
    }
    cmStateSnapshot snapshot = eval->Context.LG->GetStateSnapshot();
    cmOutputConverter converter(snapshot);
    char const* separator = snapshot.GetState()->UseWindowsShell() ? ";" : ":";
    std::vector<std::string> list_out;
    list_out.reserve(list_in.size());
    for (auto const& in : list_in) {
      if (!cmSystemTools::FileIsFullPath(in)) {
        reportError(eval, content->GetOriginalExpression(),
                    "\"" + in + "\" is not an absolute path.");
        return std::string();
      }
      list_out.emplace_back(converter.ConvertDirectorySeparatorsForShell(in));
    }
    return cmJoin(list_out, separator);
  }
} shellPathNode;

cmGeneratorExpressionNode const* cmGeneratorExpressionNode::GetNode(
  std::string const& identifier)
{
  static std::map<std::string, cmGeneratorExpressionNode const*> const nodeMap{
    { "0", &zeroNode },
    { "1", &oneNode },
    { "AND", &andNode },
    { "OR", &orNode },
    { "NOT", &notNode },
    { "C_COMPILER_ID", &cCompilerIdNode },
    { "CXX_COMPILER_ID", &cxxCompilerIdNode },
    { "OBJC_COMPILER_ID", &objcCompilerIdNode },
    { "OBJCXX_COMPILER_ID", &objcxxCompilerIdNode },
    { "CUDA_COMPILER_ID", &cudaCompilerIdNode },
    { "Fortran_COMPILER_ID", &fortranCompilerIdNode },
    { "HIP_COMPILER_ID", &hipCompilerIdNode },
    { "VERSION_GREATER", &versionGreaterNode },
    { "VERSION_GREATER_EQUAL", &versionGreaterEqNode },
    { "VERSION_LESS", &versionLessNode },
    { "VERSION_LESS_EQUAL", &versionLessEqNode },
    { "VERSION_EQUAL", &versionEqualNode },
    { "C_COMPILER_VERSION", &cCompilerVersionNode },
    { "CXX_COMPILER_VERSION", &cxxCompilerVersionNode },
    { "CUDA_COMPILER_VERSION", &cudaCompilerVersionNode },
    { "OBJC_COMPILER_VERSION", &objcCompilerVersionNode },
    { "OBJCXX_COMPILER_VERSION", &objcxxCompilerVersionNode },
    { "Fortran_COMPILER_VERSION", &fortranCompilerVersionNode },
    { "HIP_COMPILER_VERSION", &hipCompilerVersionNode },
    { "C_COMPILER_FRONTEND_VARIANT", &cCompilerFrontendVariantNode },
    { "CXX_COMPILER_FRONTEND_VARIANT", &cxxCompilerFrontendVariantNode },
    { "CUDA_COMPILER_FRONTEND_VARIANT", &cudaCompilerFrontendVariantNode },
    { "OBJC_COMPILER_FRONTEND_VARIANT", &objcCompilerFrontendVariantNode },
    { "OBJCXX_COMPILER_FRONTEND_VARIANT", &objcxxCompilerFrontendVariantNode },
    { "Fortran_COMPILER_FRONTEND_VARIANT",
      &fortranCompilerFrontendVariantNode },
    { "HIP_COMPILER_FRONTEND_VARIANT", &hipCompilerFrontendVariantNode },
    { "PLATFORM_ID", &platformIdNode },
    { "COMPILE_FEATURES", &compileFeaturesNode },
    { "CONFIGURATION", &configurationNode },
    { "CONFIG", &configurationTestNode },
    { "TARGET_FILE", &targetNodeGroup.File },
    { "TARGET_IMPORT_FILE", &targetImportNodeGroup.File },
    { "TARGET_LINKER_FILE", &targetLinkerNodeGroup.File },
    { "TARGET_LINKER_LIBRARY_FILE", &targetLinkerLibraryNodeGroup.File },
    { "TARGET_LINKER_IMPORT_FILE", &targetLinkerImportNodeGroup.File },
    { "TARGET_SONAME_FILE", &targetSoNameNodeGroup.File },
    { "TARGET_SONAME_IMPORT_FILE", &targetSoNameImportNodeGroup.File },
    { "TARGET_PDB_FILE", &targetPdbNodeGroup.File },
    { "TARGET_FILE_BASE_NAME", &targetFileBaseNameNode },
    { "TARGET_IMPORT_FILE_BASE_NAME", &targetImportFileBaseNameNode },
    { "TARGET_LINKER_FILE_BASE_NAME", &targetLinkerFileBaseNameNode },
    { "TARGET_LINKER_LIBRARY_FILE_BASE_NAME",
      &targetLinkerLibraryFileBaseNameNode },
    { "TARGET_LINKER_IMPORT_FILE_BASE_NAME",
      &targetLinkerImportFileBaseNameNode },
    { "TARGET_PDB_FILE_BASE_NAME", &targetPdbFileBaseNameNode },
    { "TARGET_FILE_PREFIX", &targetFilePrefixNode },
    { "TARGET_IMPORT_FILE_PREFIX", &targetImportFilePrefixNode },
    { "TARGET_LINKER_FILE_PREFIX", &targetLinkerFilePrefixNode },
    { "TARGET_LINKER_LIBRARY_FILE_PREFIX",
      &targetLinkerLibraryFilePrefixNode },
    { "TARGET_LINKER_IMPORT_FILE_PREFIX", &targetLinkerImportFilePrefixNode },
    { "TARGET_FILE_SUFFIX", &targetFileSuffixNode },
    { "TARGET_IMPORT_FILE_SUFFIX", &targetImportFileSuffixNode },
    { "TARGET_LINKER_FILE_SUFFIX", &targetLinkerFileSuffixNode },
    { "TARGET_LINKER_LIBRARY_FILE_SUFFIX",
      &targetLinkerLibraryFileSuffixNode },
    { "TARGET_LINKER_IMPORT_FILE_SUFFIX", &targetLinkerImportFileSuffixNode },
    { "TARGET_FILE_NAME", &targetNodeGroup.FileName },
    { "TARGET_IMPORT_FILE_NAME", &targetImportNodeGroup.FileName },
    { "TARGET_LINKER_FILE_NAME", &targetLinkerNodeGroup.FileName },
    { "TARGET_LINKER_LIBRARY_FILE_NAME",
      &targetLinkerLibraryNodeGroup.FileName },
    { "TARGET_LINKER_IMPORT_FILE_NAME",
      &targetLinkerImportNodeGroup.FileName },
    { "TARGET_SONAME_FILE_NAME", &targetSoNameNodeGroup.FileName },
    { "TARGET_SONAME_IMPORT_FILE_NAME",
      &targetSoNameImportNodeGroup.FileName },
    { "TARGET_PDB_FILE_NAME", &targetPdbNodeGroup.FileName },
    { "TARGET_FILE_DIR", &targetNodeGroup.FileDir },
    { "TARGET_IMPORT_FILE_DIR", &targetImportNodeGroup.FileDir },
    { "TARGET_LINKER_FILE_DIR", &targetLinkerNodeGroup.FileDir },
    { "TARGET_LINKER_LIBRARY_FILE_DIR",
      &targetLinkerLibraryNodeGroup.FileDir },
    { "TARGET_LINKER_IMPORT_FILE_DIR", &targetLinkerImportNodeGroup.FileDir },
    { "TARGET_SONAME_FILE_DIR", &targetSoNameNodeGroup.FileDir },
    { "TARGET_SONAME_IMPORT_FILE_DIR", &targetSoNameImportNodeGroup.FileDir },
    { "TARGET_PDB_FILE_DIR", &targetPdbNodeGroup.FileDir },
    { "TARGET_BUNDLE_DIR", &targetBundleDirNode },
    { "TARGET_BUNDLE_DIR_NAME", &targetBundleDirNameNode },
    { "TARGET_BUNDLE_CONTENT_DIR", &targetBundleContentDirNode },
    { "STREQUAL", &strEqualNode },
    { "STRLESS", &strLessNode },
    { "STRLESS_EQUAL", &strLessEqualNode },
    { "STRGREATER", &strGreaterNode },
    { "STRGREATER_EQUAL", &strGreaterEqualNode },
    { "STRING", &stringNode },
    { "EQUAL", &equalNode },
    { "IN_LIST", &inListNode },
    { "FILTER", &filterNode },
    { "REMOVE_DUPLICATES", &removeDuplicatesNode },
    { "LIST", &listNode },
    { "LOWER_CASE", &lowerCaseNode },
    { "UPPER_CASE", &upperCaseNode },
    { "PATH", &pathNode },
    { "PATH_EQUAL", &pathEqualNode },
    { "MAKE_C_IDENTIFIER", &makeCIdentifierNode },
    { "BOOL", &boolNode },
    { "IF", &ifNode },
    { "ANGLE-R", &angle_rNode },
    { "COMMA", &commaNode },
    { "SEMICOLON", &semicolonNode },
    { "QUOTE", &quoteNode },
    { "TARGET_PROPERTY", &targetPropertyNode },
    { "TARGET_INTERMEDIATE_DIR", &targetIntermediateDirNode },
    { "TARGET_NAME", &targetNameNode },
    { "TARGET_OBJECTS", &targetObjectsNode },
    { "TARGET_POLICY", &targetPolicyNode },
    { "TARGET_EXISTS", &targetExistsNode },
    { "TARGET_NAME_IF_EXISTS", &targetNameIfExistsNode },
    { "TARGET_GENEX_EVAL", &targetGenexEvalNode },
    { "TARGET_RUNTIME_DLLS", &targetRuntimeDllsNode },
    { "TARGET_RUNTIME_DLL_DIRS", &targetRuntimeDllDirsNode },
    { "GENEX_EVAL", &genexEvalNode },
    { "BUILD_INTERFACE", &buildInterfaceNode },
    { "INSTALL_INTERFACE", &installInterfaceNode },
    { "BUILD_LOCAL_INTERFACE", &buildLocalInterfaceNode },
    { "INSTALL_PREFIX", &installPrefixNode },
    { "JOIN", &joinNode },
    { "COMPILE_ONLY", &compileOnlyNode },
    { "LINK_ONLY", &linkOnlyNode },
    { "COMPILE_LANG_AND_ID", &languageAndIdNode },
    { "COMPILE_LANGUAGE", &languageNode },
    { "LINK_LANG_AND_ID", &linkLanguageAndIdNode },
    { "LINK_LANGUAGE", &linkLanguageNode },
    { "C_COMPILER_LINKER_ID", &cCompilerLinkerIdNode },
    { "CXX_COMPILER_LINKER_ID", &cxxCompilerLinkerIdNode },
    { "OBJC_COMPILER_LINKER_ID", &objcCompilerLinkerIdNode },
    { "OBJCXX_COMPILER_LINKER_ID", &objcxxCompilerLinkerIdNode },
    { "CUDA_COMPILER_LINKER_ID", &cudaCompilerLinkerIdNode },
    { "Fortran_COMPILER_LINKER_ID", &fortranCompilerLinkerIdNode },
    { "HIP_COMPILER_LINKER_ID", &hipCompilerLinkerIdNode },
    { "C_COMPILER_LINKER_FRONTEND_VARIANT",
      &cCompilerLinkerFrontendVariantNode },
    { "CXX_COMPILER_LINKER_FRONTEND_VARIANT",
      &cxxCompilerLinkerFrontendVariantNode },
    { "CUDA_COMPILER_LINKER_FRONTEND_VARIANT",
      &cudaCompilerLinkerFrontendVariantNode },
    { "OBJC_COMPILER_LINKER_FRONTEND_VARIANT",
      &objcCompilerLinkerFrontendVariantNode },
    { "OBJCXX_COMPILER_LINKER_FRONTEND_VARIANT",
      &objcxxCompilerLinkerFrontendVariantNode },
    { "Fortran_COMPILER_LINKER_FRONTEND_VARIANT",
      &fortranCompilerLinkerFrontendVariantNode },
    { "HIP_COMPILER_LINKER_FRONTEND_VARIANT",
      &hipCompilerLinkerFrontendVariantNode },
    { "LINK_LIBRARY", &linkLibraryNode },
    { "LINK_GROUP", &linkGroupNode },
    { "HOST_LINK", &hostLinkNode },
    { "DEVICE_LINK", &deviceLinkNode },
    { "SHELL_PATH", &shellPathNode }
  };

  {
    auto itr = nodeMap.find(identifier);
    if (itr != nodeMap.end()) {
      return itr->second;
    }
  }
  return nullptr;
}

void reportError(cm::GenEx::Evaluation* eval, std::string const& expr,
                 std::string const& result)
{
  eval->HadError = true;
  if (eval->Quiet) {
    return;
  }

  std::ostringstream e;
  /* clang-format off */
  e << "Error evaluating generator expression:\n"
    << "  " << expr << "\n"
    << result;
  /* clang-format on */
  eval->Context.LG->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
                                                     e.str(), eval->Backtrace);
}
