Coverage Report

Created: 2026-10-28 06:38

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmEvaluatedTargetProperty.cxx
Line
Count
Source
1
/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2
   file LICENSE.rst or https://cmake.org/licensing for details.  */
3
#include "cmEvaluatedTargetProperty.h"
4
5
#include <unordered_map>
6
#include <utility>
7
8
#include "cmGenExContext.h"
9
#include "cmGenExEvaluation.h"
10
#include "cmGeneratorFileSets.h"
11
#include "cmGeneratorTarget.h"
12
#include "cmLinkItem.h"
13
#include "cmList.h"
14
#include "cmTargetPropertyEntry.h"
15
16
struct cmGeneratorExpressionDAGChecker;
17
18
namespace cm {
19
EvaluatedTargetPropertyEntry::EvaluatedTargetPropertyEntry(
20
  cmLinkItem const& item, cmListFileBacktrace bt)
21
4.51k
  : LinkItem(item)
22
4.51k
  , Backtrace(std::move(bt))
23
4.51k
{
24
4.51k
}
25
26
EvaluatedTargetPropertyEntry EvaluateTargetPropertyEntry(
27
  cmGeneratorTarget const* thisTarget, cm::GenEx::Context const& context,
28
  cmGeneratorExpressionDAGChecker* dagChecker, cm::TargetPropertyEntry& entry)
29
964
{
30
964
  EvaluatedTargetPropertyEntry ee(entry.LinkItem, entry.GetBacktrace());
31
964
  cmExpandList(entry.Evaluate(context, thisTarget, dagChecker), ee.Values);
32
964
  if (entry.GetHadContextSensitiveCondition()) {
33
0
    ee.ContextDependent = true;
34
0
  }
35
964
  return ee;
36
964
}
37
38
EvaluatedTargetPropertyEntries EvaluateTargetPropertyEntries(
39
  cmGeneratorTarget const* thisTarget, cm::GenEx::Context const& context,
40
  cmGeneratorExpressionDAGChecker* dagChecker,
41
  std::vector<std::unique_ptr<cm::TargetPropertyEntry>> const& in)
42
1.94k
{
43
1.94k
  EvaluatedTargetPropertyEntries out;
44
1.94k
  out.Entries.reserve(in.size());
45
1.94k
  for (auto const& entry : in) {
46
964
    out.Entries.emplace_back(
47
964
      EvaluateTargetPropertyEntry(thisTarget, context, dagChecker, *entry));
48
964
  }
49
1.94k
  return out;
50
1.94k
}
51
52
namespace {
53
void addInterfaceEntry(cmGeneratorTarget const* headTarget,
54
                       std::string const& prop,
55
                       cm::GenEx::Context const& context,
56
                       cmGeneratorExpressionDAGChecker* dagChecker,
57
                       EvaluatedTargetPropertyEntries& entries,
58
                       cmGeneratorTarget::UseTo usage,
59
                       std::vector<cmLinkItem> const& libraries)
60
964
{
61
1.55k
  for (cmLinkItem const& lib : libraries) {
62
1.55k
    if (lib.Target) {
63
1.55k
      EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
64
      // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in our
65
      // caller's property and hand-evaluate it as if it were compiled.
66
      // Create a context as cmCompiledGeneratorExpression::Evaluate does.
67
1.55k
      cm::GenEx::Evaluation eval(context, false, headTarget, headTarget, true,
68
1.55k
                                 lib.Backtrace);
69
1.55k
      cmExpandList(
70
1.55k
        lib.Target->EvaluateInterfaceProperty(prop, &eval, dagChecker, usage),
71
1.55k
        ee.Values);
72
1.55k
      ee.ContextDependent = eval.HadContextSensitiveCondition;
73
1.55k
      entries.Entries.emplace_back(std::move(ee));
74
1.55k
    }
75
1.55k
  }
76
964
}
77
78
void addInterfaceFileSetsEntry(cmGeneratorTarget const* headTarget,
79
                               cm::string_view type, std::string const& prop,
80
                               cm::GenEx::Context const& context,
81
                               cmGeneratorExpressionDAGChecker* dagChecker,
82
                               EvaluatedTargetPropertyEntries& entries,
83
                               std::vector<cmLinkItem> const& libraries)
84
964
{
85
1.55k
  for (cmLinkItem const& lib : libraries) {
86
1.55k
    if (lib.Target) {
87
1.55k
      EvaluatedTargetPropertyEntry ee(lib, lib.Backtrace);
88
      // Pretend $<TARGET_PROPERTY:lib.Target,prop> appeared in our
89
      // caller's property and hand-evaluate it as if it were compiled.
90
      // Create a context as cmCompiledGeneratorExpression::Evaluate does.
91
1.55k
      cm::GenEx::Evaluation eval(context, false, headTarget, headTarget, true,
92
1.55k
                                 lib.Backtrace);
93
1.55k
      cmExpandList(
94
1.55k
        lib.Target->GetGeneratorFileSets()->EvaluateInterfaceProperty(
95
1.55k
          type, prop, &eval, dagChecker),
96
1.55k
        ee.Values);
97
1.55k
      ee.ContextDependent = eval.HadContextSensitiveCondition;
98
1.55k
      entries.Entries.emplace_back(std::move(ee));
99
1.55k
    }
100
1.55k
  }
101
964
}
102
}
103
104
void AddInterfaceEntries(cmGeneratorTarget const* headTarget,
105
                         std::string const& prop,
106
                         cm::GenEx::Context const& context,
107
                         cmGeneratorExpressionDAGChecker* dagChecker,
108
                         EvaluatedTargetPropertyEntries& entries,
109
                         IncludeRuntimeInterface searchRuntime,
110
                         cmGeneratorTarget::UseTo usage)
111
974
{
112
974
  if (searchRuntime == IncludeRuntimeInterface::Yes) {
113
0
    if (cmLinkImplementation const* impl =
114
0
          headTarget->GetLinkImplementation(context.Config, usage)) {
115
0
      entries.HadContextSensitiveCondition =
116
0
        impl->HadContextSensitiveCondition;
117
118
0
      auto runtimeLibIt =
119
0
        impl->LanguageRuntimeLibraries.find(context.Language);
120
0
      if (runtimeLibIt != impl->LanguageRuntimeLibraries.end()) {
121
0
        addInterfaceEntry(headTarget, prop, context, dagChecker, entries,
122
0
                          usage, runtimeLibIt->second);
123
0
      }
124
0
      addInterfaceEntry(headTarget, prop, context, dagChecker, entries, usage,
125
0
                        impl->Libraries);
126
0
    }
127
974
  } else {
128
974
    if (cmLinkImplementationLibraries const* impl =
129
974
          headTarget->GetLinkImplementationLibraries(context.Config, usage)) {
130
964
      entries.HadContextSensitiveCondition =
131
964
        impl->HadContextSensitiveCondition;
132
964
      addInterfaceEntry(headTarget, prop, context, dagChecker, entries, usage,
133
964
                        impl->Libraries);
134
964
    }
135
974
  }
136
974
}
137
138
void AddInterfaceFileSetsEntries(cmGeneratorTarget const* headTarget,
139
                                 cm::string_view type, std::string const& prop,
140
                                 cm::GenEx::Context const& context,
141
                                 cmGeneratorExpressionDAGChecker* dagChecker,
142
                                 EvaluatedTargetPropertyEntries& entries)
143
974
{
144
974
  if (cmLinkImplementationLibraries const* impl =
145
974
        headTarget->GetLinkImplementationLibraries(
146
974
          context.Config, cmGeneratorTarget::UseTo::Compile)) {
147
964
    entries.HadContextSensitiveCondition = impl->HadContextSensitiveCondition;
148
964
    addInterfaceFileSetsEntry(headTarget, type, prop, context, dagChecker,
149
964
                              entries, impl->Libraries);
150
964
  }
151
974
}
152
}