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

tudasc / TypeART / 13144206847

04 Feb 2025 08:25PM UTC coverage: 88.846%. First build
13144206847

Pull #157

github

web-flow
Merge 99597fb9d into 6c2a7db4c
Pull Request #157: Environment variable handling

39 of 40 new or added lines in 4 files covered. (97.5%)

4102 of 4617 relevant lines covered (88.85%)

176701.0 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) {
79,501✔
34
  const char* env_value = std::getenv(flag.data());
79,501✔
35
  const bool exists     = env_value != nullptr;
79,501✔
36
  if (exists) {
79,501✔
37
    LOG_DEBUG("Using env var " << flag << "=" << env_value)
38
    return std::string{env_value};
4,419✔
39
  }
40
  LOG_DEBUG("Not using env var " << flag << "=<unset>")
41
  return {};
75,082✔
42
}
79,501✔
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) {
37,408✔
64
  // LOG_DEBUG("Parsing value " << cl_value)
65
  auto value = util::make_opt<ClType>(cl_value.data());
37,408✔
66
  if constexpr (std::is_enum_v<ClType>) {
67
    return OptionValue{static_cast<int>(value)};
4,676✔
68
  } else {
69
    return OptionValue{value};
32,732✔
70
  }
71
}
9,352✔
72

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

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

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

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

104
  LOG_DEBUG("Construct environment flag options")
105

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

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

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

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

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

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

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

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

210
[[maybe_unused]] bool EnvironmentFlagsOptions::valueSpecified(std::string_view opt_path) const {
×
211
  auto key = llvm::StringRef(opt_path.data());
×
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