소스 검색

Merge topic 'genex-code-cleanup'

3d856eba16 cmGeneratorExpressionNode: refactor TargetPropertyNode
9e1df5df54 cmGeneratorExpressionNode: use ctor arguments instead of macro
36f36d6a49 cmGeneratorExpressionNode: add VersionNode
3f57787dff cmGeneratorExpressionNode: remove structs CompilerId*, CompilerVersion*
20d7c5631e cmGeneratorExpressionNode: add CharacterNode
abd62201bd cmGeneratorExpressionNode: simplify code in EqualNode
f2c8ff8259 cmGeneratorExpressionNode: Simplify static string constant

Acked-by: Kitware Robot <[email protected]>
Merge-request: !3234
Brad King 6 년 전
부모
커밋
e08efc36eb
1개의 변경된 파일175개의 추가작업 그리고 416개의 파일을 삭제
  1. 175 416
      Source/cmGeneratorExpressionNode.cxx

+ 175 - 416
Source/cmGeneratorExpressionNode.cxx

@@ -21,10 +21,13 @@
 #include "cmStateTypes.h"
 #include "cmSystemTools.h"
 #include "cmTarget.h"
+#include "cm_static_string_view.hxx"
+#include "cm_string_view.hxx"
 #include "cmake.h"
 
 #include "cmsys/RegularExpression.hxx"
 #include "cmsys/String.h"
+
 #include <algorithm>
 #include <assert.h>
 #include <errno.h>
@@ -96,36 +99,42 @@ static const struct OneNode buildInterfaceNode;
 
 static const struct ZeroNode installInterfaceNode;
 
-#define BOOLEAN_OP_NODE(OPNAME, OP, SUCCESS_VALUE, FAILURE_VALUE)             \
-  static const struct OP##Node : public cmGeneratorExpressionNode             \
-  {                                                                           \
-    OP##Node() {} /* NOLINT(modernize-use-equals-default) */                  \
-    virtual int NumExpectedParameters() const { return OneOrMoreParameters; } \
-                                                                              \
-    std::string Evaluate(const std::vector<std::string>& parameters,          \
-                         cmGeneratorExpressionContext* context,               \
-                         const GeneratorExpressionContent* content,           \
-                         cmGeneratorExpressionDAGChecker*) const              \
-    {                                                                         \
-      for (std::string const& param : parameters) {                           \
-        if (param == #FAILURE_VALUE) {                                        \
-          return #FAILURE_VALUE;                                              \
-        }                                                                     \
-        if (param != #SUCCESS_VALUE) {                                        \
-          reportError(context, content->GetOriginalExpression(),              \
-                      "Parameters to $<" #OP                                  \
-                      "> must resolve to either '0' or '1'.");                \
-          return std::string();                                               \
-        }                                                                     \
-      }                                                                       \
-      return #SUCCESS_VALUE;                                                  \
-    }                                                                         \
-  } OPNAME;
-
-BOOLEAN_OP_NODE(andNode, AND, 1, 0)
-BOOLEAN_OP_NODE(orNode, OR, 0, 1)
-
-#undef BOOLEAN_OP_NODE
+struct BooleanOpNode : public cmGeneratorExpressionNode
+{
+  BooleanOpNode(const char* op_, const char* successVal_,
+                const char* failureVal_)
+    : op(op_)
+    , successVal(successVal_)
+    , failureVal(failureVal_)
+  {
+  }
+
+  int NumExpectedParameters() const override { return OneOrMoreParameters; }
+
+  std::string Evaluate(const std::vector<std::string>& parameters,
+                       cmGeneratorExpressionContext* context,
+                       const GeneratorExpressionContent* 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(context, content->GetOriginalExpression(), e.str());
+        return std::string();
+      }
+    }
+    return this->successVal;
+  }
+
+  const char *const op, *const successVal, *const failureVal;
+};
+
+static const BooleanOpNode andNode("AND", "1", "0"), orNode("OR", "0", "1");
 
 static const struct NotNode : public cmGeneratorExpressionNode
 {
@@ -212,69 +221,44 @@ static const struct EqualNode : public cmGeneratorExpressionNode
     const GeneratorExpressionContent* content,
     cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
-    char* pEnd;
-
-    int base = 0;
-    bool flipSign = false;
-
-    const char* lhs = parameters[0].c_str();
-    if (cmHasLiteralPrefix(lhs, "0b") || cmHasLiteralPrefix(lhs, "0B")) {
-      base = 2;
-      lhs += 2;
-    }
-    if (cmHasLiteralPrefix(lhs, "-0b") || cmHasLiteralPrefix(lhs, "-0B")) {
-      base = 2;
-      lhs += 3;
-      flipSign = true;
-    }
-    if (cmHasLiteralPrefix(lhs, "+0b") || cmHasLiteralPrefix(lhs, "+0B")) {
-      base = 2;
-      lhs += 3;
-    }
-
-    long lnum = strtol(lhs, &pEnd, base);
-    if (pEnd == lhs || *pEnd != '\0' || errno == ERANGE) {
-      reportError(context, content->GetOriginalExpression(),
-                  "$<EQUAL> parameter " + parameters[0] +
-                    " is not a valid integer.");
-      return std::string();
-    }
-
-    if (flipSign) {
-      lnum = -lnum;
+    long numbers[2];
+    for (int i = 0; i < 2; ++i) {
+      if (!ParameterToLong(parameters[i].c_str(), &numbers[i])) {
+        reportError(context, content->GetOriginalExpression(),
+                    "$<EQUAL> parameter " + parameters[i] +
+                      " is not a valid integer.");
+        return {};
+      }
     }
+    return numbers[0] == numbers[1] ? "1" : "0";
+  }
 
-    base = 0;
-    flipSign = false;
+  static bool ParameterToLong(const char* param, long* outResult)
+  {
+    const char isNegative = param[0] == '-';
 
-    const char* rhs = parameters[1].c_str();
-    if (cmHasLiteralPrefix(rhs, "0b") || cmHasLiteralPrefix(rhs, "0B")) {
-      base = 2;
-      rhs += 2;
-    }
-    if (cmHasLiteralPrefix(rhs, "-0b") || cmHasLiteralPrefix(rhs, "-0B")) {
+    int base = 0;
+    if (cmHasLiteralPrefix(param, "0b") || cmHasLiteralPrefix(param, "0B")) {
       base = 2;
-      rhs += 3;
-      flipSign = true;
-    }
-    if (cmHasLiteralPrefix(rhs, "+0b") || cmHasLiteralPrefix(rhs, "+0B")) {
+      param += 2;
+    } else if (cmHasLiteralPrefix(param, "-0b") ||
+               cmHasLiteralPrefix(param, "-0B") ||
+               cmHasLiteralPrefix(param, "+0b") ||
+               cmHasLiteralPrefix(param, "+0B")) {
       base = 2;
-      rhs += 3;
+      param += 3;
     }
 
-    long rnum = strtol(rhs, &pEnd, base);
-    if (pEnd == rhs || *pEnd != '\0' || errno == ERANGE) {
-      reportError(context, content->GetOriginalExpression(),
-                  "$<EQUAL> parameter " + parameters[1] +
-                    " is not a valid integer.");
-      return std::string();
+    char* pEnd;
+    long result = strtol(param, &pEnd, base);
+    if (pEnd == param || *pEnd != '\0' || errno == ERANGE) {
+      return false;
     }
-
-    if (flipSign) {
-      rnum = -rnum;
+    if (isNegative && result > 0) {
+      result *= -1;
     }
-
-    return lnum == rnum ? "1" : "0";
+    *outResult = result;
+    return true;
   }
 } equalNode;
 
@@ -621,9 +605,10 @@ static const struct MakeCIdentifierNode : public cmGeneratorExpressionNode
   }
 } makeCIdentifierNode;
 
-static const struct Angle_RNode : public cmGeneratorExpressionNode
+template <char C>
+struct CharacterNode : public cmGeneratorExpressionNode
 {
-  Angle_RNode() {} // NOLINT(modernize-use-equals-default)
+  CharacterNode() {} // NOLINT(modernize-use-equals-default)
 
   int NumExpectedParameters() const override { return 0; }
 
@@ -633,47 +618,39 @@ static const struct Angle_RNode : public cmGeneratorExpressionNode
     const GeneratorExpressionContent* /*content*/,
     cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
-    return ">";
+    return { C };
   }
-} angle_rNode;
+};
+static const CharacterNode<'>'> angle_rNode;
+static const CharacterNode<','> commaNode;
+static const CharacterNode<';'> semicolonNode;
 
-static const struct CommaNode : public cmGeneratorExpressionNode
+struct CompilerIdNode : public cmGeneratorExpressionNode
 {
-  CommaNode() {} // NOLINT(modernize-use-equals-default)
-
-  int NumExpectedParameters() const override { return 0; }
-
-  std::string Evaluate(
-    const std::vector<std::string>& /*parameters*/,
-    cmGeneratorExpressionContext* /*context*/,
-    const GeneratorExpressionContent* /*content*/,
-    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
+  CompilerIdNode(const char* compilerLang)
+    : CompilerLanguage(compilerLang)
   {
-    return ",";
   }
-} commaNode;
 
-static const struct SemicolonNode : public cmGeneratorExpressionNode
-{
-  SemicolonNode() {} // NOLINT(modernize-use-equals-default)
-
-  int NumExpectedParameters() const override { return 0; }
+  int NumExpectedParameters() const override { return OneOrZeroParameters; }
 
   std::string Evaluate(
-    const std::vector<std::string>& /*parameters*/,
-    cmGeneratorExpressionContext* /*context*/,
-    const GeneratorExpressionContent* /*content*/,
-    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
+    const std::vector<std::string>& parameters,
+    cmGeneratorExpressionContext* context,
+    const GeneratorExpressionContent* content,
+    cmGeneratorExpressionDAGChecker* dagChecker) const override
   {
-    return ";";
+    if (!context->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(context, content->GetOriginalExpression(), e.str());
+      return {};
+    }
+    return this->EvaluateWithLanguage(parameters, context, content, dagChecker,
+                                      this->CompilerLanguage);
   }
-} semicolonNode;
-
-struct CompilerIdNode : public cmGeneratorExpressionNode
-{
-  CompilerIdNode() {} // NOLINT(modernize-use-equals-default)
-
-  int NumExpectedParameters() const override { return OneOrZeroParameters; }
 
   std::string EvaluateWithLanguage(const std::vector<std::string>& parameters,
                                    cmGeneratorExpressionContext* context,
@@ -721,77 +698,21 @@ struct CompilerIdNode : public cmGeneratorExpressionNode
     }
     return "0";
   }
-};
-
-static const struct CCompilerIdNode : public CompilerIdNode
-{
-  CCompilerIdNode() {} // NOLINT(modernize-use-equals-default)
 
-  std::string Evaluate(
-    const std::vector<std::string>& parameters,
-    cmGeneratorExpressionContext* context,
-    const GeneratorExpressionContent* content,
-    cmGeneratorExpressionDAGChecker* dagChecker) const override
-  {
-    if (!context->HeadTarget) {
-      reportError(
-        context, content->GetOriginalExpression(),
-        "$<C_COMPILER_ID> may only be used with binary targets.  It may "
-        "not be used with add_custom_command or add_custom_target.");
-      return std::string();
-    }
-    return this->EvaluateWithLanguage(parameters, context, content, dagChecker,
-                                      "C");
-  }
-} cCompilerIdNode;
+  const char* const CompilerLanguage;
+};
 
-static const struct CXXCompilerIdNode : public CompilerIdNode
-{
-  CXXCompilerIdNode() {} // NOLINT(modernize-use-equals-default)
+static const CompilerIdNode cCompilerIdNode("C"), cxxCompilerIdNode("CXX"),
+  cudaCompilerIdNode("CUDA"), fortranCompilerIdNode("Fortran");
 
-  std::string Evaluate(
-    const std::vector<std::string>& parameters,
-    cmGeneratorExpressionContext* context,
-    const GeneratorExpressionContent* content,
-    cmGeneratorExpressionDAGChecker* dagChecker) const override
-  {
-    if (!context->HeadTarget) {
-      reportError(
-        context, content->GetOriginalExpression(),
-        "$<CXX_COMPILER_ID> may only be used with binary targets.  It may "
-        "not be used with add_custom_command or add_custom_target.");
-      return std::string();
-    }
-    return this->EvaluateWithLanguage(parameters, context, content, dagChecker,
-                                      "CXX");
-  }
-} cxxCompilerIdNode;
-
-static const struct CUDACompilerIdNode : public CompilerIdNode
+struct CompilerVersionNode : public cmGeneratorExpressionNode
 {
-  CUDACompilerIdNode() {} // NOLINT(modernize-use-equals-default)
-
-  std::string Evaluate(
-    const std::vector<std::string>& parameters,
-    cmGeneratorExpressionContext* context,
-    const GeneratorExpressionContent* content,
-    cmGeneratorExpressionDAGChecker* dagChecker) const override
+  CompilerVersionNode(const char* compilerLang)
+    : CompilerLanguage(compilerLang)
   {
-    if (!context->HeadTarget) {
-      reportError(
-        context, content->GetOriginalExpression(),
-        "$<CUDA_COMPILER_ID> may only be used with binary targets.  It may "
-        "not be used with add_custom_command or add_custom_target.");
-      return std::string();
-    }
-    return this->EvaluateWithLanguage(parameters, context, content, dagChecker,
-                                      "CUDA");
   }
-} cudaCompilerIdNode;
 
-static const struct FortranCompilerIdNode : public CompilerIdNode
-{
-  FortranCompilerIdNode() {} // NOLINT(modernize-use-equals-default)
+  int NumExpectedParameters() const override { return OneOrZeroParameters; }
 
   std::string Evaluate(
     const std::vector<std::string>& parameters,
@@ -800,22 +721,16 @@ static const struct FortranCompilerIdNode : public CompilerIdNode
     cmGeneratorExpressionDAGChecker* dagChecker) const override
   {
     if (!context->HeadTarget) {
-      reportError(
-        context, content->GetOriginalExpression(),
-        "$<Fortran_COMPILER_ID> may only be used with binary targets.  It may "
-        "not be used with add_custom_command or add_custom_target.");
-      return std::string();
+      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(context, content->GetOriginalExpression(), e.str());
+      return {};
     }
     return this->EvaluateWithLanguage(parameters, context, content, dagChecker,
-                                      "Fortran");
+                                      this->CompilerLanguage);
   }
-} fortranCompilerIdNode;
-
-struct CompilerVersionNode : public cmGeneratorExpressionNode
-{
-  CompilerVersionNode() {} // NOLINT(modernize-use-equals-default)
-
-  int NumExpectedParameters() const override { return OneOrZeroParameters; }
 
   std::string EvaluateWithLanguage(const std::vector<std::string>& parameters,
                                    cmGeneratorExpressionContext* context,
@@ -834,7 +749,7 @@ struct CompilerVersionNode : public cmGeneratorExpressionNode
     if (!compilerIdValidator.find(parameters.front())) {
       reportError(context, content->GetOriginalExpression(),
                   "Expression syntax not recognized.");
-      return std::string();
+      return {};
     }
     if (compilerVersion.empty()) {
       return parameters.front().empty() ? "1" : "0";
@@ -846,95 +761,13 @@ struct CompilerVersionNode : public cmGeneratorExpressionNode
       ? "1"
       : "0";
   }
-};
-
-static const struct CCompilerVersionNode : public CompilerVersionNode
-{
-  CCompilerVersionNode() {} // NOLINT(modernize-use-equals-default)
-
-  std::string Evaluate(
-    const std::vector<std::string>& parameters,
-    cmGeneratorExpressionContext* context,
-    const GeneratorExpressionContent* content,
-    cmGeneratorExpressionDAGChecker* dagChecker) const override
-  {
-    if (!context->HeadTarget) {
-      reportError(
-        context, content->GetOriginalExpression(),
-        "$<C_COMPILER_VERSION> may only be used with binary targets.  It "
-        "may not be used with add_custom_command or add_custom_target.");
-      return std::string();
-    }
-    return this->EvaluateWithLanguage(parameters, context, content, dagChecker,
-                                      "C");
-  }
-} cCompilerVersionNode;
 
-static const struct CXXCompilerVersionNode : public CompilerVersionNode
-{
-  CXXCompilerVersionNode() {} // NOLINT(modernize-use-equals-default)
-
-  std::string Evaluate(
-    const std::vector<std::string>& parameters,
-    cmGeneratorExpressionContext* context,
-    const GeneratorExpressionContent* content,
-    cmGeneratorExpressionDAGChecker* dagChecker) const override
-  {
-    if (!context->HeadTarget) {
-      reportError(
-        context, content->GetOriginalExpression(),
-        "$<CXX_COMPILER_VERSION> may only be used with binary targets.  It "
-        "may not be used with add_custom_command or add_custom_target.");
-      return std::string();
-    }
-    return this->EvaluateWithLanguage(parameters, context, content, dagChecker,
-                                      "CXX");
-  }
-} cxxCompilerVersionNode;
-
-static const struct CUDACompilerVersionNode : public CompilerVersionNode
-{
-  CUDACompilerVersionNode() {} // NOLINT(modernize-use-equals-default)
-
-  std::string Evaluate(
-    const std::vector<std::string>& parameters,
-    cmGeneratorExpressionContext* context,
-    const GeneratorExpressionContent* content,
-    cmGeneratorExpressionDAGChecker* dagChecker) const override
-  {
-    if (!context->HeadTarget) {
-      reportError(
-        context, content->GetOriginalExpression(),
-        "$<CUDA_COMPILER_VERSION> may only be used with binary targets.  It "
-        "may not be used with add_custom_command or add_custom_target.");
-      return std::string();
-    }
-    return this->EvaluateWithLanguage(parameters, context, content, dagChecker,
-                                      "CUDA");
-  }
-} cudaCompilerVersionNode;
-
-static const struct FortranCompilerVersionNode : public CompilerVersionNode
-{
-  FortranCompilerVersionNode() {} // NOLINT(modernize-use-equals-default)
+  const char* const CompilerLanguage;
+};
 
-  std::string Evaluate(
-    const std::vector<std::string>& parameters,
-    cmGeneratorExpressionContext* context,
-    const GeneratorExpressionContent* content,
-    cmGeneratorExpressionDAGChecker* dagChecker) const override
-  {
-    if (!context->HeadTarget) {
-      reportError(
-        context, content->GetOriginalExpression(),
-        "$<Fortran_COMPILER_VERSION> may only be used with binary targets.  "
-        "It may not be used with add_custom_command or add_custom_target.");
-      return std::string();
-    }
-    return this->EvaluateWithLanguage(parameters, context, content, dagChecker,
-                                      "Fortran");
-  }
-} fortranCompilerVersionNode;
+static const CompilerVersionNode cCompilerVersionNode("C"),
+  cxxCompilerVersionNode("CXX"), cudaCompilerVersionNode("CUDA"),
+  fortranCompilerVersionNode("Fortran");
 
 struct PlatformIdNode : public cmGeneratorExpressionNode
 {
@@ -965,69 +798,10 @@ struct PlatformIdNode : public cmGeneratorExpressionNode
   }
 } platformIdNode;
 
-static const struct VersionGreaterNode : public cmGeneratorExpressionNode
-{
-  VersionGreaterNode() {} // NOLINT(modernize-use-equals-default)
-
-  int NumExpectedParameters() const override { return 2; }
-
-  std::string Evaluate(
-    const std::vector<std::string>& parameters,
-    cmGeneratorExpressionContext* /*context*/,
-    const GeneratorExpressionContent* /*content*/,
-    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
-  {
-    return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER,
-                                         parameters.front().c_str(),
-                                         parameters[1].c_str())
-      ? "1"
-      : "0";
-  }
-} versionGreaterNode;
-
-static const struct VersionGreaterEqNode : public cmGeneratorExpressionNode
-{
-  VersionGreaterEqNode() {} // NOLINT(modernize-use-equals-default)
-
-  int NumExpectedParameters() const override { return 2; }
-
-  std::string Evaluate(
-    const std::vector<std::string>& parameters,
-    cmGeneratorExpressionContext* /*context*/,
-    const GeneratorExpressionContent* /*content*/,
-    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
-  {
-    return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER_EQUAL,
-                                         parameters.front().c_str(),
-                                         parameters[1].c_str())
-      ? "1"
-      : "0";
-  }
-} versionGreaterEqNode;
-
-static const struct VersionLessNode : public cmGeneratorExpressionNode
-{
-  VersionLessNode() {} // NOLINT(modernize-use-equals-default)
-
-  int NumExpectedParameters() const override { return 2; }
-
-  std::string Evaluate(
-    const std::vector<std::string>& parameters,
-    cmGeneratorExpressionContext* /*context*/,
-    const GeneratorExpressionContent* /*content*/,
-    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
-  {
-    return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS,
-                                         parameters.front().c_str(),
-                                         parameters[1].c_str())
-      ? "1"
-      : "0";
-  }
-} versionLessNode;
-
-static const struct VersionLessEqNode : public cmGeneratorExpressionNode
+template <cmSystemTools::CompareOp Op>
+struct VersionNode : public cmGeneratorExpressionNode
 {
-  VersionLessEqNode() {} // NOLINT(modernize-use-equals-default)
+  VersionNode() {} // NOLINT(modernize-use-equals-default)
 
   int NumExpectedParameters() const override { return 2; }
 
@@ -1037,33 +811,18 @@ static const struct VersionLessEqNode : public cmGeneratorExpressionNode
     const GeneratorExpressionContent* /*content*/,
     cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
   {
-    return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS_EQUAL,
-                                         parameters.front().c_str(),
+    return cmSystemTools::VersionCompare(Op, parameters.front().c_str(),
                                          parameters[1].c_str())
       ? "1"
       : "0";
   }
-} versionLessEqNode;
+};
 
-static const struct VersionEqualNode : public cmGeneratorExpressionNode
-{
-  VersionEqualNode() {} // NOLINT(modernize-use-equals-default)
-
-  int NumExpectedParameters() const override { return 2; }
-
-  std::string Evaluate(
-    const std::vector<std::string>& parameters,
-    cmGeneratorExpressionContext* /*context*/,
-    const GeneratorExpressionContent* /*content*/,
-    cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
-  {
-    return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL,
-                                         parameters.front().c_str(),
-                                         parameters[1].c_str())
-      ? "1"
-      : "0";
-  }
-} versionEqualNode;
+static const VersionNode<cmSystemTools::OP_GREATER> versionGreaterNode;
+static const VersionNode<cmSystemTools::OP_GREATER_EQUAL> versionGreaterEqNode;
+static const VersionNode<cmSystemTools::OP_LESS> versionLessNode;
+static const VersionNode<cmSystemTools::OP_LESS_EQUAL> versionLessEqNode;
+static const VersionNode<cmSystemTools::OP_EQUAL> versionEqualNode;
 
 static const struct LinkOnlyNode : public cmGeneratorExpressionNode
 {
@@ -1270,73 +1029,54 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
   // This node handles errors on parameter count itself.
   int NumExpectedParameters() const override { return OneOrMoreParameters; }
 
+  static const char* 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(
     const std::vector<std::string>& parameters,
     cmGeneratorExpressionContext* context,
     const GeneratorExpressionContent* content,
     cmGeneratorExpressionDAGChecker* dagCheckerParent) const override
   {
-    if (parameters.size() != 1 && parameters.size() != 2) {
-      reportError(
-        context, content->GetOriginalExpression(),
-        "$<TARGET_PROPERTY:...> expression requires one or two parameters");
-      return std::string();
-    }
     static cmsys::RegularExpression propertyNameValidator("^[A-Za-z0-9_]+$");
 
-    cmGeneratorTarget const* target = context->HeadTarget;
-    std::string propertyName = parameters.front();
-
-    if (parameters.size() == 1) {
-      context->HadHeadSensitiveCondition = true;
-    }
-    if (!target && parameters.size() == 1) {
-      reportError(
-        context, 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();
-    }
+    cmGeneratorTarget const* target = nullptr;
+    std::string targetName, propertyName;
 
     if (parameters.size() == 2) {
-      if (parameters.front().empty() && parameters[1].empty()) {
-        reportError(
-          context, content->GetOriginalExpression(),
-          "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty "
-          "target name and property name.");
-        return std::string();
-      }
-      if (parameters.front().empty()) {
-        reportError(
-          context, content->GetOriginalExpression(),
-          "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty "
-          "target name.");
-        return std::string();
-      }
-
-      std::string targetName = parameters.front();
+      targetName = parameters[0];
       propertyName = parameters[1];
-      if (!cmGeneratorExpression::IsValidTargetName(targetName)) {
-        if (!propertyNameValidator.find(propertyName)) {
-          ::reportError(context, content->GetOriginalExpression(),
-                        "Target name and property name not supported.");
-          return std::string();
-        }
-        ::reportError(context, content->GetOriginalExpression(),
-                      "Target name not supported.");
+
+      if (const char* e = GetErrorText(targetName, propertyName)) {
+        reportError(context, content->GetOriginalExpression(), e);
         return std::string();
       }
-      static const std::string propALIASED_TARGET = "ALIASED_TARGET";
-      if (propertyName == propALIASED_TARGET) {
+      if (propertyName == "ALIASED_TARGET"_s) {
         if (context->LG->GetMakefile()->IsAlias(targetName)) {
           if (cmGeneratorTarget* tgt =
                 context->LG->FindGeneratorTargetToUse(targetName)) {
             return tgt->GetName();
           }
         }
-        return "";
+        return std::string();
       }
       target = context->LG->FindGeneratorTargetToUse(targetName);
 
@@ -1347,15 +1087,34 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
         return std::string();
       }
       context->AllTargets.insert(target);
-    }
 
-    if (target == context->HeadTarget) {
+    } else if (parameters.size() == 1) {
+      target = context->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.
       context->SeenTargetProperties.insert(propertyName);
+
+      context->HadHeadSensitiveCondition = true;
+      if (!target) {
+        reportError(
+          context, 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(
+        context, content->GetOriginalExpression(),
+        "$<TARGET_PROPERTY:...> expression requires one or two parameters");
+      return std::string();
     }
+
     if (propertyName == "SOURCES") {
       context->SourceSensitiveTargets.insert(target);
     }