Coverage Report

Created: 2026-07-14 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/CMake/Source/cmCxxModuleUsageEffects.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 "cmCxxModuleUsageEffects.h"
4
5
#include <algorithm>
6
#include <set>
7
#include <vector>
8
9
#include <cm/string_view>
10
11
#include "cmCryptoHash.h"
12
#include "cmGeneratorTarget.h"
13
#include "cmListFileCache.h"
14
#include "cmMakefile.h"
15
#include "cmRange.h"
16
#include "cmStringAlgorithms.h"
17
#include "cmTarget.h"
18
#include "cmValue.h"
19
20
namespace {
21
22
bool IsMSVCWarning(cm::string_view flag)
23
0
{
24
0
  if (flag.size() < 2) {
25
0
    return false;
26
0
  }
27
28
0
  if (flag.front() != '/' && flag.front() != '-') {
29
0
    return false;
30
0
  }
31
32
0
  flag.remove_prefix(1);
33
34
0
  if (flag.front() == 'w' || flag.front() == 'W') {
35
0
    return true;
36
0
  }
37
38
0
  if (flag.substr(0, 9) == "external:") {
39
0
    return true;
40
0
  }
41
42
0
  return false;
43
0
}
44
45
bool IsGNUWarning(cm::string_view flag)
46
0
{
47
0
  if (flag.size() < 2) {
48
0
    return false;
49
0
  }
50
51
0
  if (flag.front() != '-') {
52
0
    return false;
53
0
  }
54
55
0
  flag.remove_prefix(1);
56
57
0
  if (flag.front() == 'w' || flag.front() == 'W') {
58
0
    return true;
59
0
  }
60
61
0
  if (flag.front() == '-') {
62
0
    flag.remove_prefix(1);
63
0
  }
64
65
0
  static std::set<cm::string_view> const long_names{
66
0
    "pedantic", "pedantic-errors", "all-warnings", "extra-warnings",
67
0
    "no-warnings"
68
0
  };
69
70
0
  return long_names.find(flag) != long_names.end();
71
0
}
72
73
bool UnknownFilter(cm::string_view)
74
0
{
75
0
  return false;
76
0
}
77
78
using FlagFilter = bool (*)(cm::string_view flag);
79
80
FlagFilter GetFlagFilter(cmGeneratorTarget const* gt)
81
0
{
82
0
  static FlagFilter filter = nullptr;
83
0
  if (filter) {
84
0
    return filter;
85
0
  }
86
87
0
  cmValue frontendVariant =
88
0
    gt->Makefile->GetDefinition("CMAKE_CXX_COMPILER_FRONTEND_VARIANT");
89
90
0
  if (frontendVariant == "GNU") {
91
0
    filter = IsGNUWarning;
92
0
  } else if (frontendVariant == "MSVC") {
93
0
    filter = IsMSVCWarning;
94
0
  } else {
95
0
    filter = UnknownFilter;
96
0
  }
97
98
0
  return filter;
99
0
}
100
101
void AppendUsage(std::string& usageHashInput, std::string const& entry)
102
0
{
103
0
  usageHashInput += entry;
104
0
  usageHashInput.push_back('\0');
105
0
}
106
107
template <typename Range>
108
void AppendUsageEntries(std::string& usageHashInput, Range const& entries)
109
0
{
110
0
  std::vector<std::string> entryValues;
111
0
  entryValues.reserve(entries.size());
112
0
  for (auto const& entry : entries) {
113
0
    entryValues.push_back(entry.Value);
114
0
  }
115
0
  std::sort(entryValues.begin(), entryValues.end());
116
117
0
  for (auto const& entryValue : entryValues) {
118
0
    usageHashInput += entryValue;
119
0
    usageHashInput.push_back('\n');
120
0
  }
121
122
0
  usageHashInput.push_back('\0');
123
0
}
Unexecuted instantiation: cmCxxModuleUsageEffects.cxx:void (anonymous namespace)::AppendUsageEntries<cmRange<std::__1::__wrap_iter<BT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const*> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, cmRange<std::__1::__wrap_iter<BT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const*> > const&)
Unexecuted instantiation: cmCxxModuleUsageEffects.cxx:void (anonymous namespace)::AppendUsageEntries<cmRange<RangeIterators::FilterIterator<std::__1::__wrap_iter<BT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const*>, cmCxxModuleUsageEffects::cmCxxModuleUsageEffects(cmGeneratorTarget const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_0> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, cmRange<RangeIterators::FilterIterator<std::__1::__wrap_iter<BT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const*>, cmCxxModuleUsageEffects::cmCxxModuleUsageEffects(cmGeneratorTarget const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_0> > const&)
Unexecuted instantiation: cmCxxModuleUsageEffects.cxx:void (anonymous namespace)::AppendUsageEntries<cmRange<RangeIterators::FilterIterator<std::__1::__wrap_iter<BT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const*>, cmCxxModuleUsageEffects::cmCxxModuleUsageEffects(cmGeneratorTarget const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_1> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >&, cmRange<RangeIterators::FilterIterator<std::__1::__wrap_iter<BT<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const*>, cmCxxModuleUsageEffects::cmCxxModuleUsageEffects(cmGeneratorTarget const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)::$_1> > const&)
124
}
125
126
cmCxxModuleUsageEffects::cmCxxModuleUsageEffects(cmGeneratorTarget const* gt,
127
                                                 std::string const& config)
128
0
{
129
0
  auto const* tgt = gt->Target;
130
0
  auto const filter = GetFlagFilter(gt);
131
132
0
  std::string usageHashInput;
133
0
  if (tgt->IsImported()) {
134
0
    AppendUsageEntries(usageHashInput,
135
0
                       tgt->GetImportedCxxModulesCompileFeaturesEntries());
136
0
    AppendUsageEntries(
137
0
      usageHashInput,
138
0
      tgt->GetImportedCxxModulesCompileOptionsEntries().filter(
139
0
        [&](const BT<std::string>& flag) { return !filter(flag.Value); }));
140
0
  } else {
141
0
    AppendUsageEntries(usageHashInput,
142
0
                       cmMakeRange(gt->GetCompileOptions(config, "CXX"))
143
0
                         .filter([&](const BT<std::string>& flag) {
144
0
                           return !filter(flag.Value);
145
0
                         }));
146
147
0
    cmValue langStd = gt->GetLanguageStandard("CXX", config);
148
0
    if (!langStd) {
149
0
      langStd = gt->Makefile->GetDefinition("CMAKE_CXX_STANDARD_DEFAULT");
150
0
    }
151
0
    AppendUsage(usageHashInput,
152
0
                cmStrCat("CXX_STANDARD:", langStd ? *langStd : "20"));
153
0
    AppendUsage(
154
0
      usageHashInput,
155
0
      cmStrCat("CXX_EXTENSIONS:", *gt->GetLanguageExtensions("CXX")));
156
0
    AppendUsage(
157
0
      usageHashInput,
158
0
      cmStrCat("CXX_STANDARD_REQUIRED:",
159
0
               gt->GetLanguageStandardRequired("CXX") ? "TRUE" : "FALSE"));
160
0
  }
161
162
0
  cmCryptoHash hasher(cmCryptoHash::AlgoSHA3_512);
163
0
  this->Hash = hasher.HashString(usageHashInput);
164
0
}
165
166
std::string const& cmCxxModuleUsageEffects::GetHash() const
167
0
{
168
0
  return this->Hash;
169
0
}