[libcxx-commits] [libcxx] [libc++] Add code coverage utilities (PR #233888)
via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Oct 20 09:02:33 PDT 2026
github-actions[bot] wrote:
<!--LLVM CODE FORMAT COMMENT: {clang-format}-->
:warning: C/C++ code formatter, clang-format found issues in your code. :warning:
<details>
<summary>
You can test this locally with the following command:
</summary>
``````````bash
git-clang-format --diff origin/main HEAD --extensions cpp -- libcxx/test/tools/merge-coverage.cpp --diff_from_common_commit
``````````
:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:
</details>
<details>
<summary>
View the diff from clang-format here.
</summary>
``````````diff
diff --git a/libcxx/test/tools/merge-coverage.cpp b/libcxx/test/tools/merge-coverage.cpp
index 3de539b15..1c4e70342 100644
--- a/libcxx/test/tools/merge-coverage.cpp
+++ b/libcxx/test/tools/merge-coverage.cpp
@@ -7,8 +7,7 @@
#include <nlohmann/json.hpp>
#include <string>
-struct SourceRange
-{
+struct SourceRange {
uint64_t file;
uint64_t expanded_file;
uint64_t region_kind;
@@ -20,65 +19,56 @@ struct SourceRange
friend auto operator<=>(const SourceRange&, const SourceRange&) = default;
};
-struct ExecutionCounts
-{
+struct ExecutionCounts {
uint64_t true_count;
uint64_t false_count;
};
-struct FunctionInfo
-{
+struct FunctionInfo {
std::vector<std::string> filenames;
std::flat_map<SourceRange, uint64_t> regions;
std::flat_map<SourceRange, ExecutionCounts> branches;
uint64_t count;
};
-struct [[nodiscard]] BalancedBraces
-{
- enum Kind
- {
+struct [[nodiscard]] BalancedBraces {
+ enum Kind {
parens,
square,
brace,
} kind;
- BalancedBraces(Kind k) : kind(k)
- {
- switch (kind)
- {
- case parens:
- std::cout << '(';
- break;
- case square:
- std::cout << '[';
- break;
- case brace:
- std::cout << '{';
- break;
+ BalancedBraces(Kind k) : kind(k) {
+ switch (kind) {
+ case parens:
+ std::cout << '(';
+ break;
+ case square:
+ std::cout << '[';
+ break;
+ case brace:
+ std::cout << '{';
+ break;
}
}
- BalancedBraces(const BalancedBraces&) = delete;
+ BalancedBraces(const BalancedBraces&) = delete;
BalancedBraces& operator=(const BalancedBraces&) = delete;
- ~BalancedBraces()
- {
- switch (kind)
- {
- case parens:
- std::cout << ')';
- break;
- case square:
- std::cout << ']';
- break;
- case brace:
- std::cout << '}';
- break;
+ ~BalancedBraces() {
+ switch (kind) {
+ case parens:
+ std::cout << ')';
+ break;
+ case square:
+ std::cout << ']';
+ break;
+ case brace:
+ std::cout << '}';
+ break;
}
}
};
-int main(int, char** argv)
-{
+int main(int, char** argv) {
std::ios::sync_with_stdio(false);
std::map<std::string, FunctionInfo> functions;
@@ -87,66 +77,68 @@ int main(int, char** argv)
std::ifstream files(argv[1]);
std::string fname;
- while (std::getline(files, fname))
- {
+ while (std::getline(files, fname)) {
std::ifstream f(fname);
if (f.peek() == EOF) // skip empty files
continue;
// TODO: Verify the the files have the expected layout
json report = json::parse(f)["data"][0]["functions"];
- for (auto& file : report)
- {
+ for (auto& file : report) {
std::string function_name(file["name"]);
if (function_name == "main")
continue;
FunctionInfo& func_info = functions[std::move(function_name)];
- auto& filenames = file["filenames"];
+ auto& filenames = file["filenames"];
if (std::ranges::none_of(filenames, [](json j) {
auto name = std::string(j);
- return name.contains("test-suite-install") || name.contains("libcxx/src")
- || name.contains("libcxxabi/src") || name.contains("libunwind/src");
+ return name.contains("test-suite-install") || name.contains("libcxx/src") ||
+ name.contains("libcxxabi/src") || name.contains("libunwind/src");
}))
continue;
- if (func_info.filenames.empty())
- {
- for (auto& filename : filenames) func_info.filenames.push_back(std::string(filename));
- }
- else
- {
- auto [lhs_res, rhs_res] = std::ranges::mismatch(filenames, func_info.filenames, {},
- [](json& j) { return std::string(j); });
- if (lhs_res != filenames.end() && rhs_res != func_info.filenames.end())
- {
- std::clog << "Rejected information for function '" << file["name"]
- << "' due to different file names\n";
- for (const auto& n : func_info.filenames) std::clog << n << '\n';
+ if (func_info.filenames.empty()) {
+ for (auto& filename : filenames)
+ func_info.filenames.push_back(std::string(filename));
+ } else {
+ auto [lhs_res, rhs_res] =
+ std::ranges::mismatch(filenames, func_info.filenames, {}, [](json& j) { return std::string(j); });
+ if (lhs_res != filenames.end() && rhs_res != func_info.filenames.end()) {
+ std::clog << "Rejected information for function '" << file["name"] << "' due to different file names\n";
+ for (const auto& n : func_info.filenames)
+ std::clog << n << '\n';
std::clog << "vs.\n";
- for (const auto& n : filenames) std::clog << std::string(n) << '\n';
+ for (const auto& n : filenames)
+ std::clog << std::string(n) << '\n';
continue;
}
- std::transform(lhs_res, filenames.end(), std::back_inserter(func_info.filenames),
- [](json j) { return std::string(j); });
+ std::transform(lhs_res, filenames.end(), std::back_inserter(func_info.filenames), [](json j) {
+ return std::string(j);
+ });
}
- for (auto& region : file["regions"])
- {
- if (uint64_t(region.at(5)) >= func_info.filenames.size()
- || uint64_t(region.at(6)) >= func_info.filenames.size())
- {
+ for (auto& region : file["regions"]) {
+ if (uint64_t(region.at(5)) >= func_info.filenames.size() ||
+ uint64_t(region.at(6)) >= func_info.filenames.size()) {
std::clog << "Incoherent indices\n";
continue;
}
- func_info.regions[SourceRange {uint64_t(region.at(5)), uint64_t(region.at(6)),
- uint64_t(region.at(7)), uint64_t(region.at(0)),
- uint64_t(region.at(1)), uint64_t(region.at(2)),
- uint64_t(region.at(3))}] += uint64_t(region.at(4));
+ func_info.regions[SourceRange{
+ uint64_t(region.at(5)),
+ uint64_t(region.at(6)),
+ uint64_t(region.at(7)),
+ uint64_t(region.at(0)),
+ uint64_t(region.at(1)),
+ uint64_t(region.at(2)),
+ uint64_t(region.at(3))}] += uint64_t(region.at(4));
}
- for (auto& branch : file["branches"])
- {
- auto& [true_count, false_count] = func_info.branches[SourceRange {
- uint64_t(branch.at(6)), uint64_t(branch.at(7)), uint64_t(branch.at(8)),
- uint64_t(branch.at(0)), uint64_t(branch.at(1)), uint64_t(branch.at(2)),
+ for (auto& branch : file["branches"]) {
+ auto& [true_count, false_count] = func_info.branches[SourceRange{
+ uint64_t(branch.at(6)),
+ uint64_t(branch.at(7)),
+ uint64_t(branch.at(8)),
+ uint64_t(branch.at(0)),
+ uint64_t(branch.at(1)),
+ uint64_t(branch.at(2)),
uint64_t(branch.at(3))}];
true_count += uint64_t(branch.at(4));
false_count += uint64_t(branch.at(5));
@@ -158,8 +150,7 @@ int main(int, char** argv)
std::cout << R"json({"data":[{"functions":[)json";
bool is_first = true;
- for (const auto& [name, info] : functions)
- {
+ for (const auto& [name, info] : functions) {
if (!is_first)
std::cout << ',';
is_first = false;
@@ -174,8 +165,7 @@ int main(int, char** argv)
BalancedBraces _(BalancedBraces::square);
bool is_first_filename = true;
- for (const auto& filename : info.filenames)
- {
+ for (const auto& filename : info.filenames) {
if (!is_first_filename)
std::cout << ',';
is_first_filename = false;
@@ -194,10 +184,9 @@ int main(int, char** argv)
std::cout << ',';
is_first_branch = false;
BalancedBraces _(BalancedBraces::square);
- std::cout << branch.line_start << ',' << branch.column_start << ',' << branch.line_end
- << ',' << branch.column_end << ',' << branch_val.true_count << ','
- << branch_val.false_count << ',' << branch.file << ',' << branch.expanded_file
- << ',' << branch.region_kind;
+ std::cout << branch.line_start << ',' << branch.column_start << ',' << branch.line_end << ','
+ << branch.column_end << ',' << branch_val.true_count << ',' << branch_val.false_count << ','
+ << branch.file << ',' << branch.expanded_file << ',' << branch.region_kind;
}
}
std::cout << ',';
@@ -210,15 +199,14 @@ int main(int, char** argv)
BalancedBraces _(BalancedBraces::square);
bool is_first_region = true;
- for (const auto& [region, region_val] : info.regions)
- {
+ for (const auto& [region, region_val] : info.regions) {
if (!is_first_region)
std::cout << ',';
is_first_region = false;
BalancedBraces _(BalancedBraces::square);
- std::cout << region.line_start << ',' << region.column_start << ',' << region.line_end
- << ',' << region.column_end << ',' << region_val << ',' << region.file << ','
- << region.expanded_file << ',' << region.region_kind;
+ std::cout << region.line_start << ',' << region.column_start << ',' << region.line_end << ','
+ << region.column_end << ',' << region_val << ',' << region.file << ',' << region.expanded_file << ','
+ << region.region_kind;
}
}
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/233888
More information about the libcxx-commits
mailing list