• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tudasc / TypeART / 13955121336

19 Mar 2025 07:30PM UTC coverage: 88.842%. First build
13955121336

push

github

web-flow
Merge PR #167 from tudasc/devel

1174 of 1361 new or added lines in 49 files covered. (86.26%)

4212 of 4741 relevant lines covered (88.84%)

261950.04 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.76
/lib/passes/configuration/EnvironmentConfiguration.cpp
1
// TypeART library
2
//
3
// Copyright (c) 2017-2025 TypeART Authors
4
// Distributed under the BSD 3-Clause license.
5
// (See accompanying file LICENSE.txt or copy at
6
// https://opensource.org/licenses/BSD-3-Clause)
7
//
8
// Project home: https://github.com/tudasc/TypeART
9
//
10
// SPDX-License-Identifier: BSD-3-Clause
11
//
12

13
#include "EnvironmentConfiguration.h"
14

15
#include "Configuration.h"
16
#include "OptionsUtil.h"
17
#include "PassConfiguration.h"
18
#include "configuration/TypeARTOptions.h"
19
#include "support/ConfigurationBase.h"
20
#include "support/Logger.h"
21
#include "support/Util.h"
22

23
#include "llvm/ADT/StringSwitch.h"
24

25
#include <charconv>
26
#include <string>
27
#include <string_view>
28
#include <type_traits>
29

30
using namespace llvm;
31

32
namespace typeart::config::env {
33
std::optional<std::string> get_env_flag(std::string_view flag) {
106,024✔
34
  const char* env_value = std::getenv(flag.data());
106,024✔
35
  const bool exists     = env_value != nullptr;
106,024✔
36
  if (exists) {
106,024✔
37
    LOG_DEBUG("Using env var " << flag << "=" << env_value)
38
    return std::string{env_value};
5,768✔
39
  }
40
  LOG_DEBUG("Not using env var " << flag << "=<unset>")
41
  return {};
100,256✔
42
}
106,024✔
43

44
}  // namespace typeart::config::env
45

46
namespace typeart::config::env {
47

48
struct EnvironmentStdArgsValues final {
49
#define TYPEART_CONFIG_OPTION(name, path, type, def_value, description, upper_path) \
50
  static constexpr char name[] = #def_value;
51
#include "support/ConfigurationBaseOptions.h"
52
#undef TYPEART_CONFIG_OPTION
53
};
54

55
struct EnvironmentStdOptionsArgsValues final {
56
  static constexpr char option[]       = "TYPEART_OPTIONS";
57
  static constexpr char option_stack[] = "TYPEART_OPTIONS_STACK";
58
  static constexpr char option_heap[]  = "TYPEART_OPTIONS_HEAP";
59
};
60

61
namespace detail {
62
template <typename ClType>
63
OptionValue make_opt(std::string_view cl_value) {
49,888✔
64
  // LOG_DEBUG("Parsing value " << cl_value)
65
  auto value = util::make_opt<ClType>(cl_value.data());
49,888✔
66
  if constexpr (std::is_enum_v<ClType>) {
67
    return OptionValue{static_cast<int>(value)};
6,236✔
68
  } else {
69
    return OptionValue{value};
43,652✔
70
  }
71
}
12,472✔
72

73
template <typename ClType>
74
std::pair<StringRef, typename OptionsMap::mapped_type> make_entry(std::string_view key, std::string_view cl_opt,
49,888✔
75
                                                                  const std::string& default_value) {
76
  const auto env_value = get_env_flag(cl_opt);
49,888✔
77
  return {key, detail::make_opt<ClType>(env_value.value_or(default_value))};
49,888✔
78
}
49,888✔
79

80
template <typename ClOpt>
81
std::pair<StringRef, typename OptOccurrenceMap::mapped_type> make_occurr_entry(std::string_view key, ClOpt&& cl_opt) {
49,888✔
82
  const bool occurred = (get_env_flag(cl_opt).has_value());
49,888✔
83
  return {key, occurred};
49,888✔
84
}
85

86
void merge_mapping_with_passconfig(OptionsMap& mapping_, OptOccurrenceMap& occurence_mapping_,
6,248✔
87
                                   const pass::PassConfig& result) {
88
  const auto typeart_options = helper::options_to_map(result.first.get());
6,248✔
89
  for (const auto& entry : result.second) {
6,416✔
90
    const auto key = entry.getKey();
168✔
91
    if (entry.second && !occurence_mapping_[key]) {  // single ENV priority over TYPEART_OPTIONS
168✔
92
      LOG_DEBUG("Replacing " << key)
93
      mapping_[key]           = typeart_options.lookup(key);
156✔
94
      occurence_mapping_[key] = true;
156✔
95
    }
156✔
96
  }
97
}
6,248✔
98
}  // namespace detail
99

100
EnvironmentFlagsOptions::EnvironmentFlagsOptions() {
3,118✔
101
  using namespace config;
102
  using namespace typeart::config::env::detail;
103

104
  LOG_DEBUG("Construct environment flag options")
105

106
  mapping_ = {
53,006✔
107
      make_entry<std::string>(ConfigStdArgs::types, config::EnvironmentStdArgs::types, ConfigStdArgValues::types),
3,118✔
108
      make_entry<ConfigStdArgTypes::stats_ty>(ConfigStdArgs::stats, EnvironmentStdArgs::stats,
3,118✔
109
                                              EnvironmentStdArgsValues::stats),
3,118✔
110
      make_entry<ConfigStdArgTypes::heap_ty>(ConfigStdArgs::heap, EnvironmentStdArgs::heap,
3,118✔
111
                                             EnvironmentStdArgsValues::heap),
3,118✔
112
      make_entry<ConfigStdArgTypes::global_ty>(ConfigStdArgs::global, EnvironmentStdArgs::global,
3,118✔
113
                                               EnvironmentStdArgsValues::global),
3,118✔
114
      make_entry<ConfigStdArgTypes::stack_ty>(ConfigStdArgs::stack, EnvironmentStdArgs::stack,
3,118✔
115
                                              EnvironmentStdArgsValues::stack),
3,118✔
116
      make_entry<ConfigStdArgTypes::stack_lifetime_ty>(
3,118✔
117
          ConfigStdArgs::stack_lifetime, EnvironmentStdArgs::stack_lifetime, EnvironmentStdArgsValues::stack_lifetime),
3,118✔
118
      make_entry<typeart::TypegenImplementation>(ConfigStdArgs::typegen, EnvironmentStdArgs::typegen,
3,118✔
119
                                                 ConfigStdArgValues::typegen),
3,118✔
120
      make_entry<ConfigStdArgTypes::filter_ty>(ConfigStdArgs::filter, EnvironmentStdArgs::filter,
3,118✔
121
                                               EnvironmentStdArgsValues::filter),
3,118✔
122
      make_entry<typeart::analysis::FilterImplementation>(ConfigStdArgs::filter_impl, EnvironmentStdArgs::filter_impl,
3,118✔
123
                                                          ConfigStdArgValues::filter_impl),
3,118✔
124

125
      make_entry<ConfigStdArgTypes::filter_glob_ty>(ConfigStdArgs::filter_glob, EnvironmentStdArgs::filter_glob,
3,118✔
126
                                                    ConfigStdArgValues::filter_glob),
3,118✔
127
      make_entry<ConfigStdArgTypes::filter_glob_deep_ty>(
3,118✔
128
          ConfigStdArgs::filter_glob_deep, EnvironmentStdArgs::filter_glob_deep, ConfigStdArgValues::filter_glob_deep),
3,118✔
129
      make_entry<ConfigStdArgTypes::filter_cg_file_ty>(
3,118✔
130
          ConfigStdArgs::filter_cg_file, EnvironmentStdArgs::filter_cg_file, ConfigStdArgValues::filter_cg_file),
3,118✔
131
      make_entry<ConfigStdArgTypes::analysis_filter_global_ty>(ConfigStdArgs::analysis_filter_global,
3,118✔
132
                                                               EnvironmentStdArgs::analysis_filter_global,
3,118✔
133
                                                               EnvironmentStdArgsValues::analysis_filter_global),
3,118✔
134
      make_entry<ConfigStdArgTypes::analysis_filter_heap_alloc_ty>(
3,118✔
135
          ConfigStdArgs::analysis_filter_heap_alloc, EnvironmentStdArgs::analysis_filter_heap_alloc,
3,118✔
136
          EnvironmentStdArgsValues::analysis_filter_heap_alloc),
3,118✔
137
      make_entry<ConfigStdArgTypes::analysis_filter_pointer_alloc_ty>(
3,118✔
138
          ConfigStdArgs::analysis_filter_pointer_alloc, EnvironmentStdArgs::analysis_filter_pointer_alloc,
3,118✔
139
          EnvironmentStdArgsValues::analysis_filter_pointer_alloc),
3,118✔
140
      make_entry<ConfigStdArgTypes::analysis_filter_alloca_non_array_ty>(
3,118✔
141
          ConfigStdArgs::analysis_filter_alloca_non_array, EnvironmentStdArgs::analysis_filter_alloca_non_array,
3,118✔
142
          EnvironmentStdArgsValues::analysis_filter_alloca_non_array),
3,118✔
143
  };
144

145
  occurence_mapping_ = {
3,118✔
146
      make_occurr_entry(ConfigStdArgs::types, config::EnvironmentStdArgs::types),
3,118✔
147
      make_occurr_entry(ConfigStdArgs::stats, EnvironmentStdArgs::stats),
3,118✔
148
      make_occurr_entry(ConfigStdArgs::heap, EnvironmentStdArgs::heap),
3,118✔
149
      make_occurr_entry(ConfigStdArgs::global, EnvironmentStdArgs::global),
3,118✔
150
      make_occurr_entry(ConfigStdArgs::stack, EnvironmentStdArgs::stack),
3,118✔
151
      make_occurr_entry(ConfigStdArgs::stack_lifetime, EnvironmentStdArgs::stack_lifetime),
3,118✔
152
      make_occurr_entry(ConfigStdArgs::typegen, EnvironmentStdArgs::typegen),
3,118✔
153
      make_occurr_entry(ConfigStdArgs::filter, EnvironmentStdArgs::filter),
3,118✔
154
      make_occurr_entry(ConfigStdArgs::filter_impl, EnvironmentStdArgs::filter_impl),
3,118✔
155
      make_occurr_entry(ConfigStdArgs::filter_glob, EnvironmentStdArgs::filter_glob),
3,118✔
156
      make_occurr_entry(ConfigStdArgs::filter_glob_deep, EnvironmentStdArgs::filter_glob_deep),
3,118✔
157
      make_occurr_entry(ConfigStdArgs::filter_cg_file, EnvironmentStdArgs::filter_cg_file),
3,118✔
158
      make_occurr_entry(ConfigStdArgs::analysis_filter_global, EnvironmentStdArgs::analysis_filter_global),
3,118✔
159
      make_occurr_entry(ConfigStdArgs::analysis_filter_heap_alloc, EnvironmentStdArgs::analysis_filter_heap_alloc),
3,118✔
160
      make_occurr_entry(ConfigStdArgs::analysis_filter_pointer_alloc,
3,118✔
161
                        EnvironmentStdArgs::analysis_filter_pointer_alloc),
162
      make_occurr_entry(ConfigStdArgs::analysis_filter_alloca_non_array,
3,118✔
163
                        EnvironmentStdArgs::analysis_filter_alloca_non_array),
164
  };
165

166
  if (!occurence_mapping_.lookup(ConfigStdArgs::global) && occurence_mapping_.lookup(ConfigStdArgs::stack)) {
3,118✔
167
    const auto stack_value                    = mapping_.lookup(ConfigStdArgs::stack);
561✔
168
    mapping_[ConfigStdArgs::global]           = OptionValue{static_cast<bool>(stack_value)};
561✔
169
    occurence_mapping_[ConfigStdArgs::global] = true;
561✔
170
  }
561✔
171

172
  auto result =
173
      pass::parse_typeart_config_with_occurrence(get_env_flag(EnvironmentStdOptionsArgsValues::option).value_or(""));
3,118✔
174
  if (!result.first) {
3,118✔
NEW
175
    LOG_INFO("No parseable " << EnvironmentStdOptionsArgsValues::option << ": " << result.first.takeError())
×
NEW
176
  } else {
×
177
    LOG_DEBUG("Parsed " << EnvironmentStdOptionsArgsValues::option << "\n" << *result.first)
178
    merge_mapping_with_passconfig(mapping_, occurence_mapping_, result);
3,118✔
179
  }
180
}
3,118✔
181

182
void EnvironmentFlagsOptions::parsePhaseEnvFlags(const Phase& phase) {
3,118✔
183
  if (phase.heap) {
3,118✔
184
    auto result = pass::parse_typeart_config_with_occurrence(
2,163✔
185
        get_env_flag(EnvironmentStdOptionsArgsValues::option_heap).value_or(""));
2,163✔
186
    if (result.first) {
2,163✔
187
      LOG_DEBUG("Parsing " << EnvironmentStdOptionsArgsValues::option_heap)
188
      detail::merge_mapping_with_passconfig(mapping_, occurence_mapping_, result);
2,163✔
189
    }
2,163✔
190
  }
2,163✔
191

192
  if (phase.stack) {
3,118✔
193
    auto result = pass::parse_typeart_config_with_occurrence(
967✔
194
        get_env_flag(EnvironmentStdOptionsArgsValues::option_stack).value_or(""));
967✔
195
    if (result.first) {
967✔
196
      LOG_DEBUG("Parsing " << EnvironmentStdOptionsArgsValues::option_stack)
197
      detail::merge_mapping_with_passconfig(mapping_, occurence_mapping_, result);
967✔
198
    }
967✔
199
  }
967✔
200
}
3,118✔
201

202
std::optional<typeart::config::OptionValue> EnvironmentFlagsOptions::getValue(std::string_view opt_path) const {
245,172✔
203
  auto key = llvm::StringRef(opt_path.data());
245,172✔
204
  if (occurence_mapping_.lookup(key)) {  // only have value if it occurred
245,172✔
205
    return mapping_.lookup(key);
13,763✔
206
  }
207
  return {};
231,409✔
208
}
245,172✔
209

NEW
210
[[maybe_unused]] bool EnvironmentFlagsOptions::valueSpecified(std::string_view opt_path) const {
×
NEW
211
  auto key = llvm::StringRef(opt_path.data());
×
NEW
212
  return occurence_mapping_.lookup(key);
×
213
}
214

215
}  // namespace typeart::config::env
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc