Browse Source

Merge topic 'genex-refactor' into release-4.1

77570a1ac1 GenEx: Consolidate target property evaluation context arguments
1735b0d147 GenEx: Construct cmGeneratorExpressionDAGChecker with full evaluation context
d4d204382f GenEx: Collect evaluation arguments into local Context structures
b40a53e931 GenEx: Factor out a dedicated evaluation Context structure
e1035dc307 GenEx: Rename cmGeneratorExpressionContext to cm::GenEx::Evaluation
905cfcfa12 cmGeneratorExpressionNode: Simplify EvaluateDependentExpression signature
fe8e82090b cmGeneratorExpressionEvaluationFile: Constify some local generator usage
8321178a23 cmFileSet: Constify local generator usage

Acked-by: Kitware Robot <[email protected]>
Acked-by: buildbot <[email protected]>
Merge-request: !11224
Brad King 1 month ago
parent
commit
7cfe68619b
41 changed files with 709 additions and 654 deletions
  1. 4 2
      Source/CMakeLists.txt
  2. 7 6
      Source/cmCommonTargetGenerator.cxx
  3. 16 23
      Source/cmComputeLinkDepends.cxx
  4. 2 3
      Source/cmComputeLinkDepends.h
  5. 6 4
      Source/cmDyndepCollation.cxx
  6. 28 29
      Source/cmEvaluatedTargetProperty.cxx
  7. 12 6
      Source/cmEvaluatedTargetProperty.h
  8. 8 6
      Source/cmExportBuildCMakeConfigGenerator.cxx
  9. 5 4
      Source/cmExportInstallCMakeConfigGenerator.cxx
  10. 6 10
      Source/cmExportTryCompileFileGenerator.cxx
  11. 10 9
      Source/cmFileAPICodemodel.cxx
  12. 10 11
      Source/cmFileSet.cxx
  13. 8 5
      Source/cmFileSet.h
  14. 19 0
      Source/cmGenExContext.cxx
  15. 23 0
      Source/cmGenExContext.h
  16. 27 0
      Source/cmGenExEvaluation.cxx
  17. 13 11
      Source/cmGenExEvaluation.h
  18. 35 26
      Source/cmGeneratorExpression.cxx
  19. 12 3
      Source/cmGeneratorExpression.h
  20. 0 21
      Source/cmGeneratorExpressionContext.cxx
  21. 17 16
      Source/cmGeneratorExpressionDAGChecker.cxx
  22. 9 6
      Source/cmGeneratorExpressionDAGChecker.h
  23. 14 12
      Source/cmGeneratorExpressionEvaluationFile.cxx
  24. 10 6
      Source/cmGeneratorExpressionEvaluationFile.h
  25. 28 30
      Source/cmGeneratorExpressionEvaluator.cxx
  26. 11 7
      Source/cmGeneratorExpressionEvaluator.h
  27. 158 206
      Source/cmGeneratorExpressionNode.cxx
  28. 11 8
      Source/cmGeneratorExpressionNode.h
  29. 30 25
      Source/cmGeneratorTarget.cxx
  30. 11 7
      Source/cmGeneratorTarget.h
  31. 14 21
      Source/cmGeneratorTarget_IncludeDirectories.cxx
  32. 9 10
      Source/cmGeneratorTarget_Link.cxx
  33. 6 4
      Source/cmGeneratorTarget_LinkDirectories.cxx
  34. 41 29
      Source/cmGeneratorTarget_Options.cxx
  35. 22 18
      Source/cmGeneratorTarget_Sources.cxx
  36. 16 15
      Source/cmGeneratorTarget_TargetPropertyEntry.cxx
  37. 27 35
      Source/cmGeneratorTarget_TransitiveProperty.cxx
  38. 7 4
      Source/cmInstallFileSetGenerator.cxx
  39. 4 4
      Source/cmMakefileTargetGenerator.cxx
  40. 11 11
      Source/cmQtAutoGenInitializer.cxx
  41. 2 1
      bootstrap

+ 4 - 2
Source/CMakeLists.txt

@@ -272,9 +272,11 @@ add_library(
   cmGccDepfileLexerHelper.h
   cmGccDepfileLexerHelper.h
   cmGccDepfileReader.cxx
   cmGccDepfileReader.cxx
   cmGccDepfileReader.h
   cmGccDepfileReader.h
+  cmGenExContext.cxx
+  cmGenExContext.h
+  cmGenExEvaluation.cxx
+  cmGenExEvaluation.h
   cmGeneratedFileStream.cxx
   cmGeneratedFileStream.cxx
-  cmGeneratorExpressionContext.cxx
-  cmGeneratorExpressionContext.h
   cmGeneratorExpressionDAGChecker.cxx
   cmGeneratorExpressionDAGChecker.cxx
   cmGeneratorExpressionDAGChecker.h
   cmGeneratorExpressionDAGChecker.h
   cmGeneratorExpressionEvaluationFile.cxx
   cmGeneratorExpressionEvaluationFile.cxx

+ 7 - 6
Source/cmCommonTargetGenerator.cxx

@@ -11,6 +11,7 @@
 #include <cmext/string_view>
 #include <cmext/string_view>
 
 
 #include "cmComputeLinkInformation.h"
 #include "cmComputeLinkInformation.h"
+#include "cmGenExContext.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
@@ -521,13 +522,13 @@ std::string cmCommonTargetGenerator::GetLinkerLauncher(
   std::string propName = lang + "_LINKER_LAUNCHER";
   std::string propName = lang + "_LINKER_LAUNCHER";
   cmValue launcherProp = this->GeneratorTarget->GetProperty(propName);
   cmValue launcherProp = this->GeneratorTarget->GetProperty(propName);
   if (cmNonempty(launcherProp)) {
   if (cmNonempty(launcherProp)) {
-    cmGeneratorExpressionDAGChecker dagChecker{
-      this->GeneratorTarget,      propName, nullptr, nullptr,
-      this->LocalCommonGenerator, config,
-    };
+    cm::GenEx::Context context(this->LocalCommonGenerator, config, lang);
+    cmGeneratorExpressionDAGChecker dagChecker{ this->GeneratorTarget,
+                                                propName, nullptr, nullptr,
+                                                context };
     std::string evaluatedLinklauncher = cmGeneratorExpression::Evaluate(
     std::string evaluatedLinklauncher = cmGeneratorExpression::Evaluate(
-      *launcherProp, this->LocalCommonGenerator, config, this->GeneratorTarget,
-      &dagChecker, this->GeneratorTarget, lang);
+      *launcherProp, context.LG, context.Config, this->GeneratorTarget,
+      &dagChecker, this->GeneratorTarget, context.Language);
     // Convert ;-delimited list to single string
     // Convert ;-delimited list to single string
     cmList args{ evaluatedLinklauncher, cmList::EmptyElements::Yes };
     cmList args{ evaluatedLinklauncher, cmList::EmptyElements::Yes };
     if (!args.empty()) {
     if (!args.empty()) {

+ 16 - 23
Source/cmComputeLinkDepends.cxx

@@ -19,6 +19,7 @@
 #include "cmsys/RegularExpression.hxx"
 #include "cmsys/RegularExpression.hxx"
 
 
 #include "cmComputeComponentGraph.h"
 #include "cmComputeComponentGraph.h"
+#include "cmGenExContext.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
@@ -599,45 +600,42 @@ std::string const& cmComputeLinkDepends::LinkEntry::DEFAULT =
   cmLinkItem::DEFAULT;
   cmLinkItem::DEFAULT;
 
 
 cmComputeLinkDepends::cmComputeLinkDepends(cmGeneratorTarget const* target,
 cmComputeLinkDepends::cmComputeLinkDepends(cmGeneratorTarget const* target,
-                                           std::string const& config,
-                                           std::string const& linkLanguage,
+                                           std::string config,
+                                           std::string linkLanguage,
                                            LinkLibrariesStrategy strategy)
                                            LinkLibrariesStrategy strategy)
   : Target(target)
   : Target(target)
   , Makefile(this->Target->Target->GetMakefile())
   , Makefile(this->Target->Target->GetMakefile())
   , GlobalGenerator(this->Target->GetLocalGenerator()->GetGlobalGenerator())
   , GlobalGenerator(this->Target->GetLocalGenerator()->GetGlobalGenerator())
   , CMakeInstance(this->GlobalGenerator->GetCMakeInstance())
   , CMakeInstance(this->GlobalGenerator->GetCMakeInstance())
-  , Config(config)
+  , Config(std::move(config))
   , DebugMode(this->Makefile->IsOn("CMAKE_LINK_DEPENDS_DEBUG_MODE") ||
   , DebugMode(this->Makefile->IsOn("CMAKE_LINK_DEPENDS_DEBUG_MODE") ||
               this->Target->GetProperty("LINK_DEPENDS_DEBUG_MODE").IsOn())
               this->Target->GetProperty("LINK_DEPENDS_DEBUG_MODE").IsOn())
-  , LinkLanguage(linkLanguage)
+  , LinkLanguage(std::move(linkLanguage))
   , LinkType(ComputeLinkType(
   , LinkType(ComputeLinkType(
       this->Config, this->Makefile->GetCMakeInstance()->GetDebugConfigs()))
       this->Config, this->Makefile->GetCMakeInstance()->GetDebugConfigs()))
   , Strategy(strategy)
   , Strategy(strategy)
 
 
 {
 {
+  cm::GenEx::Context context(this->Target->LocalGenerator, this->Config,
+                             this->LinkLanguage);
   // target oriented feature override property takes precedence over
   // target oriented feature override property takes precedence over
   // global override property
   // global override property
   cm::string_view lloPrefix = "LINK_LIBRARY_OVERRIDE_"_s;
   cm::string_view lloPrefix = "LINK_LIBRARY_OVERRIDE_"_s;
   auto const& keys = this->Target->GetPropertyKeys();
   auto const& keys = this->Target->GetPropertyKeys();
   std::for_each(
   std::for_each(
     keys.cbegin(), keys.cend(),
     keys.cbegin(), keys.cend(),
-    [this, &lloPrefix, &config, &linkLanguage](std::string const& key) {
+    [this, &lloPrefix, &context](std::string const& key) {
       if (cmHasPrefix(key, lloPrefix)) {
       if (cmHasPrefix(key, lloPrefix)) {
         if (cmValue feature = this->Target->GetProperty(key)) {
         if (cmValue feature = this->Target->GetProperty(key)) {
           if (!feature->empty() && key.length() > lloPrefix.length()) {
           if (!feature->empty() && key.length() > lloPrefix.length()) {
             auto item = key.substr(lloPrefix.length());
             auto item = key.substr(lloPrefix.length());
             cmGeneratorExpressionDAGChecker dagChecker{
             cmGeneratorExpressionDAGChecker dagChecker{
-              this->Target,
-              "LINK_LIBRARY_OVERRIDE",
-              nullptr,
-              nullptr,
-              this->Target->GetLocalGenerator(),
-              config,
-              this->Target->GetBacktrace(),
+              this->Target, "LINK_LIBRARY_OVERRIDE",      nullptr, nullptr,
+              context,      this->Target->GetBacktrace(),
             };
             };
             auto overrideFeature = cmGeneratorExpression::Evaluate(
             auto overrideFeature = cmGeneratorExpression::Evaluate(
-              *feature, this->Target->GetLocalGenerator(), config,
-              this->Target, &dagChecker, this->Target, linkLanguage);
+              *feature, context.LG, context.Config, this->Target, &dagChecker,
+              this->Target, context.Language);
             this->LinkLibraryOverride.emplace(item, overrideFeature);
             this->LinkLibraryOverride.emplace(item, overrideFeature);
           }
           }
         }
         }
@@ -647,17 +645,12 @@ cmComputeLinkDepends::cmComputeLinkDepends(cmGeneratorTarget const* target,
   if (cmValue linkLibraryOverride =
   if (cmValue linkLibraryOverride =
         this->Target->GetProperty("LINK_LIBRARY_OVERRIDE")) {
         this->Target->GetProperty("LINK_LIBRARY_OVERRIDE")) {
     cmGeneratorExpressionDAGChecker dagChecker{
     cmGeneratorExpressionDAGChecker dagChecker{
-      target,
-      "LINK_LIBRARY_OVERRIDE",
-      nullptr,
-      nullptr,
-      target->GetLocalGenerator(),
-      config,
-      target->GetBacktrace(),
+      this->Target, "LINK_LIBRARY_OVERRIDE",      nullptr, nullptr,
+      context,      this->Target->GetBacktrace(),
     };
     };
     auto overrideValue = cmGeneratorExpression::Evaluate(
     auto overrideValue = cmGeneratorExpression::Evaluate(
-      *linkLibraryOverride, target->GetLocalGenerator(), config, target,
-      &dagChecker, target, linkLanguage);
+      *linkLibraryOverride, context.LG, context.Config, this->Target,
+      &dagChecker, this->Target, context.Language);
 
 
     std::vector<std::string> overrideList =
     std::vector<std::string> overrideList =
       cmTokenize(overrideValue, ',', cmTokenizerMode::New);
       cmTokenize(overrideValue, ',', cmTokenizerMode::New);

+ 2 - 3
Source/cmComputeLinkDepends.h

@@ -39,9 +39,8 @@ enum class LinkLibrariesStrategy
 class cmComputeLinkDepends
 class cmComputeLinkDepends
 {
 {
 public:
 public:
-  cmComputeLinkDepends(cmGeneratorTarget const* target,
-                       std::string const& config,
-                       std::string const& linkLanguage,
+  cmComputeLinkDepends(cmGeneratorTarget const* target, std::string config,
+                       std::string linkLanguage,
                        LinkLibrariesStrategy strategy);
                        LinkLibrariesStrategy strategy);
   ~cmComputeLinkDepends();
   ~cmComputeLinkDepends();
 
 

+ 6 - 4
Source/cmDyndepCollation.cxx

@@ -20,6 +20,7 @@
 #include "cmExportBuildFileGenerator.h"
 #include "cmExportBuildFileGenerator.h"
 #include "cmExportSet.h"
 #include "cmExportSet.h"
 #include "cmFileSet.h"
 #include "cmFileSet.h"
+#include "cmGenExContext.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorExpression.h" // IWYU pragma: keep
 #include "cmGeneratorExpression.h" // IWYU pragma: keep
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
@@ -50,6 +51,7 @@ TdiSourceInfo CollationInformationSources(cmGeneratorTarget const* gt,
                                           std::string const& config,
                                           std::string const& config,
                                           cmDyndepGeneratorCallbacks const& cb)
                                           cmDyndepGeneratorCallbacks const& cb)
 {
 {
+  cm::GenEx::Context const context(gt->LocalGenerator, config);
   TdiSourceInfo info;
   TdiSourceInfo info;
   cmTarget const* tgt = gt->Target;
   cmTarget const* tgt = gt->Target;
   auto all_file_sets = tgt->GetAllFileSetNames();
   auto all_file_sets = tgt->GetAllFileSetNames();
@@ -108,12 +110,12 @@ TdiSourceInfo CollationInformationSources(cmGeneratorTarget const* gt,
     auto fileEntries = file_set->CompileFileEntries();
     auto fileEntries = file_set->CompileFileEntries();
     auto directoryEntries = file_set->CompileDirectoryEntries();
     auto directoryEntries = file_set->CompileDirectoryEntries();
 
 
-    auto directories = file_set->EvaluateDirectoryEntries(
-      directoryEntries, gt->LocalGenerator, config, gt);
+    auto directories =
+      file_set->EvaluateDirectoryEntries(directoryEntries, context, gt);
     std::map<std::string, std::vector<std::string>> files_per_dirs;
     std::map<std::string, std::vector<std::string>> files_per_dirs;
     for (auto const& entry : fileEntries) {
     for (auto const& entry : fileEntries) {
-      file_set->EvaluateFileEntry(directories, files_per_dirs, entry,
-                                  gt->LocalGenerator, config, gt);
+      file_set->EvaluateFileEntry(directories, files_per_dirs, entry, context,
+                                  gt);
     }
     }
 
 
     Json::Value fs_dest = Json::nullValue;
     Json::Value fs_dest = Json::nullValue;

+ 28 - 29
Source/cmEvaluatedTargetProperty.cxx

@@ -5,7 +5,8 @@
 #include <unordered_map>
 #include <unordered_map>
 #include <utility>
 #include <utility>
 
 
-#include "cmGeneratorExpressionContext.h"
+#include "cmGenExContext.h"
+#include "cmGenExEvaluation.h"
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
 #include "cmLinkItem.h"
 #include "cmLinkItem.h"
 #include "cmList.h"
 #include "cmList.h"
@@ -20,14 +21,12 @@ EvaluatedTargetPropertyEntry::EvaluatedTargetPropertyEntry(
 }
 }
 
 
 EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry(
 EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry(
-  cmGeneratorTarget const* thisTarget, std::string const& config,
-  std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker,
+  cmGeneratorTarget const* thisTarget, cm::GenEx::Context const& context,
+  cmGeneratorExpressionDAGChecker* dagChecker,
   cmGeneratorTarget::TargetPropertyEntry& entry)
   cmGeneratorTarget::TargetPropertyEntry& entry)
 {
 {
   EvaluatedTargetPropertyEntry ee(entry.LinkImplItem, entry.GetBacktrace());
   EvaluatedTargetPropertyEntry ee(entry.LinkImplItem, entry.GetBacktrace());
-  cmExpandList(entry.Evaluate(thisTarget->GetLocalGenerator(), config,
-                              thisTarget, dagChecker, lang),
-               ee.Values);
+  cmExpandList(entry.Evaluate(context, thisTarget, dagChecker), ee.Values);
   if (entry.GetHadContextSensitiveCondition()) {
   if (entry.GetHadContextSensitiveCondition()) {
     ee.ContextDependent = true;
     ee.ContextDependent = true;
   }
   }
@@ -35,24 +34,24 @@ EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry(
 }
 }
 
 
 EvaluatedTargetPropertyEntries EvaluateTargetPropertyEntries(
 EvaluatedTargetPropertyEntries EvaluateTargetPropertyEntries(
-  cmGeneratorTarget const* thisTarget, std::string const& config,
-  std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker,
+  cmGeneratorTarget const* thisTarget, cm::GenEx::Context const& context,
+  cmGeneratorExpressionDAGChecker* dagChecker,
   std::vector<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>> const&
   std::vector<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>> const&
     in)
     in)
 {
 {
   EvaluatedTargetPropertyEntries out;
   EvaluatedTargetPropertyEntries out;
   out.Entries.reserve(in.size());
   out.Entries.reserve(in.size());
   for (auto const& entry : in) {
   for (auto const& entry : in) {
-    out.Entries.emplace_back(EvaluateTargetPropertyEntry(
-      thisTarget, config, lang, dagChecker, *entry));
+    out.Entries.emplace_back(
+      EvaluateTargetPropertyEntry(thisTarget, context, dagChecker, *entry));
   }
   }
   return out;
   return out;
 }
 }
 
 
 namespace {
 namespace {
 void addInterfaceEntry(cmGeneratorTarget const* headTarget,
 void addInterfaceEntry(cmGeneratorTarget const* headTarget,
-                       std::string const& config, std::string const& prop,
-                       std::string const& lang,
+                       std::string const& prop,
+                       cm::GenEx::Context const& context,
                        cmGeneratorExpressionDAGChecker* dagChecker,
                        cmGeneratorExpressionDAGChecker* dagChecker,
                        EvaluatedTargetPropertyEntries& entries,
                        EvaluatedTargetPropertyEntries& entries,
                        cmGeneratorTarget::UseTo usage,
                        cmGeneratorTarget::UseTo usage,
@@ -64,13 +63,12 @@ void addInterfaceEntry(cmGeneratorTarget const* headTarget,
       // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in our
       // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in our
       // caller's property and hand-evaluate it as if it were compiled.
       // caller's property and hand-evaluate it as if it were compiled.
       // Create a context as cmCompiledGeneratorExpression::Evaluate does.
       // Create a context as cmCompiledGeneratorExpression::Evaluate does.
-      cmGeneratorExpressionContext context(
-        headTarget->GetLocalGenerator(), config, false, headTarget, headTarget,
-        true, lib.Backtrace, lang);
-      cmExpandList(lib.Target->EvaluateInterfaceProperty(prop, &context,
-                                                         dagChecker, usage),
-                   ee.Values);
-      ee.ContextDependent = context.HadContextSensitiveCondition;
+      cm::GenEx::Evaluation eval(context, false, headTarget, headTarget, true,
+                                 lib.Backtrace);
+      cmExpandList(
+        lib.Target->EvaluateInterfaceProperty(prop, &eval, dagChecker, usage),
+        ee.Values);
+      ee.ContextDependent = eval.HadContextSensitiveCondition;
       entries.Entries.emplace_back(std::move(ee));
       entries.Entries.emplace_back(std::move(ee));
     }
     }
   }
   }
@@ -78,8 +76,8 @@ void addInterfaceEntry(cmGeneratorTarget const* headTarget,
 }
 }
 
 
 void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
 void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
-                         std::string const& config, std::string const& prop,
-                         std::string const& lang,
+                         std::string const& prop,
+                         cm::GenEx::Context const& context,
                          cmGeneratorExpressionDAGChecker* dagChecker,
                          cmGeneratorExpressionDAGChecker* dagChecker,
                          EvaluatedTargetPropertyEntries& entries,
                          EvaluatedTargetPropertyEntries& entries,
                          IncludeRuntimeInterface searchRuntime,
                          IncludeRuntimeInterface searchRuntime,
@@ -87,25 +85,26 @@ void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
 {
 {
   if (searchRuntime == IncludeRuntimeInterface::Yes) {
   if (searchRuntime == IncludeRuntimeInterface::Yes) {
     if (cmLinkImplementation const* impl =
     if (cmLinkImplementation const* impl =
-          headTarget->GetLinkImplementation(config, usage)) {
+          headTarget->GetLinkImplementation(context.Config, usage)) {
       entries.HadContextSensitiveCondition =
       entries.HadContextSensitiveCondition =
         impl->HadContextSensitiveCondition;
         impl->HadContextSensitiveCondition;
 
 
-      auto runtimeLibIt = impl->LanguageRuntimeLibraries.find(lang);
+      auto runtimeLibIt =
+        impl->LanguageRuntimeLibraries.find(context.Language);
       if (runtimeLibIt != impl->LanguageRuntimeLibraries.end()) {
       if (runtimeLibIt != impl->LanguageRuntimeLibraries.end()) {
-        addInterfaceEntry(headTarget, config, prop, lang, dagChecker, entries,
+        addInterfaceEntry(headTarget, prop, context, dagChecker, entries,
                           usage, runtimeLibIt->second);
                           usage, runtimeLibIt->second);
       }
       }
-      addInterfaceEntry(headTarget, config, prop, lang, dagChecker, entries,
-                        usage, impl->Libraries);
+      addInterfaceEntry(headTarget, prop, context, dagChecker, entries, usage,
+                        impl->Libraries);
     }
     }
   } else {
   } else {
     if (cmLinkImplementationLibraries const* impl =
     if (cmLinkImplementationLibraries const* impl =
-          headTarget->GetLinkImplementationLibraries(config, usage)) {
+          headTarget->GetLinkImplementationLibraries(context.Config, usage)) {
       entries.HadContextSensitiveCondition =
       entries.HadContextSensitiveCondition =
         impl->HadContextSensitiveCondition;
         impl->HadContextSensitiveCondition;
-      addInterfaceEntry(headTarget, config, prop, lang, dagChecker, entries,
-                        usage, impl->Libraries);
+      addInterfaceEntry(headTarget, prop, context, dagChecker, entries, usage,
+                        impl->Libraries);
     }
     }
   }
   }
 }
 }

+ 12 - 6
Source/cmEvaluatedTargetProperty.h

@@ -9,6 +9,12 @@
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
 #include "cmListFileCache.h"
 #include "cmListFileCache.h"
 
 
+namespace cm {
+namespace GenEx {
+struct Context;
+}
+}
+
 class cmLinkImplItem;
 class cmLinkImplItem;
 struct cmGeneratorExpressionDAGChecker;
 struct cmGeneratorExpressionDAGChecker;
 
 
@@ -34,8 +40,8 @@ struct EvaluatedTargetPropertyEntry
 };
 };
 
 
 EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry(
 EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry(
-  cmGeneratorTarget const* thisTarget, std::string const& config,
-  std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker,
+  cmGeneratorTarget const* thisTarget, cm::GenEx::Context const& context,
+  cmGeneratorExpressionDAGChecker* dagChecker,
   cmGeneratorTarget::TargetPropertyEntry& entry);
   cmGeneratorTarget::TargetPropertyEntry& entry);
 
 
 struct EvaluatedTargetPropertyEntries
 struct EvaluatedTargetPropertyEntries
@@ -45,8 +51,8 @@ struct EvaluatedTargetPropertyEntries
 };
 };
 
 
 EvaluatedTargetPropertyEntries EvaluateTargetPropertyEntries(
 EvaluatedTargetPropertyEntries EvaluateTargetPropertyEntries(
-  cmGeneratorTarget const* thisTarget, std::string const& config,
-  std::string const& lang, cmGeneratorExpressionDAGChecker* dagChecker,
+  cmGeneratorTarget const* thisTarget, cm::GenEx::Context const& context,
+  cmGeneratorExpressionDAGChecker* dagChecker,
   std::vector<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>> const&
   std::vector<std::unique_ptr<cmGeneratorTarget::TargetPropertyEntry>> const&
     in);
     in);
 
 
@@ -71,8 +77,8 @@ enum class IncludeRuntimeInterface
 };
 };
 
 
 void AddInterfaceEntries(
 void AddInterfaceEntries(
-  cmGeneratorTarget const* headTarget, std::string const& config,
-  std::string const& prop, std::string const& lang,
+  cmGeneratorTarget const* headTarget, std::string const& prop,
+  cm::GenEx::Context const& context,
   cmGeneratorExpressionDAGChecker* dagChecker,
   cmGeneratorExpressionDAGChecker* dagChecker,
   EvaluatedTargetPropertyEntries& entries,
   EvaluatedTargetPropertyEntries& entries,
   IncludeRuntimeInterface searchRuntime,
   IncludeRuntimeInterface searchRuntime,

+ 8 - 6
Source/cmExportBuildCMakeConfigGenerator.cxx

@@ -17,6 +17,7 @@
 #include "cmCryptoHash.h"
 #include "cmCryptoHash.h"
 #include "cmExportSet.h"
 #include "cmExportSet.h"
 #include "cmFileSet.h"
 #include "cmFileSet.h"
+#include "cmGenExContext.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
@@ -176,8 +177,9 @@ std::string cmExportBuildCMakeConfigGenerator::GetFileSetDirectories(
   auto directoryEntries = fileSet->CompileDirectoryEntries();
   auto directoryEntries = fileSet->CompileDirectoryEntries();
 
 
   for (auto const& config : configs) {
   for (auto const& config : configs) {
-    auto directories = fileSet->EvaluateDirectoryEntries(
-      directoryEntries, gte->LocalGenerator, config, gte);
+    cm::GenEx::Context context(gte->LocalGenerator, config);
+    auto directories =
+      fileSet->EvaluateDirectoryEntries(directoryEntries, context, gte);
 
 
     bool const contextSensitive =
     bool const contextSensitive =
       std::any_of(directoryEntries.begin(), directoryEntries.end(),
       std::any_of(directoryEntries.begin(), directoryEntries.end(),
@@ -226,13 +228,13 @@ std::string cmExportBuildCMakeConfigGenerator::GetFileSetFiles(
   auto directoryEntries = fileSet->CompileDirectoryEntries();
   auto directoryEntries = fileSet->CompileDirectoryEntries();
 
 
   for (auto const& config : configs) {
   for (auto const& config : configs) {
-    auto directories = fileSet->EvaluateDirectoryEntries(
-      directoryEntries, gte->LocalGenerator, config, gte);
+    cm::GenEx::Context context(gte->LocalGenerator, config);
+    auto directories =
+      fileSet->EvaluateDirectoryEntries(directoryEntries, context, gte);
 
 
     std::map<std::string, std::vector<std::string>> files;
     std::map<std::string, std::vector<std::string>> files;
     for (auto const& entry : fileEntries) {
     for (auto const& entry : fileEntries) {
-      fileSet->EvaluateFileEntry(directories, files, entry,
-                                 gte->LocalGenerator, config, gte);
+      fileSet->EvaluateFileEntry(directories, files, entry, context, gte);
     }
     }
 
 
     bool const contextSensitive =
     bool const contextSensitive =

+ 5 - 4
Source/cmExportInstallCMakeConfigGenerator.cxx

@@ -16,6 +16,7 @@
 #include "cmExportFileGenerator.h"
 #include "cmExportFileGenerator.h"
 #include "cmExportSet.h"
 #include "cmExportSet.h"
 #include "cmFileSet.h"
 #include "cmFileSet.h"
+#include "cmGenExContext.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
@@ -339,13 +340,13 @@ std::string cmExportInstallCMakeConfigGenerator::GetFileSetFiles(
     te->FileSetGenerators.at(fileSet->GetName())->GetDestination());
     te->FileSetGenerators.at(fileSet->GetName())->GetDestination());
 
 
   for (auto const& config : configs) {
   for (auto const& config : configs) {
-    auto directories = fileSet->EvaluateDirectoryEntries(
-      directoryEntries, gte->LocalGenerator, config, gte);
+    cm::GenEx::Context context(gte->LocalGenerator, config);
+    auto directories =
+      fileSet->EvaluateDirectoryEntries(directoryEntries, context, gte);
 
 
     std::map<std::string, std::vector<std::string>> files;
     std::map<std::string, std::vector<std::string>> files;
     for (auto const& entry : fileEntries) {
     for (auto const& entry : fileEntries) {
-      fileSet->EvaluateFileEntry(directories, files, entry,
-                                 gte->LocalGenerator, config, gte);
+      fileSet->EvaluateFileEntry(directories, files, entry, context, gte);
     }
     }
     auto unescapedDest = destCge->Evaluate(gte->LocalGenerator, config, gte);
     auto unescapedDest = destCge->Evaluate(gte->LocalGenerator, config, gte);
     auto dest =
     auto dest =

+ 6 - 10
Source/cmExportTryCompileFileGenerator.cxx

@@ -9,6 +9,7 @@
 #include <cm/string_view>
 #include <cm/string_view>
 
 
 #include "cmFileSet.h"
 #include "cmFileSet.h"
+#include "cmGenExContext.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
@@ -76,6 +77,8 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
     return std::string();
     return std::string();
   }
   }
 
 
+  cm::GenEx::Context context(tgt->LocalGenerator, this->Config, language);
+
   cmGeneratorExpression ge(*tgt->Makefile->GetCMakeInstance());
   cmGeneratorExpression ge(*tgt->Makefile->GetCMakeInstance());
 
 
   std::unique_ptr<cmGeneratorExpressionDAGChecker> parentDagChecker;
   std::unique_ptr<cmGeneratorExpressionDAGChecker> parentDagChecker;
@@ -83,16 +86,10 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
     // To please constraint checks of DAGChecker, this property must have
     // To please constraint checks of DAGChecker, this property must have
     // LINK_OPTIONS property as parent
     // LINK_OPTIONS property as parent
     parentDagChecker = cm::make_unique<cmGeneratorExpressionDAGChecker>(
     parentDagChecker = cm::make_unique<cmGeneratorExpressionDAGChecker>(
-      tgt, "LINK_OPTIONS", nullptr, nullptr, tgt->GetLocalGenerator(),
-      this->Config);
+      tgt, "LINK_OPTIONS", nullptr, nullptr, context);
   }
   }
   cmGeneratorExpressionDAGChecker dagChecker{
   cmGeneratorExpressionDAGChecker dagChecker{
-    tgt,
-    propName,
-    nullptr,
-    parentDagChecker.get(),
-    tgt->GetLocalGenerator(),
-    this->Config,
+    tgt, propName, nullptr, parentDagChecker.get(), context,
   };
   };
 
 
   std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*prop);
   std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(*prop);
@@ -103,8 +100,7 @@ std::string cmExportTryCompileFileGenerator::FindTargets(
 
 
   cmGeneratorTarget gDummyHead(&dummyHead, tgt->GetLocalGenerator());
   cmGeneratorTarget gDummyHead(&dummyHead, tgt->GetLocalGenerator());
 
 
-  std::string result = cge->Evaluate(tgt->GetLocalGenerator(), this->Config,
-                                     &gDummyHead, &dagChecker, tgt, language);
+  std::string result = cge->Evaluate(context, &dagChecker, &gDummyHead, tgt);
 
 
   std::set<cmGeneratorTarget const*> const& allTargets =
   std::set<cmGeneratorTarget const*> const& allTargets =
     cge->GetAllTargetsSeen();
     cge->GetAllTargetsSeen();

+ 10 - 9
Source/cmFileAPICodemodel.cxx

@@ -24,6 +24,7 @@
 #include "cmExportSet.h"
 #include "cmExportSet.h"
 #include "cmFileAPI.h"
 #include "cmFileAPI.h"
 #include "cmFileSet.h"
 #include "cmFileSet.h"
+#include "cmGenExContext.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalGenerator.h"
 #include "cmGlobalGenerator.h"
@@ -1080,16 +1081,15 @@ Json::Value DirectoryObject::DumpInstaller(cmInstallGenerator* gen)
 
 
     auto* target = installFileSet->GetTarget();
     auto* target = installFileSet->GetTarget();
 
 
+    cm::GenEx::Context context(target->LocalGenerator, this->Config);
+
     auto dirCges = fileSet->CompileDirectoryEntries();
     auto dirCges = fileSet->CompileDirectoryEntries();
-    auto dirs = fileSet->EvaluateDirectoryEntries(
-      dirCges, target->GetLocalGenerator(), this->Config, target);
+    auto dirs = fileSet->EvaluateDirectoryEntries(dirCges, context, target);
 
 
     auto entryCges = fileSet->CompileFileEntries();
     auto entryCges = fileSet->CompileFileEntries();
     std::map<std::string, std::vector<std::string>> entries;
     std::map<std::string, std::vector<std::string>> entries;
     for (auto const& entryCge : entryCges) {
     for (auto const& entryCge : entryCges) {
-      fileSet->EvaluateFileEntry(dirs, entries, entryCge,
-                                 target->GetLocalGenerator(), this->Config,
-                                 target);
+      fileSet->EvaluateFileEntry(dirs, entries, entryCge, context, target);
     }
     }
 
 
     Json::Value files = Json::arrayValue;
     Json::Value files = Json::arrayValue;
@@ -1608,18 +1608,19 @@ std::pair<Json::Value, Target::FileSetDatabase> Target::DumpFileSets()
         continue;
         continue;
       }
       }
 
 
+      cm::GenEx::Context context(this->GT->LocalGenerator, this->Config);
+
       auto fileEntries = fs->CompileFileEntries();
       auto fileEntries = fs->CompileFileEntries();
       auto directoryEntries = fs->CompileDirectoryEntries();
       auto directoryEntries = fs->CompileDirectoryEntries();
 
 
-      auto directories = fs->EvaluateDirectoryEntries(
-        directoryEntries, this->GT->LocalGenerator, this->Config, this->GT);
+      auto directories =
+        fs->EvaluateDirectoryEntries(directoryEntries, context, this->GT);
 
 
       fsJson.append(this->DumpFileSet(fs, directories));
       fsJson.append(this->DumpFileSet(fs, directories));
 
 
       std::map<std::string, std::vector<std::string>> files_per_dirs;
       std::map<std::string, std::vector<std::string>> files_per_dirs;
       for (auto const& entry : fileEntries) {
       for (auto const& entry : fileEntries) {
-        fs->EvaluateFileEntry(directories, files_per_dirs, entry,
-                              this->GT->LocalGenerator, this->Config,
+        fs->EvaluateFileEntry(directories, files_per_dirs, entry, context,
                               this->GT);
                               this->GT);
       }
       }
 
 

+ 10 - 11
Source/cmFileSet.cxx

@@ -14,6 +14,7 @@
 
 
 #include "cmsys/RegularExpression.hxx"
 #include "cmsys/RegularExpression.hxx"
 
 
+#include "cmGenExContext.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpression.h"
 #include "cmList.h"
 #include "cmList.h"
 #include "cmListFileCache.h"
 #include "cmListFileCache.h"
@@ -156,8 +157,7 @@ cmFileSet::CompileDirectoryEntries() const
 
 
 std::vector<std::string> cmFileSet::EvaluateDirectoryEntries(
 std::vector<std::string> cmFileSet::EvaluateDirectoryEntries(
   std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> const& cges,
   std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> const& cges,
-  cmLocalGenerator* lg, std::string const& config,
-  cmGeneratorTarget const* target,
+  cm::GenEx::Context const& context, cmGeneratorTarget const* target,
   cmGeneratorExpressionDAGChecker* dagChecker) const
   cmGeneratorExpressionDAGChecker* dagChecker) const
 {
 {
   struct DirCacheEntry
   struct DirCacheEntry
@@ -169,11 +169,11 @@ std::vector<std::string> cmFileSet::EvaluateDirectoryEntries(
   std::unordered_map<std::string, DirCacheEntry> dirCache;
   std::unordered_map<std::string, DirCacheEntry> dirCache;
   std::vector<std::string> result;
   std::vector<std::string> result;
   for (auto const& cge : cges) {
   for (auto const& cge : cges) {
-    auto entry = cge->Evaluate(lg, config, target, dagChecker);
+    auto entry = cge->Evaluate(context, dagChecker, target);
     cmList dirs{ entry };
     cmList dirs{ entry };
     for (std::string dir : dirs) {
     for (std::string dir : dirs) {
       if (!cmSystemTools::FileIsFullPath(dir)) {
       if (!cmSystemTools::FileIsFullPath(dir)) {
-        dir = cmStrCat(lg->GetCurrentSourceDirectory(), '/', dir);
+        dir = cmStrCat(context.LG->GetCurrentSourceDirectory(), '/', dir);
       }
       }
 
 
       auto dirCacheResult = dirCache.emplace(dir, DirCacheEntry());
       auto dirCacheResult = dirCache.emplace(dir, DirCacheEntry());
@@ -198,7 +198,7 @@ std::vector<std::string> cmFileSet::EvaluateDirectoryEntries(
                                            priorDirCacheEntry.collapsedDir) ||
                                            priorDirCacheEntry.collapsedDir) ||
              cmSystemTools::IsSubDirectory(priorDirCacheEntry.collapsedDir,
              cmSystemTools::IsSubDirectory(priorDirCacheEntry.collapsedDir,
                                            dirCacheEntry.collapsedDir))) {
                                            dirCacheEntry.collapsedDir))) {
-          lg->GetCMakeInstance()->IssueMessage(
+          context.LG->GetCMakeInstance()->IssueMessage(
             MessageType::FATAL_ERROR,
             MessageType::FATAL_ERROR,
             cmStrCat(
             cmStrCat(
               "Base directories in file set cannot be subdirectories of each "
               "Base directories in file set cannot be subdirectories of each "
@@ -218,14 +218,13 @@ void cmFileSet::EvaluateFileEntry(
   std::vector<std::string> const& dirs,
   std::vector<std::string> const& dirs,
   std::map<std::string, std::vector<std::string>>& filesPerDir,
   std::map<std::string, std::vector<std::string>>& filesPerDir,
   std::unique_ptr<cmCompiledGeneratorExpression> const& cge,
   std::unique_ptr<cmCompiledGeneratorExpression> const& cge,
-  cmLocalGenerator* lg, std::string const& config,
-  cmGeneratorTarget const* target,
+  cm::GenEx::Context const& context, cmGeneratorTarget const* target,
   cmGeneratorExpressionDAGChecker* dagChecker) const
   cmGeneratorExpressionDAGChecker* dagChecker) const
 {
 {
-  auto files = cge->Evaluate(lg, config, target, dagChecker);
+  auto files = cge->Evaluate(context, dagChecker, target);
   for (std::string file : cmList{ files }) {
   for (std::string file : cmList{ files }) {
     if (!cmSystemTools::FileIsFullPath(file)) {
     if (!cmSystemTools::FileIsFullPath(file)) {
-      file = cmStrCat(lg->GetCurrentSourceDirectory(), '/', file);
+      file = cmStrCat(context.LG->GetCurrentSourceDirectory(), '/', file);
     }
     }
     auto collapsedFile = cmSystemTools::CollapseFullPath(file);
     auto collapsedFile = cmSystemTools::CollapseFullPath(file);
     bool found = false;
     bool found = false;
@@ -246,8 +245,8 @@ void cmFileSet::EvaluateFileEntry(
       for (auto const& dir : dirs) {
       for (auto const& dir : dirs) {
         e << "\n  " << dir;
         e << "\n  " << dir;
       }
       }
-      lg->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str(),
-                                           cge->GetBacktrace());
+      context.LG->GetCMakeInstance()->IssueMessage(
+        MessageType::FATAL_ERROR, e.str(), cge->GetBacktrace());
       return;
       return;
     }
     }
 
 

+ 8 - 5
Source/cmFileSet.h

@@ -12,10 +12,15 @@
 
 
 #include "cmListFileCache.h"
 #include "cmListFileCache.h"
 
 
+namespace cm {
+namespace GenEx {
+struct Context;
+}
+}
+
 class cmCompiledGeneratorExpression;
 class cmCompiledGeneratorExpression;
 struct cmGeneratorExpressionDAGChecker;
 struct cmGeneratorExpressionDAGChecker;
 class cmGeneratorTarget;
 class cmGeneratorTarget;
-class cmLocalGenerator;
 class cmMakefile;
 class cmMakefile;
 class cmake;
 class cmake;
 
 
@@ -67,16 +72,14 @@ public:
 
 
   std::vector<std::string> EvaluateDirectoryEntries(
   std::vector<std::string> EvaluateDirectoryEntries(
     std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> const& cges,
     std::vector<std::unique_ptr<cmCompiledGeneratorExpression>> const& cges,
-    cmLocalGenerator* lg, std::string const& config,
-    cmGeneratorTarget const* target,
+    cm::GenEx::Context const& context, cmGeneratorTarget const* target,
     cmGeneratorExpressionDAGChecker* dagChecker = nullptr) const;
     cmGeneratorExpressionDAGChecker* dagChecker = nullptr) const;
 
 
   void EvaluateFileEntry(
   void EvaluateFileEntry(
     std::vector<std::string> const& dirs,
     std::vector<std::string> const& dirs,
     std::map<std::string, std::vector<std::string>>& filesPerDir,
     std::map<std::string, std::vector<std::string>>& filesPerDir,
     std::unique_ptr<cmCompiledGeneratorExpression> const& cge,
     std::unique_ptr<cmCompiledGeneratorExpression> const& cge,
-    cmLocalGenerator* lg, std::string const& config,
-    cmGeneratorTarget const* target,
+    cm::GenEx::Context const& context, cmGeneratorTarget const* target,
     cmGeneratorExpressionDAGChecker* dagChecker = nullptr) const;
     cmGeneratorExpressionDAGChecker* dagChecker = nullptr) const;
 
 
   static bool IsValidName(std::string const& name);
   static bool IsValidName(std::string const& name);

+ 19 - 0
Source/cmGenExContext.cxx

@@ -0,0 +1,19 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+#include "cmGenExContext.h"
+
+#include <utility>
+
+namespace cm {
+namespace GenEx {
+
+Context::Context(cmLocalGenerator const* lg, std::string config,
+                 std::string language)
+  : LG(lg)
+  , Config(std::move(config))
+  , Language(std::move(language))
+{
+}
+
+}
+}

+ 23 - 0
Source/cmGenExContext.h

@@ -0,0 +1,23 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+#pragma once
+
+#include <string>
+
+class cmLocalGenerator;
+
+namespace cm {
+namespace GenEx {
+
+struct Context final
+{
+  Context(cmLocalGenerator const* lg, std::string config,
+          std::string language = std::string());
+
+  cmLocalGenerator const* LG;
+  std::string Config;
+  std::string Language;
+};
+
+}
+}

+ 27 - 0
Source/cmGenExEvaluation.cxx

@@ -0,0 +1,27 @@
+/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+   file LICENSE.rst or https://cmake.org/licensing for details.  */
+#include "cmGenExEvaluation.h"
+
+#include <utility>
+
+#include "cmGenExContext.h"
+
+namespace cm {
+namespace GenEx {
+
+Evaluation::Evaluation(GenEx::Context context, bool quiet,
+                       cmGeneratorTarget const* headTarget,
+                       cmGeneratorTarget const* currentTarget,
+                       bool evaluateForBuildsystem,
+                       cmListFileBacktrace backtrace)
+  : Context(std::move(context))
+  , Backtrace(std::move(backtrace))
+  , HeadTarget(headTarget)
+  , CurrentTarget(currentTarget)
+  , Quiet(quiet)
+  , EvaluateForBuildsystem(evaluateForBuildsystem)
+{
+}
+
+}
+}

+ 13 - 11
Source/cmGeneratorExpressionContext.h → Source/cmGenExEvaluation.h

@@ -6,20 +6,22 @@
 #include <set>
 #include <set>
 #include <string>
 #include <string>
 
 
+#include "cmGenExContext.h"
 #include "cmListFileCache.h"
 #include "cmListFileCache.h"
 
 
 class cmGeneratorTarget;
 class cmGeneratorTarget;
-class cmLocalGenerator;
 
 
-struct cmGeneratorExpressionContext
+namespace cm {
+namespace GenEx {
+
+struct Evaluation final
 {
 {
-  cmGeneratorExpressionContext(cmLocalGenerator const* lg, std::string config,
-                               bool quiet, cmGeneratorTarget const* headTarget,
-                               cmGeneratorTarget const* currentTarget,
-                               bool evaluateForBuildsystem,
-                               cmListFileBacktrace backtrace,
-                               std::string language);
+  Evaluation(GenEx::Context context, bool quiet,
+             cmGeneratorTarget const* headTarget,
+             cmGeneratorTarget const* currentTarget,
+             bool evaluateForBuildsystem, cmListFileBacktrace backtrace);
 
 
+  GenEx::Context const Context;
   cmListFileBacktrace Backtrace;
   cmListFileBacktrace Backtrace;
   std::set<cmGeneratorTarget*> DependTargets;
   std::set<cmGeneratorTarget*> DependTargets;
   std::set<cmGeneratorTarget const*> AllTargets;
   std::set<cmGeneratorTarget const*> AllTargets;
@@ -27,9 +29,6 @@ struct cmGeneratorExpressionContext
   std::set<cmGeneratorTarget const*> SourceSensitiveTargets;
   std::set<cmGeneratorTarget const*> SourceSensitiveTargets;
   std::map<cmGeneratorTarget const*, std::map<std::string, std::string>>
   std::map<cmGeneratorTarget const*, std::map<std::string, std::string>>
     MaxLanguageStandard;
     MaxLanguageStandard;
-  cmLocalGenerator const* LG;
-  std::string Config;
-  std::string Language;
   // The target whose property is being evaluated.
   // The target whose property is being evaluated.
   cmGeneratorTarget const* HeadTarget;
   cmGeneratorTarget const* HeadTarget;
   // The dependent of HeadTarget which appears
   // The dependent of HeadTarget which appears
@@ -42,3 +41,6 @@ struct cmGeneratorExpressionContext
   bool HadLinkLanguageSensitiveCondition = false;
   bool HadLinkLanguageSensitiveCondition = false;
   bool EvaluateForBuildsystem;
   bool EvaluateForBuildsystem;
 };
 };
+
+}
+}

+ 35 - 26
Source/cmGeneratorExpression.cxx

@@ -12,7 +12,8 @@
 
 
 #include "cmsys/RegularExpression.hxx"
 #include "cmsys/RegularExpression.hxx"
 
 
-#include "cmGeneratorExpressionContext.h"
+#include "cmGenExContext.h"
+#include "cmGenExEvaluation.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGeneratorExpressionEvaluator.h"
 #include "cmGeneratorExpressionEvaluator.h"
 #include "cmGeneratorExpressionLexer.h"
 #include "cmGeneratorExpressionLexer.h"
@@ -54,24 +55,31 @@ std::string cmGeneratorExpression::Evaluate(
       "genex_compile_eval", input);
       "genex_compile_eval", input);
 #endif
 #endif
 
 
+    cm::GenEx::Context context(lg, config, language);
     cmCompiledGeneratorExpression cge(*lg->GetCMakeInstance(),
     cmCompiledGeneratorExpression cge(*lg->GetCMakeInstance(),
                                       cmListFileBacktrace(), std::move(input));
                                       cmListFileBacktrace(), std::move(input));
-    return cge.Evaluate(lg, config, headTarget, dagChecker, currentTarget,
-                        language);
+    return cge.Evaluate(context, dagChecker, headTarget, currentTarget);
   }
   }
   return input;
   return input;
 }
 }
 
 
 std::string const& cmCompiledGeneratorExpression::Evaluate(
 std::string const& cmCompiledGeneratorExpression::Evaluate(
   cmLocalGenerator const* lg, std::string const& config,
   cmLocalGenerator const* lg, std::string const& config,
-  cmGeneratorTarget const* headTarget,
+  cmGeneratorTarget const* headTarget) const
+{
+  cm::GenEx::Context context(lg, config);
+  return this->Evaluate(context, nullptr, headTarget);
+}
+
+std::string const& cmCompiledGeneratorExpression::Evaluate(
+  cm::GenEx::Context const& context,
   cmGeneratorExpressionDAGChecker* dagChecker,
   cmGeneratorExpressionDAGChecker* dagChecker,
-  cmGeneratorTarget const* currentTarget, std::string const& language) const
+  cmGeneratorTarget const* headTarget,
+  cmGeneratorTarget const* currentTarget) const
 {
 {
-  cmGeneratorExpressionContext context(
-    lg, config, this->Quiet, headTarget,
-    currentTarget ? currentTarget : headTarget, this->EvaluateForBuildsystem,
-    this->Backtrace, language);
+  cm::GenEx::Evaluation eval(context, this->Quiet, headTarget,
+                             currentTarget ? currentTarget : headTarget,
+                             this->EvaluateForBuildsystem, this->Backtrace);
 
 
   if (!this->NeedsEvaluation) {
   if (!this->NeedsEvaluation) {
     return this->Input;
     return this->Input;
@@ -80,28 +88,28 @@ std::string const& cmCompiledGeneratorExpression::Evaluate(
   this->Output.clear();
   this->Output.clear();
 
 
   for (auto const& it : this->Evaluators) {
   for (auto const& it : this->Evaluators) {
-    this->Output += it->Evaluate(&context, dagChecker);
+    this->Output += it->Evaluate(&eval, dagChecker);
 
 
-    this->SeenTargetProperties.insert(context.SeenTargetProperties.cbegin(),
-                                      context.SeenTargetProperties.cend());
-    if (context.HadError) {
+    this->SeenTargetProperties.insert(eval.SeenTargetProperties.cbegin(),
+                                      eval.SeenTargetProperties.cend());
+    if (eval.HadError) {
       this->Output.clear();
       this->Output.clear();
       break;
       break;
     }
     }
   }
   }
 
 
-  this->MaxLanguageStandard = context.MaxLanguageStandard;
+  this->MaxLanguageStandard = eval.MaxLanguageStandard;
 
 
-  if (!context.HadError) {
-    this->HadContextSensitiveCondition = context.HadContextSensitiveCondition;
-    this->HadHeadSensitiveCondition = context.HadHeadSensitiveCondition;
+  if (!eval.HadError) {
+    this->HadContextSensitiveCondition = eval.HadContextSensitiveCondition;
+    this->HadHeadSensitiveCondition = eval.HadHeadSensitiveCondition;
     this->HadLinkLanguageSensitiveCondition =
     this->HadLinkLanguageSensitiveCondition =
-      context.HadLinkLanguageSensitiveCondition;
-    this->SourceSensitiveTargets = context.SourceSensitiveTargets;
+      eval.HadLinkLanguageSensitiveCondition;
+    this->SourceSensitiveTargets = eval.SourceSensitiveTargets;
   }
   }
 
 
-  this->DependTargets = context.DependTargets;
-  this->AllTargetsSeen = context.AllTargets;
+  this->DependTargets = eval.DependTargets;
+  this->AllTargetsSeen = eval.AllTargets;
   return this->Output;
   return this->Output;
 }
 }
 
 
@@ -453,17 +461,18 @@ std::string const& cmGeneratorExpressionInterpreter::Evaluate(
   this->CompiledGeneratorExpression =
   this->CompiledGeneratorExpression =
     this->GeneratorExpression.Parse(std::move(expression));
     this->GeneratorExpression.Parse(std::move(expression));
 
 
+  cm::GenEx::Context context(this->LocalGenerator, this->Config,
+                             this->Language);
+
   // Specify COMPILE_OPTIONS to DAGchecker, same semantic as COMPILE_FLAGS
   // Specify COMPILE_OPTIONS to DAGchecker, same semantic as COMPILE_FLAGS
   cmGeneratorExpressionDAGChecker dagChecker{
   cmGeneratorExpressionDAGChecker dagChecker{
     this->HeadTarget,
     this->HeadTarget,
     property == "COMPILE_FLAGS" ? "COMPILE_OPTIONS" : property,
     property == "COMPILE_FLAGS" ? "COMPILE_OPTIONS" : property,
     nullptr,
     nullptr,
     nullptr,
     nullptr,
-    this->LocalGenerator,
-    this->Config,
+    context,
   };
   };
 
 
-  return this->CompiledGeneratorExpression->Evaluate(
-    this->LocalGenerator, this->Config, this->HeadTarget, &dagChecker, nullptr,
-    this->Language);
+  return this->CompiledGeneratorExpression->Evaluate(context, &dagChecker,
+                                                     this->HeadTarget);
 }
 }

+ 12 - 3
Source/cmGeneratorExpression.h

@@ -16,6 +16,12 @@
 #include "cmListFileCache.h"
 #include "cmListFileCache.h"
 #include "cmLocalGenerator.h"
 #include "cmLocalGenerator.h"
 
 
+namespace cm {
+namespace GenEx {
+struct Context;
+}
+}
+
 class cmake;
 class cmake;
 class cmCompiledGeneratorExpression;
 class cmCompiledGeneratorExpression;
 class cmGeneratorTarget;
 class cmGeneratorTarget;
@@ -104,10 +110,13 @@ public:
 
 
   std::string const& Evaluate(
   std::string const& Evaluate(
     cmLocalGenerator const* lg, std::string const& config,
     cmLocalGenerator const* lg, std::string const& config,
+    cmGeneratorTarget const* headTarget = nullptr) const;
+
+  std::string const& Evaluate(
+    cm::GenEx::Context const& context,
+    cmGeneratorExpressionDAGChecker* dagChecker,
     cmGeneratorTarget const* headTarget = nullptr,
     cmGeneratorTarget const* headTarget = nullptr,
-    cmGeneratorExpressionDAGChecker* dagChecker = nullptr,
-    cmGeneratorTarget const* currentTarget = nullptr,
-    std::string const& language = std::string()) const;
+    cmGeneratorTarget const* currentTarget = nullptr) const;
 
 
   /** Get set of targets found during evaluations.  */
   /** Get set of targets found during evaluations.  */
   std::set<cmGeneratorTarget*> const& GetTargets() const
   std::set<cmGeneratorTarget*> const& GetTargets() const

+ 0 - 21
Source/cmGeneratorExpressionContext.cxx

@@ -1,21 +0,0 @@
-/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
-   file LICENSE.rst or https://cmake.org/licensing for details.  */
-#include "cmGeneratorExpressionContext.h"
-
-#include <utility>
-
-cmGeneratorExpressionContext::cmGeneratorExpressionContext(
-  cmLocalGenerator const* lg, std::string config, bool quiet,
-  cmGeneratorTarget const* headTarget, cmGeneratorTarget const* currentTarget,
-  bool evaluateForBuildsystem, cmListFileBacktrace backtrace,
-  std::string language)
-  : Backtrace(std::move(backtrace))
-  , LG(lg)
-  , Config(std::move(config))
-  , Language(std::move(language))
-  , HeadTarget(headTarget)
-  , CurrentTarget(currentTarget)
-  , Quiet(quiet)
-  , EvaluateForBuildsystem(evaluateForBuildsystem)
-{
-}

+ 17 - 16
Source/cmGeneratorExpressionDAGChecker.cxx

@@ -9,7 +9,8 @@
 #include <cm/string_view>
 #include <cm/string_view>
 #include <cmext/string_view>
 #include <cmext/string_view>
 
 
-#include "cmGeneratorExpressionContext.h"
+#include "cmGenExContext.h"
+#include "cmGenExEvaluation.h"
 #include "cmGeneratorExpressionEvaluator.h"
 #include "cmGeneratorExpressionEvaluator.h"
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
 #include "cmLocalGenerator.h"
 #include "cmLocalGenerator.h"
@@ -20,9 +21,8 @@
 cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
 cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
   cmGeneratorTarget const* target, std::string property,
   cmGeneratorTarget const* target, std::string property,
   GeneratorExpressionContent const* content,
   GeneratorExpressionContent const* content,
-  cmGeneratorExpressionDAGChecker* parent, cmLocalGenerator const* contextLG,
-  std::string const& contextConfig, cmListFileBacktrace backtrace,
-  ComputingLinkLibraries computingLinkLibraries)
+  cmGeneratorExpressionDAGChecker* parent, cm::GenEx::Context const& context,
+  cmListFileBacktrace backtrace, ComputingLinkLibraries computingLinkLibraries)
   : Parent(parent)
   : Parent(parent)
   , Top(parent ? parent->Top : this)
   , Top(parent ? parent->Top : this)
   , Target(target)
   , Target(target)
@@ -36,7 +36,8 @@ cmGeneratorExpressionDAGChecker::cmGeneratorExpressionDAGChecker(
   } else {
   } else {
     this->TopIsTransitiveProperty =
     this->TopIsTransitiveProperty =
       this->Target
       this->Target
-        ->IsTransitiveProperty(this->Property, contextLG, contextConfig, this)
+        ->IsTransitiveProperty(this->Property, context.LG, context.Config,
+                               this)
         .has_value();
         .has_value();
   }
   }
 
 
@@ -62,15 +63,15 @@ cmGeneratorExpressionDAGChecker::Check() const
   return this->CheckResult;
   return this->CheckResult;
 }
 }
 
 
-void cmGeneratorExpressionDAGChecker::ReportError(
-  cmGeneratorExpressionContext* context, std::string const& expr)
+void cmGeneratorExpressionDAGChecker::ReportError(cm::GenEx::Evaluation* eval,
+                                                  std::string const& expr)
 {
 {
   if (this->CheckResult == DAG) {
   if (this->CheckResult == DAG) {
     return;
     return;
   }
   }
 
 
-  context->HadError = true;
-  if (context->Quiet) {
+  eval->HadError = true;
+  if (eval->Quiet) {
     return;
     return;
   }
   }
 
 
@@ -80,10 +81,10 @@ void cmGeneratorExpressionDAGChecker::ReportError(
     std::ostringstream e;
     std::ostringstream e;
     e << "Error evaluating generator expression:\n"
     e << "Error evaluating generator expression:\n"
       << "  " << expr << "\n"
       << "  " << expr << "\n"
-      << "Self reference on target \"" << context->HeadTarget->GetName()
+      << "Self reference on target \"" << eval->HeadTarget->GetName()
       << "\".\n";
       << "\".\n";
-    context->LG->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
-                                                  e.str(), parent->Backtrace);
+    eval->Context.LG->GetCMakeInstance()->IssueMessage(
+      MessageType::FATAL_ERROR, e.str(), parent->Backtrace);
     return;
     return;
   }
   }
 
 
@@ -94,8 +95,8 @@ void cmGeneratorExpressionDAGChecker::ReportError(
     << "  " << expr << "\n"
     << "  " << expr << "\n"
     << "Dependency loop found.";
     << "Dependency loop found.";
     /* clang-format on */
     /* clang-format on */
-    context->LG->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
-                                                  e.str(), context->Backtrace);
+    eval->Context.LG->GetCMakeInstance()->IssueMessage(
+      MessageType::FATAL_ERROR, e.str(), eval->Backtrace);
   }
   }
 
 
   int loopStep = 1;
   int loopStep = 1;
@@ -105,8 +106,8 @@ void cmGeneratorExpressionDAGChecker::ReportError(
       << "  "
       << "  "
       << (parent->Content ? parent->Content->GetOriginalExpression() : expr)
       << (parent->Content ? parent->Content->GetOriginalExpression() : expr)
       << "\n";
       << "\n";
-    context->LG->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
-                                                  e.str(), parent->Backtrace);
+    eval->Context.LG->GetCMakeInstance()->IssueMessage(
+      MessageType::FATAL_ERROR, e.str(), parent->Backtrace);
     parent = parent->Parent;
     parent = parent->Parent;
     ++loopStep;
     ++loopStep;
   }
   }

+ 9 - 6
Source/cmGeneratorExpressionDAGChecker.h

@@ -10,10 +10,15 @@
 
 
 #include "cmListFileCache.h"
 #include "cmListFileCache.h"
 
 
+namespace cm {
+namespace GenEx {
+struct Context;
+struct Evaluation;
+}
+}
+
 struct GeneratorExpressionContent;
 struct GeneratorExpressionContent;
-struct cmGeneratorExpressionContext;
 class cmGeneratorTarget;
 class cmGeneratorTarget;
-class cmLocalGenerator;
 
 
 struct cmGeneratorExpressionDAGChecker
 struct cmGeneratorExpressionDAGChecker
 {
 {
@@ -25,8 +30,7 @@ struct cmGeneratorExpressionDAGChecker
   cmGeneratorExpressionDAGChecker(
   cmGeneratorExpressionDAGChecker(
     cmGeneratorTarget const* target, std::string property,
     cmGeneratorTarget const* target, std::string property,
     GeneratorExpressionContent const* content,
     GeneratorExpressionContent const* content,
-    cmGeneratorExpressionDAGChecker* parent, cmLocalGenerator const* contextLG,
-    std::string const& contextConfig,
+    cmGeneratorExpressionDAGChecker* parent, cm::GenEx::Context const& context,
     cmListFileBacktrace backtrace = cmListFileBacktrace(),
     cmListFileBacktrace backtrace = cmListFileBacktrace(),
     ComputingLinkLibraries computingLinkLibraries =
     ComputingLinkLibraries computingLinkLibraries =
       ComputingLinkLibraries::No);
       ComputingLinkLibraries::No);
@@ -41,8 +45,7 @@ struct cmGeneratorExpressionDAGChecker
 
 
   Result Check() const;
   Result Check() const;
 
 
-  void ReportError(cmGeneratorExpressionContext* context,
-                   std::string const& expr);
+  void ReportError(cm::GenEx::Evaluation* eval, std::string const& expr);
 
 
   bool EvaluatingTransitiveProperty() const;
   bool EvaluatingTransitiveProperty() const;
   bool EvaluatingGenexExpression() const;
   bool EvaluatingGenexExpression() const;

+ 14 - 12
Source/cmGeneratorExpressionEvaluationFile.cxx

@@ -8,6 +8,7 @@
 
 
 #include "cmsys/FStream.hxx"
 #include "cmsys/FStream.hxx"
 
 
+#include "cmGenExContext.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGlobalGenerator.h"
 #include "cmGlobalGenerator.h"
 #include "cmListFileCache.h"
 #include "cmListFileCache.h"
@@ -39,11 +40,12 @@ void cmGeneratorExpressionEvaluationFile::Generate(
   cmCompiledGeneratorExpression* inputExpression,
   cmCompiledGeneratorExpression* inputExpression,
   std::map<std::string, std::string>& outputFiles, mode_t perm)
   std::map<std::string, std::string>& outputFiles, mode_t perm)
 {
 {
+  cm::GenEx::Context context(lg, config, lang);
   std::string rawCondition = this->Condition->GetInput();
   std::string rawCondition = this->Condition->GetInput();
   cmGeneratorTarget* target = lg->FindGeneratorTargetToUse(this->Target);
   cmGeneratorTarget* target = lg->FindGeneratorTargetToUse(this->Target);
   if (!rawCondition.empty()) {
   if (!rawCondition.empty()) {
     std::string condResult =
     std::string condResult =
-      this->Condition->Evaluate(lg, config, target, nullptr, nullptr, lang);
+      this->Condition->Evaluate(context, nullptr, target);
     if (condResult == "0") {
     if (condResult == "0") {
       return;
       return;
     }
     }
@@ -58,10 +60,9 @@ void cmGeneratorExpressionEvaluationFile::Generate(
     }
     }
   }
   }
 
 
-  std::string const outputFileName =
-    this->GetOutputFileName(lg, target, config, lang);
+  std::string const outputFileName = this->GetOutputFileName(context, target);
   std::string const& outputContent =
   std::string const& outputContent =
-    inputExpression->Evaluate(lg, config, target, nullptr, nullptr, lang);
+    inputExpression->Evaluate(context, nullptr, target);
 
 
   auto it = outputFiles.find(outputFileName);
   auto it = outputFiles.find(outputFileName);
 
 
@@ -123,8 +124,9 @@ void cmGeneratorExpressionEvaluationFile::CreateOutputFile(
   cmGeneratorTarget* target = lg->FindGeneratorTargetToUse(this->Target);
   cmGeneratorTarget* target = lg->FindGeneratorTargetToUse(this->Target);
   gg->GetEnabledLanguages(enabledLanguages);
   gg->GetEnabledLanguages(enabledLanguages);
 
 
-  for (std::string const& le : enabledLanguages) {
-    std::string const name = this->GetOutputFileName(lg, target, config, le);
+  for (std::string const& lang : enabledLanguages) {
+    cm::GenEx::Context context(lg, config, lang);
+    std::string const name = this->GetOutputFileName(context, target);
     cmSourceFile* sf = lg->GetMakefile()->GetOrCreateGeneratedSource(name);
     cmSourceFile* sf = lg->GetMakefile()->GetOrCreateGeneratedSource(name);
 
 
     // Tell the build system generators that there is no build rule
     // Tell the build system generators that there is no build rule
@@ -190,7 +192,7 @@ void cmGeneratorExpressionEvaluationFile::Generate(cmLocalGenerator* lg)
 }
 }
 
 
 std::string cmGeneratorExpressionEvaluationFile::GetInputFileName(
 std::string cmGeneratorExpressionEvaluationFile::GetInputFileName(
-  cmLocalGenerator* lg)
+  cmLocalGenerator const* lg)
 {
 {
   std::string inputFileName = this->Input;
   std::string inputFileName = this->Input;
 
 
@@ -204,23 +206,23 @@ std::string cmGeneratorExpressionEvaluationFile::GetInputFileName(
 }
 }
 
 
 std::string cmGeneratorExpressionEvaluationFile::GetOutputFileName(
 std::string cmGeneratorExpressionEvaluationFile::GetOutputFileName(
-  cmLocalGenerator* lg, cmGeneratorTarget* target, std::string const& config,
-  std::string const& lang)
+  cm::GenEx::Context const& context, cmGeneratorTarget* target)
 {
 {
   std::string outputFileName =
   std::string outputFileName =
-    this->OutputFileExpr->Evaluate(lg, config, target, nullptr, nullptr, lang);
+    this->OutputFileExpr->Evaluate(context, nullptr, target);
 
 
   if (cmSystemTools::FileIsFullPath(outputFileName)) {
   if (cmSystemTools::FileIsFullPath(outputFileName)) {
     outputFileName = cmSystemTools::CollapseFullPath(outputFileName);
     outputFileName = cmSystemTools::CollapseFullPath(outputFileName);
   } else {
   } else {
-    outputFileName = this->FixRelativePath(outputFileName, PathForOutput, lg);
+    outputFileName =
+      this->FixRelativePath(outputFileName, PathForOutput, context.LG);
   }
   }
 
 
   return outputFileName;
   return outputFileName;
 }
 }
 
 
 std::string cmGeneratorExpressionEvaluationFile::FixRelativePath(
 std::string cmGeneratorExpressionEvaluationFile::FixRelativePath(
-  std::string const& relativePath, PathRole role, cmLocalGenerator* lg)
+  std::string const& relativePath, PathRole role, cmLocalGenerator const* lg)
 {
 {
   std::string resultPath;
   std::string resultPath;
   switch (this->PolicyStatusCMP0070) {
   switch (this->PolicyStatusCMP0070) {

+ 10 - 6
Source/cmGeneratorExpressionEvaluationFile.h

@@ -14,6 +14,12 @@
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpression.h"
 #include "cmPolicies.h"
 #include "cmPolicies.h"
 
 
+namespace cm {
+namespace GenEx {
+struct Context;
+}
+}
+
 class cmGeneratorTarget;
 class cmGeneratorTarget;
 class cmLocalGenerator;
 class cmLocalGenerator;
 
 
@@ -39,18 +45,16 @@ private:
                 cmCompiledGeneratorExpression* inputExpression,
                 cmCompiledGeneratorExpression* inputExpression,
                 std::map<std::string, std::string>& outputFiles, mode_t perm);
                 std::map<std::string, std::string>& outputFiles, mode_t perm);
 
 
-  std::string GetInputFileName(cmLocalGenerator* lg);
-  std::string GetOutputFileName(cmLocalGenerator* lg,
-                                cmGeneratorTarget* target,
-                                std::string const& config,
-                                std::string const& lang);
+  std::string GetInputFileName(cmLocalGenerator const* lg);
+  std::string GetOutputFileName(cm::GenEx::Context const& context,
+                                cmGeneratorTarget* target);
   enum PathRole
   enum PathRole
   {
   {
     PathForInput,
     PathForInput,
     PathForOutput
     PathForOutput
   };
   };
   std::string FixRelativePath(std::string const& filePath, PathRole role,
   std::string FixRelativePath(std::string const& filePath, PathRole role,
-                              cmLocalGenerator* lg);
+                              cmLocalGenerator const* lg);
 
 
   std::string const Input;
   std::string const Input;
   std::string const Target;
   std::string const Target;

+ 28 - 30
Source/cmGeneratorExpressionEvaluator.cxx

@@ -8,7 +8,8 @@
 #  include <cm3p/json/value.h>
 #  include <cm3p/json/value.h>
 #endif
 #endif
 
 
-#include "cmGeneratorExpressionContext.h"
+#include "cmGenExContext.h"
+#include "cmGenExEvaluation.h"
 #include "cmGeneratorExpressionNode.h"
 #include "cmGeneratorExpressionNode.h"
 #include "cmLocalGenerator.h"
 #include "cmLocalGenerator.h"
 #include "cmake.h"
 #include "cmake.h"
@@ -29,8 +30,7 @@ std::string GeneratorExpressionContent::GetOriginalExpression() const
 
 
 std::string GeneratorExpressionContent::ProcessArbitraryContent(
 std::string GeneratorExpressionContent::ProcessArbitraryContent(
   cmGeneratorExpressionNode const* node, std::string const& identifier,
   cmGeneratorExpressionNode const* node, std::string const& identifier,
-  cmGeneratorExpressionContext* context,
-  cmGeneratorExpressionDAGChecker* dagChecker,
+  cm::GenEx::Evaluation* eval, cmGeneratorExpressionDAGChecker* dagChecker,
   std::vector<cmGeneratorExpressionEvaluatorVector>::const_iterator pit) const
   std::vector<cmGeneratorExpressionEvaluatorVector>::const_iterator pit) const
 {
 {
   std::string result;
   std::string result;
@@ -40,14 +40,14 @@ std::string GeneratorExpressionContent::ProcessArbitraryContent(
     for (auto const& pExprEval : *pit) {
     for (auto const& pExprEval : *pit) {
       if (node->RequiresLiteralInput()) {
       if (node->RequiresLiteralInput()) {
         if (pExprEval->GetType() != cmGeneratorExpressionEvaluator::Text) {
         if (pExprEval->GetType() != cmGeneratorExpressionEvaluator::Text) {
-          reportError(context, this->GetOriginalExpression(),
+          reportError(eval, this->GetOriginalExpression(),
                       "$<" + identifier +
                       "$<" + identifier +
                         "> expression requires literal input.");
                         "> expression requires literal input.");
           return std::string();
           return std::string();
         }
         }
       }
       }
-      result += pExprEval->Evaluate(context, dagChecker);
-      if (context->HadError) {
+      result += pExprEval->Evaluate(eval, dagChecker);
+      if (eval->HadError) {
         return std::string();
         return std::string();
       }
       }
     }
     }
@@ -58,26 +58,26 @@ std::string GeneratorExpressionContent::ProcessArbitraryContent(
   if (node->RequiresLiteralInput()) {
   if (node->RequiresLiteralInput()) {
     std::vector<std::string> parameters;
     std::vector<std::string> parameters;
     parameters.push_back(result);
     parameters.push_back(result);
-    return node->Evaluate(parameters, context, this, dagChecker);
+    return node->Evaluate(parameters, eval, this, dagChecker);
   }
   }
   return result;
   return result;
 }
 }
 
 
 std::string GeneratorExpressionContent::Evaluate(
 std::string GeneratorExpressionContent::Evaluate(
-  cmGeneratorExpressionContext* context,
+  cm::GenEx::Evaluation* eval,
   cmGeneratorExpressionDAGChecker* dagChecker) const
   cmGeneratorExpressionDAGChecker* dagChecker) const
 {
 {
 #ifndef CMAKE_BOOTSTRAP
 #ifndef CMAKE_BOOTSTRAP
   auto evalProfilingRAII =
   auto evalProfilingRAII =
-    context->LG->GetCMakeInstance()->CreateProfilingEntry(
+    eval->Context.LG->GetCMakeInstance()->CreateProfilingEntry(
       "genex_eval", this->GetOriginalExpression());
       "genex_eval", this->GetOriginalExpression());
 #endif
 #endif
 
 
   std::string identifier;
   std::string identifier;
   {
   {
     for (auto const& pExprEval : this->IdentifierChildren) {
     for (auto const& pExprEval : this->IdentifierChildren) {
-      identifier += pExprEval->Evaluate(context, dagChecker);
-      if (context->HadError) {
+      identifier += pExprEval->Evaluate(eval, dagChecker);
+      if (eval->HadError) {
         return std::string();
         return std::string();
       }
       }
     }
     }
@@ -87,7 +87,7 @@ std::string GeneratorExpressionContent::Evaluate(
     cmGeneratorExpressionNode::GetNode(identifier);
     cmGeneratorExpressionNode::GetNode(identifier);
 
 
   if (!node) {
   if (!node) {
-    reportError(context, this->GetOriginalExpression(),
+    reportError(eval, this->GetOriginalExpression(),
                 "Expression did not evaluate to a known generator expression");
                 "Expression did not evaluate to a known generator expression");
     return std::string();
     return std::string();
   }
   }
@@ -96,27 +96,26 @@ std::string GeneratorExpressionContent::Evaluate(
     if (node->NumExpectedParameters() == 1 &&
     if (node->NumExpectedParameters() == 1 &&
         node->AcceptsArbitraryContentParameter()) {
         node->AcceptsArbitraryContentParameter()) {
       if (this->ParamChildren.empty()) {
       if (this->ParamChildren.empty()) {
-        reportError(context, this->GetOriginalExpression(),
+        reportError(eval, this->GetOriginalExpression(),
                     "$<" + identifier + "> expression requires a parameter.");
                     "$<" + identifier + "> expression requires a parameter.");
       }
       }
     } else {
     } else {
       std::vector<std::string> parameters;
       std::vector<std::string> parameters;
-      this->EvaluateParameters(node, identifier, context, dagChecker,
-                               parameters);
+      this->EvaluateParameters(node, identifier, eval, dagChecker, parameters);
     }
     }
     return std::string();
     return std::string();
   }
   }
 
 
   std::vector<std::string> parameters;
   std::vector<std::string> parameters;
-  this->EvaluateParameters(node, identifier, context, dagChecker, parameters);
-  if (context->HadError) {
+  this->EvaluateParameters(node, identifier, eval, dagChecker, parameters);
+  if (eval->HadError) {
     return std::string();
     return std::string();
   }
   }
 
 
   {
   {
 #ifndef CMAKE_BOOTSTRAP
 #ifndef CMAKE_BOOTSTRAP
     auto execProfilingRAII =
     auto execProfilingRAII =
-      context->LG->GetCMakeInstance()->CreateProfilingEntry(
+      eval->Context.LG->GetCMakeInstance()->CreateProfilingEntry(
         "genex_exec", identifier, [&parameters]() -> Json::Value {
         "genex_exec", identifier, [&parameters]() -> Json::Value {
           Json::Value args = Json::objectValue;
           Json::Value args = Json::objectValue;
           if (!parameters.empty()) {
           if (!parameters.empty()) {
@@ -129,14 +128,13 @@ std::string GeneratorExpressionContent::Evaluate(
         });
         });
 #endif
 #endif
 
 
-    return node->Evaluate(parameters, context, this, dagChecker);
+    return node->Evaluate(parameters, eval, this, dagChecker);
   }
   }
 }
 }
 
 
 std::string GeneratorExpressionContent::EvaluateParameters(
 std::string GeneratorExpressionContent::EvaluateParameters(
   cmGeneratorExpressionNode const* node, std::string const& identifier,
   cmGeneratorExpressionNode const* node, std::string const& identifier,
-  cmGeneratorExpressionContext* context,
-  cmGeneratorExpressionDAGChecker* dagChecker,
+  cm::GenEx::Evaluation* eval, cmGeneratorExpressionDAGChecker* dagChecker,
   std::vector<std::string>& parameters) const
   std::vector<std::string>& parameters) const
 {
 {
   int const numExpected = node->NumExpectedParameters();
   int const numExpected = node->NumExpectedParameters();
@@ -149,14 +147,14 @@ std::string GeneratorExpressionContent::EvaluateParameters(
     for (; pit != pend; ++pit, ++counter) {
     for (; pit != pend; ++pit, ++counter) {
       if (acceptsArbitraryContent && counter == numExpected) {
       if (acceptsArbitraryContent && counter == numExpected) {
         parameters.push_back(this->ProcessArbitraryContent(
         parameters.push_back(this->ProcessArbitraryContent(
-          node, identifier, context, dagChecker, pit));
+          node, identifier, eval, dagChecker, pit));
         return std::string();
         return std::string();
       }
       }
       std::string parameter;
       std::string parameter;
       if (node->ShouldEvaluateNextParameter(parameters, parameter)) {
       if (node->ShouldEvaluateNextParameter(parameters, parameter)) {
         for (auto const& pExprEval : *pit) {
         for (auto const& pExprEval : *pit) {
-          parameter += pExprEval->Evaluate(context, dagChecker);
-          if (context->HadError) {
+          parameter += pExprEval->Evaluate(eval, dagChecker);
+          if (eval->HadError) {
             return std::string();
             return std::string();
           }
           }
         }
         }
@@ -168,10 +166,10 @@ std::string GeneratorExpressionContent::EvaluateParameters(
   if ((numExpected > cmGeneratorExpressionNode::DynamicParameters &&
   if ((numExpected > cmGeneratorExpressionNode::DynamicParameters &&
        static_cast<unsigned int>(numExpected) != parameters.size())) {
        static_cast<unsigned int>(numExpected) != parameters.size())) {
     if (numExpected == 0) {
     if (numExpected == 0) {
-      reportError(context, this->GetOriginalExpression(),
+      reportError(eval, this->GetOriginalExpression(),
                   "$<" + identifier + "> expression requires no parameters.");
                   "$<" + identifier + "> expression requires no parameters.");
     } else if (numExpected == 1) {
     } else if (numExpected == 1) {
-      reportError(context, this->GetOriginalExpression(),
+      reportError(eval, this->GetOriginalExpression(),
                   "$<" + identifier +
                   "$<" + identifier +
                     "> expression requires "
                     "> expression requires "
                     "exactly one parameter.");
                     "exactly one parameter.");
@@ -180,24 +178,24 @@ std::string GeneratorExpressionContent::EvaluateParameters(
       e << "$<" + identifier + "> expression requires " << numExpected
       e << "$<" + identifier + "> expression requires " << numExpected
         << " comma separated parameters, but got " << parameters.size()
         << " comma separated parameters, but got " << parameters.size()
         << " instead.";
         << " instead.";
-      reportError(context, this->GetOriginalExpression(), e.str());
+      reportError(eval, this->GetOriginalExpression(), e.str());
     }
     }
     return std::string();
     return std::string();
   }
   }
 
 
   if (numExpected == cmGeneratorExpressionNode::OneOrMoreParameters &&
   if (numExpected == cmGeneratorExpressionNode::OneOrMoreParameters &&
       parameters.empty()) {
       parameters.empty()) {
-    reportError(context, this->GetOriginalExpression(),
+    reportError(eval, this->GetOriginalExpression(),
                 "$<" + identifier +
                 "$<" + identifier +
                   "> expression requires at least one parameter.");
                   "> expression requires at least one parameter.");
   } else if (numExpected == cmGeneratorExpressionNode::TwoOrMoreParameters &&
   } else if (numExpected == cmGeneratorExpressionNode::TwoOrMoreParameters &&
              parameters.size() < 2) {
              parameters.size() < 2) {
-    reportError(context, this->GetOriginalExpression(),
+    reportError(eval, this->GetOriginalExpression(),
                 "$<" + identifier +
                 "$<" + identifier +
                   "> expression requires at least two parameters.");
                   "> expression requires at least two parameters.");
   } else if (numExpected == cmGeneratorExpressionNode::OneOrZeroParameters &&
   } else if (numExpected == cmGeneratorExpressionNode::OneOrZeroParameters &&
              parameters.size() > 1) {
              parameters.size() > 1) {
-    reportError(context, this->GetOriginalExpression(),
+    reportError(eval, this->GetOriginalExpression(),
                 "$<" + identifier +
                 "$<" + identifier +
                   "> expression requires one or zero parameters.");
                   "> expression requires one or zero parameters.");
   }
   }

+ 11 - 7
Source/cmGeneratorExpressionEvaluator.h

@@ -10,7 +10,12 @@
 #include <utility>
 #include <utility>
 #include <vector>
 #include <vector>
 
 
-struct cmGeneratorExpressionContext;
+namespace cm {
+namespace GenEx {
+struct Evaluation;
+}
+}
+
 struct cmGeneratorExpressionDAGChecker;
 struct cmGeneratorExpressionDAGChecker;
 struct cmGeneratorExpressionNode;
 struct cmGeneratorExpressionNode;
 
 
@@ -32,7 +37,7 @@ struct cmGeneratorExpressionEvaluator
 
 
   virtual Type GetType() const = 0;
   virtual Type GetType() const = 0;
 
 
-  virtual std::string Evaluate(cmGeneratorExpressionContext* context,
+  virtual std::string Evaluate(cm::GenEx::Evaluation* eval,
                                cmGeneratorExpressionDAGChecker*) const = 0;
                                cmGeneratorExpressionDAGChecker*) const = 0;
 };
 };
 
 
@@ -47,7 +52,7 @@ struct TextContent : public cmGeneratorExpressionEvaluator
   {
   {
   }
   }
 
 
-  std::string Evaluate(cmGeneratorExpressionContext*,
+  std::string Evaluate(cm::GenEx::Evaluation*,
                        cmGeneratorExpressionDAGChecker*) const override
                        cmGeneratorExpressionDAGChecker*) const override
   {
   {
     return std::string(this->Content, this->Length);
     return std::string(this->Content, this->Length);
@@ -87,7 +92,7 @@ struct GeneratorExpressionContent : public cmGeneratorExpressionEvaluator
     return cmGeneratorExpressionEvaluator::Generator;
     return cmGeneratorExpressionEvaluator::Generator;
   }
   }
 
 
-  std::string Evaluate(cmGeneratorExpressionContext* context,
+  std::string Evaluate(cm::GenEx::Evaluation* eval,
                        cmGeneratorExpressionDAGChecker*) const override;
                        cmGeneratorExpressionDAGChecker*) const override;
 
 
   std::string GetOriginalExpression() const;
   std::string GetOriginalExpression() const;
@@ -97,14 +102,13 @@ struct GeneratorExpressionContent : public cmGeneratorExpressionEvaluator
 private:
 private:
   std::string EvaluateParameters(cmGeneratorExpressionNode const* node,
   std::string EvaluateParameters(cmGeneratorExpressionNode const* node,
                                  std::string const& identifier,
                                  std::string const& identifier,
-                                 cmGeneratorExpressionContext* context,
+                                 cm::GenEx::Evaluation* eval,
                                  cmGeneratorExpressionDAGChecker* dagChecker,
                                  cmGeneratorExpressionDAGChecker* dagChecker,
                                  std::vector<std::string>& parameters) const;
                                  std::vector<std::string>& parameters) const;
 
 
   std::string ProcessArbitraryContent(
   std::string ProcessArbitraryContent(
     cmGeneratorExpressionNode const* node, std::string const& identifier,
     cmGeneratorExpressionNode const* node, std::string const& identifier,
-    cmGeneratorExpressionContext* context,
-    cmGeneratorExpressionDAGChecker* dagChecker,
+    cm::GenEx::Evaluation* eval, cmGeneratorExpressionDAGChecker* dagChecker,
     std::vector<cmGeneratorExpressionEvaluatorVector>::const_iterator pit)
     std::vector<cmGeneratorExpressionEvaluatorVector>::const_iterator pit)
     const;
     const;
 
 

File diff suppressed because it is too large
+ 158 - 206
Source/cmGeneratorExpressionNode.cxx


+ 11 - 8
Source/cmGeneratorExpressionNode.h

@@ -7,10 +7,14 @@
 #include <string>
 #include <string>
 #include <vector>
 #include <vector>
 
 
+namespace cm {
+namespace GenEx {
+struct Evaluation;
+}
+}
+
 class cmGeneratorTarget;
 class cmGeneratorTarget;
-class cmLocalGenerator;
 struct GeneratorExpressionContent;
 struct GeneratorExpressionContent;
-struct cmGeneratorExpressionContext;
 struct cmGeneratorExpressionDAGChecker;
 struct cmGeneratorExpressionDAGChecker;
 
 
 struct cmGeneratorExpressionNode
 struct cmGeneratorExpressionNode
@@ -40,14 +44,13 @@ struct cmGeneratorExpressionNode
   }
   }
 
 
   virtual std::string Evaluate(
   virtual std::string Evaluate(
-    std::vector<std::string> const& parameters,
-    cmGeneratorExpressionContext* context,
+    std::vector<std::string> const& parameters, cm::GenEx::Evaluation* eval,
     GeneratorExpressionContent const* content,
     GeneratorExpressionContent const* content,
     cmGeneratorExpressionDAGChecker* dagChecker) const = 0;
     cmGeneratorExpressionDAGChecker* dagChecker) const = 0;
 
 
   static std::string EvaluateDependentExpression(
   static std::string EvaluateDependentExpression(
-    std::string const& prop, cmLocalGenerator const* lg,
-    cmGeneratorExpressionContext* context, cmGeneratorTarget const* headTarget,
+    std::string const& prop, cm::GenEx::Evaluation* eval,
+    cmGeneratorTarget const* headTarget,
     cmGeneratorExpressionDAGChecker* dagChecker,
     cmGeneratorExpressionDAGChecker* dagChecker,
     cmGeneratorTarget const* currentTarget);
     cmGeneratorTarget const* currentTarget);
 
 
@@ -55,5 +58,5 @@ struct cmGeneratorExpressionNode
     std::string const& identifier);
     std::string const& identifier);
 };
 };
 
 
-void reportError(cmGeneratorExpressionContext* context,
-                 std::string const& expr, std::string const& result);
+void reportError(cm::GenEx::Evaluation* eval, std::string const& expr,
+                 std::string const& result);

+ 30 - 25
Source/cmGeneratorTarget.cxx

@@ -27,6 +27,7 @@
 #include "cmExperimental.h"
 #include "cmExperimental.h"
 #include "cmFileSet.h"
 #include "cmFileSet.h"
 #include "cmFileTimes.h"
 #include "cmFileTimes.h"
+#include "cmGenExContext.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGeneratorExpressionDAGChecker.h"
@@ -630,7 +631,7 @@ std::vector<cmSourceFile*> const* cmGeneratorTarget::GetSourceDepends(
 }
 }
 
 
 namespace {
 namespace {
-void handleSystemIncludesDep(cmLocalGenerator* lg,
+void handleSystemIncludesDep(cmLocalGenerator const* lg,
                              cmGeneratorTarget const* depTgt,
                              cmGeneratorTarget const* depTgt,
                              std::string const& config,
                              std::string const& config,
                              cmGeneratorTarget const* headTarget,
                              cmGeneratorTarget const* headTarget,
@@ -737,12 +738,13 @@ std::string cmGeneratorTarget::GetLinkerTypeProperty(
   std::string propName{ "LINKER_TYPE" };
   std::string propName{ "LINKER_TYPE" };
   auto linkerType = this->GetProperty(propName);
   auto linkerType = this->GetProperty(propName);
   if (!linkerType.IsEmpty()) {
   if (!linkerType.IsEmpty()) {
+    cm::GenEx::Context context(this->LocalGenerator, config, lang);
     cmGeneratorExpressionDAGChecker dagChecker{
     cmGeneratorExpressionDAGChecker dagChecker{
-      this, propName, nullptr, nullptr, this->LocalGenerator, config,
+      this, propName, nullptr, nullptr, context,
     };
     };
-    auto ltype =
-      cmGeneratorExpression::Evaluate(*linkerType, this->GetLocalGenerator(),
-                                      config, this, &dagChecker, this, lang);
+    auto ltype = cmGeneratorExpression::Evaluate(
+      *linkerType, context.LG, context.Config, this, &dagChecker, this,
+      context.Language);
     if (this->IsDeviceLink()) {
     if (this->IsDeviceLink()) {
       cmList list{ ltype };
       cmList list{ ltype };
       auto const DL_BEGIN = "<DEVICE_LINK>"_s;
       auto const DL_BEGIN = "<DEVICE_LINK>"_s;
@@ -1199,24 +1201,25 @@ void cmGeneratorTarget::AddSystemIncludeCacheKey(
   std::string const& key, std::string const& config,
   std::string const& key, std::string const& config,
   std::string const& language) const
   std::string const& language) const
 {
 {
+  cm::GenEx::Context context(this->LocalGenerator, config, language);
   cmGeneratorExpressionDAGChecker dagChecker{
   cmGeneratorExpressionDAGChecker dagChecker{
-    this,    "SYSTEM_INCLUDE_DIRECTORIES", nullptr,
-    nullptr, this->LocalGenerator,         config,
+    this, "SYSTEM_INCLUDE_DIRECTORIES", nullptr, nullptr, context,
   };
   };
 
 
   bool excludeImported = this->GetPropertyAsBool("NO_SYSTEM_FROM_IMPORTED");
   bool excludeImported = this->GetPropertyAsBool("NO_SYSTEM_FROM_IMPORTED");
 
 
   cmList result;
   cmList result;
   for (std::string const& it : this->Target->GetSystemIncludeDirectories()) {
   for (std::string const& it : this->Target->GetSystemIncludeDirectories()) {
-    result.append(cmGeneratorExpression::Evaluate(
-      it, this->LocalGenerator, config, this, &dagChecker, nullptr, language));
+    result.append(
+      cmGeneratorExpression::Evaluate(it, context.LG, context.Config, this,
+                                      &dagChecker, nullptr, context.Language));
   }
   }
 
 
   std::vector<cmGeneratorTarget const*> const& deps =
   std::vector<cmGeneratorTarget const*> const& deps =
     this->GetLinkImplementationClosure(config, UseTo::Compile);
     this->GetLinkImplementationClosure(config, UseTo::Compile);
   for (cmGeneratorTarget const* dep : deps) {
   for (cmGeneratorTarget const* dep : deps) {
-    handleSystemIncludesDep(this->LocalGenerator, dep, config, this,
-                            &dagChecker, result, excludeImported, language);
+    handleSystemIncludesDep(context.LG, dep, context.Config, this, &dagChecker,
+                            result, excludeImported, context.Language);
   }
   }
 
 
   cmLinkImplementation const* impl =
   cmLinkImplementation const* impl =
@@ -1226,9 +1229,9 @@ void cmGeneratorTarget::AddSystemIncludeCacheKey(
     if (runtimeEntries != impl->LanguageRuntimeLibraries.end()) {
     if (runtimeEntries != impl->LanguageRuntimeLibraries.end()) {
       for (auto const& lib : runtimeEntries->second) {
       for (auto const& lib : runtimeEntries->second) {
         if (lib.Target) {
         if (lib.Target) {
-          handleSystemIncludesDep(this->LocalGenerator, lib.Target, config,
-                                  this, &dagChecker, result, excludeImported,
-                                  language);
+          handleSystemIncludesDep(context.LG, lib.Target, context.Config, this,
+                                  &dagChecker, result, excludeImported,
+                                  context.Language);
         }
         }
       }
       }
     }
     }
@@ -1975,11 +1978,12 @@ void cmGeneratorTarget::GetAutoUicOptions(std::vector<std::string>& result,
     return;
     return;
   }
   }
 
 
+  cm::GenEx::Context context(this->LocalGenerator, config);
   cmGeneratorExpressionDAGChecker dagChecker{
   cmGeneratorExpressionDAGChecker dagChecker{
-    this, "AUTOUIC_OPTIONS", nullptr, nullptr, this->LocalGenerator, config,
+    this, "AUTOUIC_OPTIONS", nullptr, nullptr, context,
   };
   };
-  cmExpandList(cmGeneratorExpression::Evaluate(prop, this->LocalGenerator,
-                                               config, this, &dagChecker),
+  cmExpandList(cmGeneratorExpression::Evaluate(
+                 prop, context.LG, context.Config, this, &dagChecker),
                result);
                result);
 }
 }
 
 
@@ -5439,17 +5443,17 @@ bool cmGeneratorTarget::AddHeaderSetVerification()
     bool first = true;
     bool first = true;
     for (auto const& config : this->Makefile->GetGeneratorConfigs(
     for (auto const& config : this->Makefile->GetGeneratorConfigs(
            cmMakefile::GeneratorConfigQuery::IncludeEmptyConfig)) {
            cmMakefile::GeneratorConfigQuery::IncludeEmptyConfig)) {
+      cm::GenEx::Context context(this->LocalGenerator, config);
       if (first || dirCgesContextSensitive) {
       if (first || dirCgesContextSensitive) {
-        dirs = fileSet->EvaluateDirectoryEntries(dirCges, this->LocalGenerator,
-                                                 config, this);
+        dirs = fileSet->EvaluateDirectoryEntries(dirCges, context, this);
         dirCgesContextSensitive =
         dirCgesContextSensitive =
           std::any_of(dirCges.begin(), dirCges.end(), contextSensitive);
           std::any_of(dirCges.begin(), dirCges.end(), contextSensitive);
       }
       }
       if (first || fileCgesContextSensitive) {
       if (first || fileCgesContextSensitive) {
         filesPerDir.clear();
         filesPerDir.clear();
         for (auto const& fileCge : fileCges) {
         for (auto const& fileCge : fileCges) {
-          fileSet->EvaluateFileEntry(dirs, filesPerDir, fileCge,
-                                     this->LocalGenerator, config, this);
+          fileSet->EvaluateFileEntry(dirs, filesPerDir, fileCge, context,
+                                     this);
           if (fileCge->GetHadContextSensitiveCondition()) {
           if (fileCge->GetHadContextSensitiveCondition()) {
             fileCgesContextSensitive = true;
             fileCgesContextSensitive = true;
           }
           }
@@ -5980,15 +5984,16 @@ void cmGeneratorTarget::BuildFileSetInfoCache(std::string const& config) const
       continue;
       continue;
     }
     }
 
 
+    cm::GenEx::Context context(this->LocalGenerator, config);
+
     auto fileEntries = file_set->CompileFileEntries();
     auto fileEntries = file_set->CompileFileEntries();
     auto directoryEntries = file_set->CompileDirectoryEntries();
     auto directoryEntries = file_set->CompileDirectoryEntries();
-    auto directories = file_set->EvaluateDirectoryEntries(
-      directoryEntries, this->LocalGenerator, config, this);
+    auto directories =
+      file_set->EvaluateDirectoryEntries(directoryEntries, context, this);
 
 
     std::map<std::string, std::vector<std::string>> files;
     std::map<std::string, std::vector<std::string>> files;
     for (auto const& entry : fileEntries) {
     for (auto const& entry : fileEntries) {
-      file_set->EvaluateFileEntry(directories, files, entry,
-                                  this->LocalGenerator, config, this);
+      file_set->EvaluateFileEntry(directories, files, entry, context, this);
     }
     }
 
 
     for (auto const& it : files) {
     for (auto const& it : files) {

+ 11 - 7
Source/cmGeneratorTarget.h

@@ -25,6 +25,13 @@
 #include "cmStateTypes.h"
 #include "cmStateTypes.h"
 #include "cmValue.h"
 #include "cmValue.h"
 
 
+namespace cm {
+namespace GenEx {
+struct Context;
+struct Evaluation;
+}
+}
+
 class cmake;
 class cmake;
 enum class cmBuildStep;
 enum class cmBuildStep;
 class cmCompiledGeneratorExpression;
 class cmCompiledGeneratorExpression;
@@ -38,7 +45,6 @@ class cmSourceFile;
 struct cmSyntheticTargetCache;
 struct cmSyntheticTargetCache;
 class cmTarget;
 class cmTarget;
 
 
-struct cmGeneratorExpressionContext;
 struct cmGeneratorExpressionDAGChecker;
 struct cmGeneratorExpressionDAGChecker;
 
 
 class cmGeneratorTarget
 class cmGeneratorTarget
@@ -986,7 +992,7 @@ public:
   class TargetPropertyEntry;
   class TargetPropertyEntry;
 
 
   std::string EvaluateInterfaceProperty(
   std::string EvaluateInterfaceProperty(
-    std::string const& prop, cmGeneratorExpressionContext* context,
+    std::string const& prop, cm::GenEx::Evaluation* eval,
     cmGeneratorExpressionDAGChecker* dagCheckerParent, UseTo usage) const;
     cmGeneratorExpressionDAGChecker* dagCheckerParent, UseTo usage) const;
 
 
   struct TransitiveProperty
   struct TransitiveProperty
@@ -1296,7 +1302,7 @@ private:
 
 
   mutable std::unordered_map<std::string, bool> MaybeInterfacePropertyExists;
   mutable std::unordered_map<std::string, bool> MaybeInterfacePropertyExists;
   bool MaybeHaveInterfaceProperty(std::string const& prop,
   bool MaybeHaveInterfaceProperty(std::string const& prop,
-                                  cmGeneratorExpressionContext* context,
+                                  cm::GenEx::Evaluation* eval,
                                   UseTo usage) const;
                                   UseTo usage) const;
 
 
   using TargetPropertyEntryVector =
   using TargetPropertyEntryVector =
@@ -1538,10 +1544,8 @@ public:
     cmFileSet const* fileSet, cmLinkImplItem const& item = NoLinkImplItem);
     cmFileSet const* fileSet, cmLinkImplItem const& item = NoLinkImplItem);
 
 
   virtual std::string const& Evaluate(
   virtual std::string const& Evaluate(
-    cmLocalGenerator* lg, std::string const& config,
-    cmGeneratorTarget const* headTarget,
-    cmGeneratorExpressionDAGChecker* dagChecker,
-    std::string const& language) const = 0;
+    cm::GenEx::Context const& context, cmGeneratorTarget const* headTarget,
+    cmGeneratorExpressionDAGChecker* dagChecker) const = 0;
 
 
   virtual cmListFileBacktrace GetBacktrace() const = 0;
   virtual cmListFileBacktrace GetBacktrace() const = 0;
   virtual std::string const& GetInput() const = 0;
   virtual std::string const& GetInput() const = 0;

+ 14 - 21
Source/cmGeneratorTarget_IncludeDirectories.cxx

@@ -17,6 +17,7 @@
 #include <cmext/algorithm>
 #include <cmext/algorithm>
 
 
 #include "cmEvaluatedTargetProperty.h"
 #include "cmEvaluatedTargetProperty.h"
+#include "cmGenExContext.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGlobalGenerator.h"
 #include "cmGlobalGenerator.h"
 #include "cmLinkItem.h"
 #include "cmLinkItem.h"
@@ -44,16 +45,12 @@ std::string AddLangSpecificInterfaceIncludeDirectories(
   cmGeneratorTarget const* root, cmGeneratorTarget const* target,
   cmGeneratorTarget const* root, cmGeneratorTarget const* target,
   std::string const& lang, std::string const& config,
   std::string const& lang, std::string const& config,
   std::string const& propertyName, IncludeDirectoryFallBack mode,
   std::string const& propertyName, IncludeDirectoryFallBack mode,
-  cmGeneratorExpressionDAGChecker* context)
+  cmGeneratorExpressionDAGChecker* dagCheckerParent)
 {
 {
+  cm::GenEx::Context context(target->LocalGenerator, config);
   cmGeneratorExpressionDAGChecker dagChecker{
   cmGeneratorExpressionDAGChecker dagChecker{
-    target,
-    propertyName,
-    nullptr,
-    context,
-    target->GetLocalGenerator(),
-    config,
-    target->GetBacktrace(),
+    target,           propertyName, nullptr,
+    dagCheckerParent, context,      target->GetBacktrace(),
   };
   };
   switch (dagChecker.Check()) {
   switch (dagChecker.Check()) {
     case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
     case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
@@ -103,14 +100,9 @@ void AddLangSpecificImplicitIncludeDirectories(
 {
 {
   if (auto const* libraries =
   if (auto const* libraries =
         target->GetLinkImplementationLibraries(config, UseTo::Compile)) {
         target->GetLinkImplementationLibraries(config, UseTo::Compile)) {
+    cm::GenEx::Context context(target->LocalGenerator, config, lang);
     cmGeneratorExpressionDAGChecker dagChecker{
     cmGeneratorExpressionDAGChecker dagChecker{
-      target,
-      propertyName,
-      nullptr,
-      nullptr,
-      target->GetLocalGenerator(),
-      config,
-      target->GetBacktrace(),
+      target, propertyName, nullptr, nullptr, context, target->GetBacktrace(),
     };
     };
 
 
     for (cmLinkImplItem const& library : libraries->Libraries) {
     for (cmLinkImplItem const& library : libraries->Libraries) {
@@ -137,8 +129,8 @@ void AddLangSpecificImplicitIncludeDirectories(
           }
           }
 
 
           cmExpandList(AddLangSpecificInterfaceIncludeDirectories(
           cmExpandList(AddLangSpecificInterfaceIncludeDirectories(
-                         target, dependency, lang, config, propertyName, mode,
-                         &dagChecker),
+                         target, dependency, context.Language, context.Config,
+                         propertyName, mode, &dagChecker),
                        entry.Values);
                        entry.Values);
           entries.Entries.emplace_back(std::move(entry));
           entries.Entries.emplace_back(std::move(entry));
         }
         }
@@ -231,9 +223,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
   std::vector<BT<std::string>> includes;
   std::vector<BT<std::string>> includes;
   std::unordered_set<std::string> uniqueIncludes;
   std::unordered_set<std::string> uniqueIncludes;
 
 
+  cm::GenEx::Context context(this->LocalGenerator, config, lang);
+
   cmGeneratorExpressionDAGChecker dagChecker{
   cmGeneratorExpressionDAGChecker dagChecker{
-    this,    "INCLUDE_DIRECTORIES", nullptr,
-    nullptr, this->LocalGenerator,  config,
+    this, "INCLUDE_DIRECTORIES", nullptr, nullptr, context,
   };
   };
 
 
   cmList debugProperties{ this->Makefile->GetDefinition(
   cmList debugProperties{ this->Makefile->GetDefinition(
@@ -244,7 +237,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
   this->DebugIncludesDone = true;
   this->DebugIncludesDone = true;
 
 
   EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
   EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
-    this, config, lang, &dagChecker, this->IncludeDirectoriesEntries);
+    this, context, &dagChecker, this->IncludeDirectoriesEntries);
 
 
   if (lang == "Swift") {
   if (lang == "Swift") {
     AddLangSpecificImplicitIncludeDirectories(
     AddLangSpecificImplicitIncludeDirectories(
@@ -271,7 +264,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetIncludeDirectories(
       entries);
       entries);
   }
   }
 
 
-  AddInterfaceEntries(this, config, "INTERFACE_INCLUDE_DIRECTORIES", lang,
+  AddInterfaceEntries(this, "INTERFACE_INCLUDE_DIRECTORIES", context,
                       &dagChecker, entries, IncludeRuntimeInterface::Yes);
                       &dagChecker, entries, IncludeRuntimeInterface::Yes);
 
 
   processIncludeDirectories(this, entries, includes, uniqueIncludes,
   processIncludeDirectories(this, entries, includes, uniqueIncludes,

+ 9 - 10
Source/cmGeneratorTarget_Link.cxx

@@ -25,6 +25,7 @@
 
 
 #include "cmAlgorithms.h"
 #include "cmAlgorithms.h"
 #include "cmComputeLinkInformation.h"
 #include "cmComputeLinkInformation.h"
+#include "cmGenExContext.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGlobalGenerator.h"
 #include "cmGlobalGenerator.h"
@@ -541,13 +542,14 @@ void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
     return;
     return;
   }
   }
   // Keep this logic in sync with ComputeLinkImplementationLibraries.
   // Keep this logic in sync with ComputeLinkImplementationLibraries.
+  cm::GenEx::Context context(this->LocalGenerator, config,
+                             headTarget->LinkerLanguage);
   cmGeneratorExpressionDAGChecker dagChecker{
   cmGeneratorExpressionDAGChecker dagChecker{
     this,
     this,
     prop,
     prop,
     nullptr,
     nullptr,
     nullptr,
     nullptr,
-    this->LocalGenerator,
-    config,
+    context,
     cmListFileBacktrace(),
     cmListFileBacktrace(),
     cmGeneratorExpressionDAGChecker::ComputingLinkLibraries::Yes,
     cmGeneratorExpressionDAGChecker::ComputingLinkLibraries::Yes,
   };
   };
@@ -565,9 +567,7 @@ void cmGeneratorTarget::ExpandLinkItems(std::string const& prop,
                              entry.Backtrace);
                              entry.Backtrace);
     std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(entry.Value);
     std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(entry.Value);
     cge->SetEvaluateForBuildsystem(true);
     cge->SetEvaluateForBuildsystem(true);
-    cmList libs{ cge->Evaluate(this->LocalGenerator, config, headTarget,
-                               &dagChecker, this,
-                               headTarget->LinkerLanguage) };
+    cmList libs{ cge->Evaluate(context, &dagChecker, headTarget, this) };
 
 
     auto linkFeature = cmLinkItem::DEFAULT;
     auto linkFeature = cmLinkItem::DEFAULT;
     for (auto const& lib : libs) {
     for (auto const& lib : libs) {
@@ -1133,6 +1133,8 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
   std::string const& config, cmOptionalLinkImplementation& impl,
   std::string const& config, cmOptionalLinkImplementation& impl,
   UseTo usage) const
   UseTo usage) const
 {
 {
+  cm::GenEx::Context context(this->LocalGenerator, config,
+                             this->LinkerLanguage);
   cmLocalGenerator const* lg = this->LocalGenerator;
   cmLocalGenerator const* lg = this->LocalGenerator;
   cmMakefile const* mf = lg->GetMakefile();
   cmMakefile const* mf = lg->GetMakefile();
   cmBTStringRange entryRange = this->Target->GetLinkImplementationEntries();
   cmBTStringRange entryRange = this->Target->GetLinkImplementationEntries();
@@ -1145,8 +1147,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
       "LINK_LIBRARIES",
       "LINK_LIBRARIES",
       nullptr,
       nullptr,
       nullptr,
       nullptr,
-      this->LocalGenerator,
-      config,
+      context,
       cmListFileBacktrace(),
       cmListFileBacktrace(),
       cmGeneratorExpressionDAGChecker::ComputingLinkLibraries::Yes,
       cmGeneratorExpressionDAGChecker::ComputingLinkLibraries::Yes,
     };
     };
@@ -1168,9 +1169,7 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
     std::unique_ptr<cmCompiledGeneratorExpression> const cge =
     std::unique_ptr<cmCompiledGeneratorExpression> const cge =
       ge.Parse(entry.Value);
       ge.Parse(entry.Value);
     cge->SetEvaluateForBuildsystem(true);
     cge->SetEvaluateForBuildsystem(true);
-    std::string const& evaluated =
-      cge->Evaluate(this->LocalGenerator, config, this, &dagChecker, nullptr,
-                    this->LinkerLanguage);
+    std::string const& evaluated = cge->Evaluate(context, &dagChecker, this);
     cmList llibs(evaluated);
     cmList llibs(evaluated);
     if (cge->GetHadHeadSensitiveCondition()) {
     if (cge->GetHadHeadSensitiveCondition()) {
       impl.HadHeadSensitiveCondition = true;
       impl.HadHeadSensitiveCondition = true;

+ 6 - 4
Source/cmGeneratorTarget_LinkDirectories.cxx

@@ -14,6 +14,7 @@
 #include <cmext/algorithm>
 #include <cmext/algorithm>
 
 
 #include "cmEvaluatedTargetProperty.h"
 #include "cmEvaluatedTargetProperty.h"
+#include "cmGenExContext.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmLinkItem.h"
 #include "cmLinkItem.h"
 #include "cmList.h"
 #include "cmList.h"
@@ -122,8 +123,9 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories(
   std::vector<BT<std::string>> result;
   std::vector<BT<std::string>> result;
   std::unordered_set<std::string> uniqueDirectories;
   std::unordered_set<std::string> uniqueDirectories;
 
 
+  cm::GenEx::Context context(this->LocalGenerator, config, language);
   cmGeneratorExpressionDAGChecker dagChecker{
   cmGeneratorExpressionDAGChecker dagChecker{
-    this, "LINK_DIRECTORIES", nullptr, nullptr, this->LocalGenerator, config,
+    this, "LINK_DIRECTORIES", nullptr, nullptr, context,
   };
   };
 
 
   cmList debugProperties{ this->Makefile->GetDefinition(
   cmList debugProperties{ this->Makefile->GetDefinition(
@@ -134,10 +136,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDirectories(
   this->DebugLinkDirectoriesDone = true;
   this->DebugLinkDirectoriesDone = true;
 
 
   EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
   EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
-    this, config, language, &dagChecker, this->LinkDirectoriesEntries);
+    this, context, &dagChecker, this->LinkDirectoriesEntries);
 
 
-  AddInterfaceEntries(this, config, "INTERFACE_LINK_DIRECTORIES", language,
-                      &dagChecker, entries, IncludeRuntimeInterface::Yes,
+  AddInterfaceEntries(this, "INTERFACE_LINK_DIRECTORIES", context, &dagChecker,
+                      entries, IncludeRuntimeInterface::Yes,
                       this->GetPolicyStatusCMP0099() == cmPolicies::NEW
                       this->GetPolicyStatusCMP0099() == cmPolicies::NEW
                         ? UseTo::Link
                         ? UseTo::Link
                         : UseTo::Compile);
                         : UseTo::Compile);

+ 41 - 29
Source/cmGeneratorTarget_Options.cxx

@@ -18,6 +18,7 @@
 #include <cmext/string_view>
 #include <cmext/string_view>
 
 
 #include "cmEvaluatedTargetProperty.h"
 #include "cmEvaluatedTargetProperty.h"
+#include "cmGenExContext.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmList.h"
 #include "cmList.h"
 #include "cmListFileCache.h"
 #include "cmListFileCache.h"
@@ -230,8 +231,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileOptions(
   std::vector<BT<std::string>> result;
   std::vector<BT<std::string>> result;
   std::unordered_set<std::string> uniqueOptions;
   std::unordered_set<std::string> uniqueOptions;
 
 
+  cm::GenEx::Context context(this->LocalGenerator, config, language);
+
   cmGeneratorExpressionDAGChecker dagChecker{
   cmGeneratorExpressionDAGChecker dagChecker{
-    this, "COMPILE_OPTIONS", nullptr, nullptr, this->LocalGenerator, config,
+    this, "COMPILE_OPTIONS", nullptr, nullptr, context,
   };
   };
 
 
   cmList debugProperties{ this->Makefile->GetDefinition(
   cmList debugProperties{ this->Makefile->GetDefinition(
@@ -242,10 +245,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileOptions(
   this->DebugCompileOptionsDone = true;
   this->DebugCompileOptionsDone = true;
 
 
   EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
   EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
-    this, config, language, &dagChecker, this->CompileOptionsEntries);
+    this, context, &dagChecker, this->CompileOptionsEntries);
 
 
-  AddInterfaceEntries(this, config, "INTERFACE_COMPILE_OPTIONS", language,
-                      &dagChecker, entries, IncludeRuntimeInterface::Yes);
+  AddInterfaceEntries(this, "INTERFACE_COMPILE_OPTIONS", context, &dagChecker,
+                      entries, IncludeRuntimeInterface::Yes);
 
 
   processOptions(this, entries, result, uniqueOptions, debugOptions,
   processOptions(this, entries, result, uniqueOptions, debugOptions,
                  "compile options", OptionsParse::Shell);
                  "compile options", OptionsParse::Shell);
@@ -270,8 +273,11 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileFeatures(
   std::vector<BT<std::string>> result;
   std::vector<BT<std::string>> result;
   std::unordered_set<std::string> uniqueFeatures;
   std::unordered_set<std::string> uniqueFeatures;
 
 
+  cm::GenEx::Context context(this->LocalGenerator, config,
+                             /*language=*/std::string());
+
   cmGeneratorExpressionDAGChecker dagChecker{
   cmGeneratorExpressionDAGChecker dagChecker{
-    this, "COMPILE_FEATURES", nullptr, nullptr, this->LocalGenerator, config,
+    this, "COMPILE_FEATURES", nullptr, nullptr, context,
   };
   };
 
 
   cmList debugProperties{ this->Makefile->GetDefinition(
   cmList debugProperties{ this->Makefile->GetDefinition(
@@ -282,11 +288,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileFeatures(
   this->DebugCompileFeaturesDone = true;
   this->DebugCompileFeaturesDone = true;
 
 
   EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
   EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
-    this, config, std::string(), &dagChecker, this->CompileFeaturesEntries);
+    this, context, &dagChecker, this->CompileFeaturesEntries);
 
 
-  AddInterfaceEntries(this, config, "INTERFACE_COMPILE_FEATURES",
-                      std::string(), &dagChecker, entries,
-                      IncludeRuntimeInterface::Yes);
+  AddInterfaceEntries(this, "INTERFACE_COMPILE_FEATURES", context, &dagChecker,
+                      entries, IncludeRuntimeInterface::Yes);
 
 
   processOptions(this, entries, result, uniqueFeatures, debugFeatures,
   processOptions(this, entries, result, uniqueFeatures, debugFeatures,
                  "compile features", OptionsParse::None);
                  "compile features", OptionsParse::None);
@@ -319,9 +324,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
   std::vector<BT<std::string>> list;
   std::vector<BT<std::string>> list;
   std::unordered_set<std::string> uniqueOptions;
   std::unordered_set<std::string> uniqueOptions;
 
 
+  cm::GenEx::Context context(this->LocalGenerator, config, language);
+
   cmGeneratorExpressionDAGChecker dagChecker{
   cmGeneratorExpressionDAGChecker dagChecker{
-    this,    "COMPILE_DEFINITIONS", nullptr,
-    nullptr, this->LocalGenerator,  config,
+    this, "COMPILE_DEFINITIONS", nullptr, nullptr, context,
   };
   };
 
 
   cmList debugProperties{ this->Makefile->GetDefinition(
   cmList debugProperties{ this->Makefile->GetDefinition(
@@ -332,9 +338,9 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetCompileDefinitions(
   this->DebugCompileDefinitionsDone = true;
   this->DebugCompileDefinitionsDone = true;
 
 
   EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
   EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
-    this, config, language, &dagChecker, this->CompileDefinitionsEntries);
+    this, context, &dagChecker, this->CompileDefinitionsEntries);
 
 
-  AddInterfaceEntries(this, config, "INTERFACE_COMPILE_DEFINITIONS", language,
+  AddInterfaceEntries(this, "INTERFACE_COMPILE_DEFINITIONS", context,
                       &dagChecker, entries, IncludeRuntimeInterface::Yes);
                       &dagChecker, entries, IncludeRuntimeInterface::Yes);
 
 
   processOptions(this, entries, list, uniqueOptions, debugDefines,
   processOptions(this, entries, list, uniqueOptions, debugDefines,
@@ -356,8 +362,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders(
   }
   }
   std::unordered_set<std::string> uniqueOptions;
   std::unordered_set<std::string> uniqueOptions;
 
 
+  cm::GenEx::Context context(this->LocalGenerator, config, language);
+
   cmGeneratorExpressionDAGChecker dagChecker{
   cmGeneratorExpressionDAGChecker dagChecker{
-    this, "PRECOMPILE_HEADERS", nullptr, nullptr, this->LocalGenerator, config,
+    this, "PRECOMPILE_HEADERS", nullptr, nullptr, context,
   };
   };
 
 
   cmList debugProperties{ this->Makefile->GetDefinition(
   cmList debugProperties{ this->Makefile->GetDefinition(
@@ -369,9 +377,9 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetPrecompileHeaders(
   this->DebugPrecompileHeadersDone = true;
   this->DebugPrecompileHeadersDone = true;
 
 
   EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
   EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
-    this, config, language, &dagChecker, this->PrecompileHeadersEntries);
+    this, context, &dagChecker, this->PrecompileHeadersEntries);
 
 
-  AddInterfaceEntries(this, config, "INTERFACE_PRECOMPILE_HEADERS", language,
+  AddInterfaceEntries(this, "INTERFACE_PRECOMPILE_HEADERS", context,
                       &dagChecker, entries, IncludeRuntimeInterface::Yes);
                       &dagChecker, entries, IncludeRuntimeInterface::Yes);
 
 
   std::vector<BT<std::string>> list;
   std::vector<BT<std::string>> list;
@@ -413,8 +421,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
   std::vector<BT<std::string>> result;
   std::vector<BT<std::string>> result;
   std::unordered_set<std::string> uniqueOptions;
   std::unordered_set<std::string> uniqueOptions;
 
 
+  cm::GenEx::Context context(this->LocalGenerator, config, language);
+
   cmGeneratorExpressionDAGChecker dagChecker{
   cmGeneratorExpressionDAGChecker dagChecker{
-    this, "LINK_OPTIONS", nullptr, nullptr, this->LocalGenerator, config,
+    this, "LINK_OPTIONS", nullptr, nullptr, context,
   };
   };
 
 
   cmList debugProperties{ this->Makefile->GetDefinition(
   cmList debugProperties{ this->Makefile->GetDefinition(
@@ -425,10 +435,10 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkOptions(
   this->DebugLinkOptionsDone = true;
   this->DebugLinkOptionsDone = true;
 
 
   EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
   EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
-    this, config, language, &dagChecker, this->LinkOptionsEntries);
+    this, context, &dagChecker, this->LinkOptionsEntries);
 
 
-  AddInterfaceEntries(this, config, "INTERFACE_LINK_OPTIONS", language,
-                      &dagChecker, entries, IncludeRuntimeInterface::Yes,
+  AddInterfaceEntries(this, "INTERFACE_LINK_OPTIONS", context, &dagChecker,
+                      entries, IncludeRuntimeInterface::Yes,
                       this->GetPolicyStatusCMP0099() == cmPolicies::NEW
                       this->GetPolicyStatusCMP0099() == cmPolicies::NEW
                         ? UseTo::Link
                         ? UseTo::Link
                         : UseTo::Compile);
                         : UseTo::Compile);
@@ -595,17 +605,18 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetStaticLibraryLinkOptions(
   std::vector<BT<std::string>> result;
   std::vector<BT<std::string>> result;
   std::unordered_set<std::string> uniqueOptions;
   std::unordered_set<std::string> uniqueOptions;
 
 
+  cm::GenEx::Context context(this->LocalGenerator, config, language);
+
   cmGeneratorExpressionDAGChecker dagChecker{
   cmGeneratorExpressionDAGChecker dagChecker{
-    this,    "STATIC_LIBRARY_OPTIONS", nullptr,
-    nullptr, this->LocalGenerator,     config,
+    this, "STATIC_LIBRARY_OPTIONS", nullptr, nullptr, context,
   };
   };
 
 
   EvaluatedTargetPropertyEntries entries;
   EvaluatedTargetPropertyEntries entries;
   if (cmValue linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
   if (cmValue linkOptions = this->GetProperty("STATIC_LIBRARY_OPTIONS")) {
     std::unique_ptr<TargetPropertyEntry> entry = TargetPropertyEntry::Create(
     std::unique_ptr<TargetPropertyEntry> entry = TargetPropertyEntry::Create(
       *this->LocalGenerator->GetCMakeInstance(), *linkOptions);
       *this->LocalGenerator->GetCMakeInstance(), *linkOptions);
-    entries.Entries.emplace_back(EvaluateTargetPropertyEntry(
-      this, config, language, &dagChecker, *entry));
+    entries.Entries.emplace_back(
+      EvaluateTargetPropertyEntry(this, context, &dagChecker, *entry));
   }
   }
   processOptions(this, entries, result, uniqueOptions, false,
   processOptions(this, entries, result, uniqueOptions, false,
                  "static library link options", OptionsParse::Shell);
                  "static library link options", OptionsParse::Shell);
@@ -640,8 +651,9 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends(
 {
 {
   std::vector<BT<std::string>> result;
   std::vector<BT<std::string>> result;
   std::unordered_set<std::string> uniqueOptions;
   std::unordered_set<std::string> uniqueOptions;
+  cm::GenEx::Context context(this->LocalGenerator, config, language);
   cmGeneratorExpressionDAGChecker dagChecker{
   cmGeneratorExpressionDAGChecker dagChecker{
-    this, "LINK_DEPENDS", nullptr, nullptr, this->LocalGenerator, config,
+    this, "LINK_DEPENDS", nullptr, nullptr, context,
   };
   };
 
 
   EvaluatedTargetPropertyEntries entries;
   EvaluatedTargetPropertyEntries entries;
@@ -650,12 +662,12 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetLinkDepends(
     for (auto const& depend : depends) {
     for (auto const& depend : depends) {
       std::unique_ptr<TargetPropertyEntry> entry = TargetPropertyEntry::Create(
       std::unique_ptr<TargetPropertyEntry> entry = TargetPropertyEntry::Create(
         *this->LocalGenerator->GetCMakeInstance(), depend);
         *this->LocalGenerator->GetCMakeInstance(), depend);
-      entries.Entries.emplace_back(EvaluateTargetPropertyEntry(
-        this, config, language, &dagChecker, *entry));
+      entries.Entries.emplace_back(
+        EvaluateTargetPropertyEntry(this, context, &dagChecker, *entry));
     }
     }
   }
   }
-  AddInterfaceEntries(this, config, "INTERFACE_LINK_DEPENDS", language,
-                      &dagChecker, entries, IncludeRuntimeInterface::Yes,
+  AddInterfaceEntries(this, "INTERFACE_LINK_DEPENDS", context, &dagChecker,
+                      entries, IncludeRuntimeInterface::Yes,
                       this->GetPolicyStatusCMP0099() == cmPolicies::NEW
                       this->GetPolicyStatusCMP0099() == cmPolicies::NEW
                         ? UseTo::Link
                         ? UseTo::Link
                         : UseTo::Compile);
                         : UseTo::Compile);

+ 22 - 18
Source/cmGeneratorTarget_Sources.cxx

@@ -24,6 +24,7 @@
 #include "cmAlgorithms.h"
 #include "cmAlgorithms.h"
 #include "cmEvaluatedTargetProperty.h"
 #include "cmEvaluatedTargetProperty.h"
 #include "cmFileSet.h"
 #include "cmFileSet.h"
+#include "cmGenExContext.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGlobalGenerator.h"
 #include "cmGlobalGenerator.h"
@@ -46,12 +47,13 @@ namespace {
 using UseTo = cmGeneratorTarget::UseTo;
 using UseTo = cmGeneratorTarget::UseTo;
 
 
 void AddObjectEntries(cmGeneratorTarget const* headTarget,
 void AddObjectEntries(cmGeneratorTarget const* headTarget,
-                      std::string const& config,
+                      cm::GenEx::Context const& context,
                       cmGeneratorExpressionDAGChecker* dagChecker,
                       cmGeneratorExpressionDAGChecker* dagChecker,
                       EvaluatedTargetPropertyEntries& entries)
                       EvaluatedTargetPropertyEntries& entries)
 {
 {
   if (cmLinkImplementationLibraries const* impl =
   if (cmLinkImplementationLibraries const* impl =
-        headTarget->GetLinkImplementationLibraries(config, UseTo::Link)) {
+        headTarget->GetLinkImplementationLibraries(context.Config,
+                                                   UseTo::Link)) {
     entries.HadContextSensitiveCondition = impl->HadContextSensitiveCondition;
     entries.HadContextSensitiveCondition = impl->HadContextSensitiveCondition;
     for (cmLinkImplItem const& lib : impl->Libraries) {
     for (cmLinkImplItem const& lib : impl->Libraries) {
       if (lib.Target &&
       if (lib.Target &&
@@ -66,8 +68,7 @@ void AddObjectEntries(cmGeneratorTarget const* headTarget,
         cge->SetEvaluateForBuildsystem(true);
         cge->SetEvaluateForBuildsystem(true);
 
 
         EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
         EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
-        cmExpandList(cge->Evaluate(headTarget->GetLocalGenerator(), config,
-                                   headTarget, dagChecker),
+        cmExpandList(cge->Evaluate(context, dagChecker, headTarget),
                      ee.Values);
                      ee.Values);
         if (cge->GetHadContextSensitiveCondition()) {
         if (cge->GetHadContextSensitiveCondition()) {
           ee.ContextDependent = true;
           ee.ContextDependent = true;
@@ -79,14 +80,14 @@ void AddObjectEntries(cmGeneratorTarget const* headTarget,
 }
 }
 
 
 void addFileSetEntry(cmGeneratorTarget const* headTarget,
 void addFileSetEntry(cmGeneratorTarget const* headTarget,
-                     std::string const& config,
+                     cm::GenEx::Context const& context,
                      cmGeneratorExpressionDAGChecker* dagChecker,
                      cmGeneratorExpressionDAGChecker* dagChecker,
                      cmFileSet const* fileSet,
                      cmFileSet const* fileSet,
                      EvaluatedTargetPropertyEntries& entries)
                      EvaluatedTargetPropertyEntries& entries)
 {
 {
   auto dirCges = fileSet->CompileDirectoryEntries();
   auto dirCges = fileSet->CompileDirectoryEntries();
-  auto dirs = fileSet->EvaluateDirectoryEntries(
-    dirCges, headTarget->GetLocalGenerator(), config, headTarget, dagChecker);
+  auto dirs = fileSet->EvaluateDirectoryEntries(dirCges, context, headTarget,
+                                                dagChecker);
   bool contextSensitiveDirs = false;
   bool contextSensitiveDirs = false;
   for (auto const& dirCge : dirCges) {
   for (auto const& dirCge : dirCges) {
     if (dirCge->GetHadContextSensitiveCondition()) {
     if (dirCge->GetHadContextSensitiveCondition()) {
@@ -99,7 +100,7 @@ void addFileSetEntry(cmGeneratorTarget const* headTarget,
     auto tpe = cmGeneratorTarget::TargetPropertyEntry::CreateFileSet(
     auto tpe = cmGeneratorTarget::TargetPropertyEntry::CreateFileSet(
       dirs, contextSensitiveDirs, std::move(entryCge), fileSet);
       dirs, contextSensitiveDirs, std::move(entryCge), fileSet);
     entries.Entries.emplace_back(
     entries.Entries.emplace_back(
-      EvaluateTargetPropertyEntry(headTarget, config, "", dagChecker, *tpe));
+      EvaluateTargetPropertyEntry(headTarget, context, dagChecker, *tpe));
     EvaluatedTargetPropertyEntry const& entry = entries.Entries.back();
     EvaluatedTargetPropertyEntry const& entry = entries.Entries.back();
     for (auto const& file : entry.Values) {
     for (auto const& file : entry.Values) {
       auto* sf = headTarget->Makefile->GetOrCreateSource(file);
       auto* sf = headTarget->Makefile->GetOrCreateSource(file);
@@ -139,20 +140,20 @@ void addFileSetEntry(cmGeneratorTarget const* headTarget,
 }
 }
 
 
 void AddFileSetEntries(cmGeneratorTarget const* headTarget,
 void AddFileSetEntries(cmGeneratorTarget const* headTarget,
-                       std::string const& config,
+                       cm::GenEx::Context const& context,
                        cmGeneratorExpressionDAGChecker* dagChecker,
                        cmGeneratorExpressionDAGChecker* dagChecker,
                        EvaluatedTargetPropertyEntries& entries)
                        EvaluatedTargetPropertyEntries& entries)
 {
 {
   for (auto const& entry : headTarget->Target->GetHeaderSetsEntries()) {
   for (auto const& entry : headTarget->Target->GetHeaderSetsEntries()) {
     for (auto const& name : cmList{ entry.Value }) {
     for (auto const& name : cmList{ entry.Value }) {
       auto const* headerSet = headTarget->Target->GetFileSet(name);
       auto const* headerSet = headTarget->Target->GetFileSet(name);
-      addFileSetEntry(headTarget, config, dagChecker, headerSet, entries);
+      addFileSetEntry(headTarget, context, dagChecker, headerSet, entries);
     }
     }
   }
   }
   for (auto const& entry : headTarget->Target->GetCxxModuleSetsEntries()) {
   for (auto const& entry : headTarget->Target->GetCxxModuleSetsEntries()) {
     for (auto const& name : cmList{ entry.Value }) {
     for (auto const& name : cmList{ entry.Value }) {
       auto const* cxxModuleSet = headTarget->Target->GetFileSet(name);
       auto const* cxxModuleSet = headTarget->Target->GetFileSet(name);
-      addFileSetEntry(headTarget, config, dagChecker, cxxModuleSet, entries);
+      addFileSetEntry(headTarget, context, dagChecker, cxxModuleSet, entries);
     }
     }
   }
   }
 }
 }
@@ -240,12 +241,15 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
 
 
   this->DebugSourcesDone = true;
   this->DebugSourcesDone = true;
 
 
+  cm::GenEx::Context context(this->LocalGenerator, config,
+                             /*language=*/std::string());
+
   cmGeneratorExpressionDAGChecker dagChecker{
   cmGeneratorExpressionDAGChecker dagChecker{
-    this, "SOURCES", nullptr, nullptr, this->LocalGenerator, config,
+    this, "SOURCES", nullptr, nullptr, context,
   };
   };
 
 
   EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
   EvaluatedTargetPropertyEntries entries = EvaluateTargetPropertyEntries(
-    this, config, std::string(), &dagChecker, this->SourceEntries);
+    this, context, &dagChecker, this->SourceEntries);
 
 
   std::unordered_set<std::string> uniqueSrcs;
   std::unordered_set<std::string> uniqueSrcs;
   bool contextDependentDirectSources =
   bool contextDependentDirectSources =
@@ -253,9 +257,9 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
 
 
   // Collect INTERFACE_SOURCES of all direct link-dependencies.
   // Collect INTERFACE_SOURCES of all direct link-dependencies.
   EvaluatedTargetPropertyEntries linkInterfaceSourcesEntries;
   EvaluatedTargetPropertyEntries linkInterfaceSourcesEntries;
-  AddInterfaceEntries(this, config, "INTERFACE_SOURCES", std::string(),
-                      &dagChecker, linkInterfaceSourcesEntries,
-                      IncludeRuntimeInterface::No, UseTo::Compile);
+  AddInterfaceEntries(this, "INTERFACE_SOURCES", context, &dagChecker,
+                      linkInterfaceSourcesEntries, IncludeRuntimeInterface::No,
+                      UseTo::Compile);
   bool contextDependentInterfaceSources = processSources(
   bool contextDependentInterfaceSources = processSources(
     this, linkInterfaceSourcesEntries, files, uniqueSrcs, debugSources);
     this, linkInterfaceSourcesEntries, files, uniqueSrcs, debugSources);
 
 
@@ -263,7 +267,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
   bool contextDependentObjects = false;
   bool contextDependentObjects = false;
   if (this->GetType() != cmStateEnums::OBJECT_LIBRARY) {
   if (this->GetType() != cmStateEnums::OBJECT_LIBRARY) {
     EvaluatedTargetPropertyEntries linkObjectsEntries;
     EvaluatedTargetPropertyEntries linkObjectsEntries;
-    AddObjectEntries(this, config, &dagChecker, linkObjectsEntries);
+    AddObjectEntries(this, context, &dagChecker, linkObjectsEntries);
     contextDependentObjects = processSources(this, linkObjectsEntries, files,
     contextDependentObjects = processSources(this, linkObjectsEntries, files,
                                              uniqueSrcs, debugSources);
                                              uniqueSrcs, debugSources);
     // Note that for imported targets or multi-config generators supporting
     // Note that for imported targets or multi-config generators supporting
@@ -274,7 +278,7 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
 
 
   // Collect this target's file sets.
   // Collect this target's file sets.
   EvaluatedTargetPropertyEntries fileSetEntries;
   EvaluatedTargetPropertyEntries fileSetEntries;
-  AddFileSetEntries(this, config, &dagChecker, fileSetEntries);
+  AddFileSetEntries(this, context, &dagChecker, fileSetEntries);
   bool contextDependentFileSets =
   bool contextDependentFileSets =
     processSources(this, fileSetEntries, files, uniqueSrcs, debugSources);
     processSources(this, fileSetEntries, files, uniqueSrcs, debugSources);
 
 

+ 16 - 15
Source/cmGeneratorTarget_TargetPropertyEntry.cxx

@@ -17,7 +17,12 @@
 #include "cmList.h"
 #include "cmList.h"
 #include "cmListFileCache.h"
 #include "cmListFileCache.h"
 
 
-class cmLocalGenerator;
+namespace cm {
+namespace GenEx {
+struct Context;
+}
+}
+
 class cmake;
 class cmake;
 struct cmGeneratorExpressionDAGChecker;
 struct cmGeneratorExpressionDAGChecker;
 
 
@@ -33,10 +38,9 @@ public:
   {
   {
   }
   }
 
 
-  std::string const& Evaluate(cmLocalGenerator*, std::string const&,
+  std::string const& Evaluate(cm::GenEx::Context const&,
                               cmGeneratorTarget const*,
                               cmGeneratorTarget const*,
-                              cmGeneratorExpressionDAGChecker*,
-                              std::string const&) const override
+                              cmGeneratorExpressionDAGChecker*) const override
   {
   {
     return this->PropertyValue.Value;
     return this->PropertyValue.Value;
   }
   }
@@ -64,13 +68,11 @@ public:
   {
   {
   }
   }
 
 
-  std::string const& Evaluate(cmLocalGenerator* lg, std::string const& config,
-                              cmGeneratorTarget const* headTarget,
-                              cmGeneratorExpressionDAGChecker* dagChecker,
-                              std::string const& language) const override
+  std::string const& Evaluate(
+    cm::GenEx::Context const& context, cmGeneratorTarget const* headTarget,
+    cmGeneratorExpressionDAGChecker* dagChecker) const override
   {
   {
-    return this->ge->Evaluate(lg, config, headTarget, dagChecker, nullptr,
-                              language);
+    return this->ge->Evaluate(context, dagChecker, headTarget);
   }
   }
 
 
   cmListFileBacktrace GetBacktrace() const override
   cmListFileBacktrace GetBacktrace() const override
@@ -105,14 +107,13 @@ public:
   {
   {
   }
   }
 
 
-  std::string const& Evaluate(cmLocalGenerator* lg, std::string const& config,
-                              cmGeneratorTarget const* headTarget,
-                              cmGeneratorExpressionDAGChecker* dagChecker,
-                              std::string const& /*lang*/) const override
+  std::string const& Evaluate(
+    cm::GenEx::Context const& context, cmGeneratorTarget const* headTarget,
+    cmGeneratorExpressionDAGChecker* dagChecker) const override
   {
   {
     std::map<std::string, std::vector<std::string>> filesPerDir;
     std::map<std::string, std::vector<std::string>> filesPerDir;
     this->FileSet->EvaluateFileEntry(this->BaseDirs, filesPerDir,
     this->FileSet->EvaluateFileEntry(this->BaseDirs, filesPerDir,
-                                     this->EntryCge, lg, config, headTarget,
+                                     this->EntryCge, context, headTarget,
                                      dagChecker);
                                      dagChecker);
 
 
     std::vector<std::string> files;
     std::vector<std::string> files;

+ 27 - 35
Source/cmGeneratorTarget_TransitiveProperty.cxx

@@ -15,8 +15,9 @@
 #include <cm/string_view>
 #include <cm/string_view>
 #include <cmext/string_view>
 #include <cmext/string_view>
 
 
+#include "cmGenExContext.h"
+#include "cmGenExEvaluation.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpression.h"
-#include "cmGeneratorExpressionContext.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGeneratorExpressionNode.h"
 #include "cmGeneratorExpressionNode.h"
 #include "cmLinkItem.h"
 #include "cmLinkItem.h"
@@ -54,11 +55,11 @@ std::map<cm::string_view, TransitiveProperty> const
       { "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES"_s, UseTo::Compile } },
       { "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES"_s, UseTo::Compile } },
   };
   };
 
 
-bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
-  std::string const& prop, cmGeneratorExpressionContext* context,
-  UseTo usage) const
+bool cmGeneratorTarget::MaybeHaveInterfaceProperty(std::string const& prop,
+                                                   cm::GenEx::Evaluation* eval,
+                                                   UseTo usage) const
 {
 {
-  std::string const key = prop + '@' + context->Config;
+  std::string const key = prop + '@' + eval->Context.Config;
   auto i = this->MaybeInterfacePropertyExists.find(key);
   auto i = this->MaybeInterfacePropertyExists.find(key);
   if (i == this->MaybeInterfacePropertyExists.end()) {
   if (i == this->MaybeInterfacePropertyExists.end()) {
     // Insert an entry now in case there is a cycle.
     // Insert an entry now in case there is a cycle.
@@ -71,9 +72,9 @@ bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
     // Otherwise, recurse to interface dependencies.
     // Otherwise, recurse to interface dependencies.
     if (!maybeInterfaceProp) {
     if (!maybeInterfaceProp) {
       cmGeneratorTarget const* headTarget =
       cmGeneratorTarget const* headTarget =
-        context->HeadTarget ? context->HeadTarget : this;
+        eval->HeadTarget ? eval->HeadTarget : this;
       if (cmLinkInterfaceLibraries const* iface =
       if (cmLinkInterfaceLibraries const* iface =
-            this->GetLinkInterfaceLibraries(context->Config, headTarget,
+            this->GetLinkInterfaceLibraries(eval->Context.Config, headTarget,
                                             usage)) {
                                             usage)) {
         if (iface->HadHeadSensitiveCondition) {
         if (iface->HadHeadSensitiveCondition) {
           // With a different head target we may get to a library with
           // With a different head target we may get to a library with
@@ -84,7 +85,7 @@ bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
           // head target, so we can follow them.
           // head target, so we can follow them.
           for (cmLinkItem const& lib : iface->Libraries) {
           for (cmLinkItem const& lib : iface->Libraries) {
             if (lib.Target &&
             if (lib.Target &&
-                lib.Target->MaybeHaveInterfaceProperty(prop, context, usage)) {
+                lib.Target->MaybeHaveInterfaceProperty(prop, eval, usage)) {
               maybeInterfaceProp = true;
               maybeInterfaceProp = true;
               break;
               break;
             }
             }
@@ -97,13 +98,13 @@ bool cmGeneratorTarget::MaybeHaveInterfaceProperty(
 }
 }
 
 
 std::string cmGeneratorTarget::EvaluateInterfaceProperty(
 std::string cmGeneratorTarget::EvaluateInterfaceProperty(
-  std::string const& prop, cmGeneratorExpressionContext* context,
+  std::string const& prop, cm::GenEx::Evaluation* eval,
   cmGeneratorExpressionDAGChecker* dagCheckerParent, UseTo usage) const
   cmGeneratorExpressionDAGChecker* dagCheckerParent, UseTo usage) const
 {
 {
   std::string result;
   std::string result;
 
 
   // If the property does not appear transitively at all, we are done.
   // If the property does not appear transitively at all, we are done.
-  if (!this->MaybeHaveInterfaceProperty(prop, context, usage)) {
+  if (!this->MaybeHaveInterfaceProperty(prop, eval, usage)) {
     return result;
     return result;
   }
   }
 
 
@@ -111,18 +112,12 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
   // a subset of TargetPropertyNode::Evaluate without stringify/parse steps
   // a subset of TargetPropertyNode::Evaluate without stringify/parse steps
   // but sufficient for transitive interface properties.
   // but sufficient for transitive interface properties.
   cmGeneratorExpressionDAGChecker dagChecker{
   cmGeneratorExpressionDAGChecker dagChecker{
-    this,
-    prop,
-    nullptr,
-    dagCheckerParent,
-    context->LG,
-    context->Config,
-    context->Backtrace,
+    this, prop, nullptr, dagCheckerParent, eval->Context, eval->Backtrace,
   };
   };
   switch (dagChecker.Check()) {
   switch (dagChecker.Check()) {
     case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
     case cmGeneratorExpressionDAGChecker::SELF_REFERENCE:
       dagChecker.ReportError(
       dagChecker.ReportError(
-        context, "$<TARGET_PROPERTY:" + this->GetName() + "," + prop + ">");
+        eval, "$<TARGET_PROPERTY:" + this->GetName() + "," + prop + ">");
       return result;
       return result;
     case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
     case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE:
       // No error. We just skip cyclic references.
       // No error. We just skip cyclic references.
@@ -134,17 +129,16 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
   }
   }
 
 
   cmGeneratorTarget const* headTarget =
   cmGeneratorTarget const* headTarget =
-    context->HeadTarget ? context->HeadTarget : this;
+    eval->HeadTarget ? eval->HeadTarget : this;
 
 
   if (cmValue p = this->GetProperty(prop)) {
   if (cmValue p = this->GetProperty(prop)) {
     result = cmGeneratorExpressionNode::EvaluateDependentExpression(
     result = cmGeneratorExpressionNode::EvaluateDependentExpression(
-      *p, context->LG, context, headTarget, &dagChecker, this);
+      *p, eval, headTarget, &dagChecker, this);
   }
   }
 
 
-  if (cmLinkInterfaceLibraries const* iface =
-        this->GetLinkInterfaceLibraries(context->Config, headTarget, usage)) {
-    context->HadContextSensitiveCondition =
-      context->HadContextSensitiveCondition ||
+  if (cmLinkInterfaceLibraries const* iface = this->GetLinkInterfaceLibraries(
+        eval->Context.Config, headTarget, usage)) {
+    eval->HadContextSensitiveCondition = eval->HadContextSensitiveCondition ||
       iface->HadContextSensitiveCondition;
       iface->HadContextSensitiveCondition;
     for (cmLinkItem const& lib : iface->Libraries) {
     for (cmLinkItem const& lib : iface->Libraries) {
       // Broken code can have a target in its own link interface.
       // Broken code can have a target in its own link interface.
@@ -154,12 +148,11 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
         // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in the
         // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in the
         // above property and hand-evaluate it as if it were compiled.
         // above property and hand-evaluate it as if it were compiled.
         // Create a context as cmCompiledGeneratorExpression::Evaluate does.
         // Create a context as cmCompiledGeneratorExpression::Evaluate does.
-        cmGeneratorExpressionContext libContext(
-          context->LG, context->Config, context->Quiet, headTarget, this,
-          context->EvaluateForBuildsystem, context->Backtrace,
-          context->Language);
+        cm::GenEx::Evaluation libEval(eval->Context, eval->Quiet, headTarget,
+                                      this, eval->EvaluateForBuildsystem,
+                                      eval->Backtrace);
         std::string libResult = cmGeneratorExpression::StripEmptyListElements(
         std::string libResult = cmGeneratorExpression::StripEmptyListElements(
-          lib.Target->EvaluateInterfaceProperty(prop, &libContext, &dagChecker,
+          lib.Target->EvaluateInterfaceProperty(prop, &libEval, &dagChecker,
                                                 usage));
                                                 usage));
         if (!libResult.empty()) {
         if (!libResult.empty()) {
           if (result.empty()) {
           if (result.empty()) {
@@ -170,12 +163,11 @@ std::string cmGeneratorTarget::EvaluateInterfaceProperty(
             result += libResult;
             result += libResult;
           }
           }
         }
         }
-        context->HadContextSensitiveCondition =
-          context->HadContextSensitiveCondition ||
-          libContext.HadContextSensitiveCondition;
-        context->HadHeadSensitiveCondition =
-          context->HadHeadSensitiveCondition ||
-          libContext.HadHeadSensitiveCondition;
+        eval->HadContextSensitiveCondition =
+          eval->HadContextSensitiveCondition ||
+          libEval.HadContextSensitiveCondition;
+        eval->HadHeadSensitiveCondition =
+          eval->HadHeadSensitiveCondition || libEval.HadHeadSensitiveCondition;
       }
       }
     }
     }
   }
   }

+ 7 - 4
Source/cmInstallFileSetGenerator.cxx

@@ -12,6 +12,7 @@
 #include <cmext/string_view>
 #include <cmext/string_view>
 
 
 #include "cmFileSet.h"
 #include "cmFileSet.h"
+#include "cmGenExContext.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
 #include "cmGlobalGenerator.h"
 #include "cmGlobalGenerator.h"
@@ -122,14 +123,16 @@ cmInstallFileSetGenerator::CalculateFilesPerDir(
 {
 {
   std::map<std::string, std::vector<std::string>> result;
   std::map<std::string, std::vector<std::string>> result;
 
 
+  cm::GenEx::Context context(this->LocalGenerator, config);
+
   auto dirCges = this->FileSet->CompileDirectoryEntries();
   auto dirCges = this->FileSet->CompileDirectoryEntries();
-  auto dirs = this->FileSet->EvaluateDirectoryEntries(
-    dirCges, this->LocalGenerator, config, this->Target);
+  auto dirs =
+    this->FileSet->EvaluateDirectoryEntries(dirCges, context, this->Target);
 
 
   auto fileCges = this->FileSet->CompileFileEntries();
   auto fileCges = this->FileSet->CompileFileEntries();
   for (auto const& fileCge : fileCges) {
   for (auto const& fileCge : fileCges) {
-    this->FileSet->EvaluateFileEntry(
-      dirs, result, fileCge, this->LocalGenerator, config, this->Target);
+    this->FileSet->EvaluateFileEntry(dirs, result, fileCge, context,
+                                     this->Target);
   }
   }
 
 
   return result;
   return result;

+ 4 - 4
Source/cmMakefileTargetGenerator.cxx

@@ -23,6 +23,7 @@
 #include "cmCustomCommand.h"
 #include "cmCustomCommand.h"
 #include "cmCustomCommandGenerator.h"
 #include "cmCustomCommandGenerator.h"
 #include "cmFileSet.h"
 #include "cmFileSet.h"
+#include "cmGenExContext.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorOptions.h"
 #include "cmGeneratorOptions.h"
@@ -205,6 +206,7 @@ void cmMakefileTargetGenerator::CreateRuleFile()
 
 
 void cmMakefileTargetGenerator::WriteTargetBuildRules()
 void cmMakefileTargetGenerator::WriteTargetBuildRules()
 {
 {
+  cm::GenEx::Context context(this->LocalGenerator, this->GetConfigName());
   this->GeneratorTarget->CheckCxxModuleStatus(this->GetConfigName());
   this->GeneratorTarget->CheckCxxModuleStatus(this->GetConfigName());
 
 
   // -- Write the custom commands for this target
   // -- Write the custom commands for this target
@@ -362,13 +364,11 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
     auto fileEntries = file_set->CompileFileEntries();
     auto fileEntries = file_set->CompileFileEntries();
     auto directoryEntries = file_set->CompileDirectoryEntries();
     auto directoryEntries = file_set->CompileDirectoryEntries();
     auto directories = file_set->EvaluateDirectoryEntries(
     auto directories = file_set->EvaluateDirectoryEntries(
-      directoryEntries, this->LocalGenerator, this->GetConfigName(),
-      this->GeneratorTarget);
+      directoryEntries, context, this->GeneratorTarget);
 
 
     std::map<std::string, std::vector<std::string>> files;
     std::map<std::string, std::vector<std::string>> files;
     for (auto const& entry : fileEntries) {
     for (auto const& entry : fileEntries) {
-      file_set->EvaluateFileEntry(directories, files, entry,
-                                  this->LocalGenerator, this->GetConfigName(),
+      file_set->EvaluateFileEntry(directories, files, entry, context,
                                   this->GeneratorTarget);
                                   this->GeneratorTarget);
     }
     }
 
 

+ 11 - 11
Source/cmQtAutoGenInitializer.cxx

@@ -31,6 +31,7 @@
 #include "cmCustomCommand.h"
 #include "cmCustomCommand.h"
 #include "cmCustomCommandLines.h"
 #include "cmCustomCommandLines.h"
 #include "cmEvaluatedTargetProperty.h"
 #include "cmEvaluatedTargetProperty.h"
+#include "cmGenExContext.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratedFileStream.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpression.h"
 #include "cmGeneratorExpressionDAGChecker.h"
 #include "cmGeneratorExpressionDAGChecker.h"
@@ -1966,25 +1967,24 @@ bool cmQtAutoGenInitializer::SetupWriteAutogenInfo()
     if (this->MultiConfig) {
     if (this->MultiConfig) {
       for (auto const& cfg : this->ConfigsList) {
       for (auto const& cfg : this->ConfigsList) {
         if (!cfg.empty()) {
         if (!cfg.empty()) {
+          cm::GenEx::Context context(this->LocalGen, cfg, "CXX");
           cmGeneratorExpressionDAGChecker dagChecker{
           cmGeneratorExpressionDAGChecker dagChecker{
-            this->GenTarget, "AUTOMOC_MACRO_NAMES", nullptr,
-            nullptr,         this->LocalGen,        cfg,
+            this->GenTarget, "AUTOMOC_MACRO_NAMES", nullptr, nullptr, context,
           };
           };
-          AddInterfaceEntries(this->GenTarget, cfg,
-                              "INTERFACE_AUTOMOC_MACRO_NAMES", "CXX",
-                              &dagChecker, InterfaceAutoMocMacroNamesEntries,
+          AddInterfaceEntries(this->GenTarget, "INTERFACE_AUTOMOC_MACRO_NAMES",
+                              context, &dagChecker,
+                              InterfaceAutoMocMacroNamesEntries,
                               IncludeRuntimeInterface::Yes);
                               IncludeRuntimeInterface::Yes);
         }
         }
       }
       }
     } else {
     } else {
+      cm::GenEx::Context context(this->LocalGen, this->ConfigDefault, "CXX");
       cmGeneratorExpressionDAGChecker dagChecker{
       cmGeneratorExpressionDAGChecker dagChecker{
-        this->GenTarget, "AUTOMOC_MACRO_NAMES", nullptr,
-        nullptr,         this->LocalGen,        this->ConfigDefault,
+        this->GenTarget, "AUTOMOC_MACRO_NAMES", nullptr, nullptr, context,
       };
       };
-      AddInterfaceEntries(this->GenTarget, this->ConfigDefault,
-                          "INTERFACE_AUTOMOC_MACRO_NAMES", "CXX", &dagChecker,
-                          InterfaceAutoMocMacroNamesEntries,
-                          IncludeRuntimeInterface::Yes);
+      AddInterfaceEntries(
+        this->GenTarget, "INTERFACE_AUTOMOC_MACRO_NAMES", context, &dagChecker,
+        InterfaceAutoMocMacroNamesEntries, IncludeRuntimeInterface::Yes);
     }
     }
 
 
     for (auto const& entry : InterfaceAutoMocMacroNamesEntries.Entries) {
     for (auto const& entry : InterfaceAutoMocMacroNamesEntries.Entries) {

+ 2 - 1
bootstrap

@@ -375,8 +375,9 @@ CMAKE_CXX_SOURCES="\
   cmFunctionCommand \
   cmFunctionCommand \
   cmFSPermissions \
   cmFSPermissions \
   cmGeneratedFileStream \
   cmGeneratedFileStream \
+  cmGenExContext \
+  cmGenExEvaluation \
   cmGeneratorExpression \
   cmGeneratorExpression \
-  cmGeneratorExpressionContext \
   cmGeneratorExpressionDAGChecker \
   cmGeneratorExpressionDAGChecker \
   cmGeneratorExpressionEvaluationFile \
   cmGeneratorExpressionEvaluationFile \
   cmGeneratorExpressionEvaluator \
   cmGeneratorExpressionEvaluator \

Some files were not shown because too many files changed in this diff