[llvm] Add executed MC/DC TestVectors to `llvm-cov export` (PR #105511)

Arpad Borsos via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 21 05:58:51 PDT 2024


https://github.com/Swatinem updated https://github.com/llvm/llvm-project/pull/105511

>From 691080277137f7aadc4b443526873f2b98277ad4 Mon Sep 17 00:00:00 2001
From: Arpad Borsos <arpad.borsos at sentry.io>
Date: Wed, 21 Aug 2024 14:29:47 +0200
Subject: [PATCH] Add executed MC/DC TestVectors to `llvm-cov export`

---
 llvm/tools/llvm-cov/CoverageExporterJson.cpp | 58 ++++++++++++++------
 1 file changed, 41 insertions(+), 17 deletions(-)

diff --git a/llvm/tools/llvm-cov/CoverageExporterJson.cpp b/llvm/tools/llvm-cov/CoverageExporterJson.cpp
index 9a8c7c94f06124..51f7c326b74650 100644
--- a/llvm/tools/llvm-cov/CoverageExporterJson.cpp
+++ b/llvm/tools/llvm-cov/CoverageExporterJson.cpp
@@ -62,7 +62,7 @@
 #include <utility>
 
 /// The semantic version combined as a string.
-#define LLVM_COVERAGE_EXPORT_JSON_STR "2.0.1"
+#define LLVM_COVERAGE_EXPORT_JSON_STR "2.1.0"
 
 /// Unique type identifier for JSON coverage export.
 #define LLVM_COVERAGE_EXPORT_JSON_TYPE_STR "llvm.coverage.json.export"
@@ -108,11 +108,40 @@ json::Array gatherConditions(const coverage::MCDCRecord &Record) {
   return Conditions;
 }
 
+json::Value renderCondState(const coverage::MCDCRecord::CondState CondState) {
+  switch (CondState) {
+  case coverage::MCDCRecord::MCDC_DontCare:
+    return json::Value(nullptr);
+  case coverage::MCDCRecord::MCDC_True:
+    return json::Value(true);
+  case coverage::MCDCRecord::MCDC_False:
+    return json::Value(false);
+  }
+}
+
+json::Array gatherTestVectors(coverage::MCDCRecord &Record) {
+  json::Array TestVectors;
+  unsigned NumConditions = Record.getNumConditions();
+  for (unsigned tv = 0; tv < Record.getNumTestVectors(); tv++) {
+
+    json::Array TVConditions;
+    for (unsigned c = 0; c < NumConditions; c++)
+      TVConditions.push_back(renderCondState(Record.getTVCondition(tv, c)));
+
+    TestVectors.push_back(
+        json::Object({{"executed", json::Value(true)},
+                      {"result", renderCondState(Record.getTVResult(tv))},
+                      {"conditions", std::move(TVConditions)}}));
+  }
+  return TestVectors;
+}
+
 json::Array renderMCDCRecord(const coverage::MCDCRecord &Record) {
   const llvm::coverage::CounterMappingRegion &CMR = Record.getDecisionRegion();
-  return json::Array({CMR.LineStart, CMR.ColumnStart, CMR.LineEnd,
-                      CMR.ColumnEnd, CMR.ExpandedFileID, int64_t(CMR.Kind),
-                      gatherConditions(Record)});
+  return json::Array(
+      {CMR.LineStart, CMR.ColumnStart, CMR.LineEnd, CMR.ColumnEnd,
+       CMR.ExpandedFileID, int64_t(CMR.Kind), gatherConditions(Record),
+       gatherTestVectors(const_cast<coverage::MCDCRecord &>(Record))});
 }
 
 json::Array renderRegions(ArrayRef<coverage::CountedRegion> Regions) {
@@ -214,32 +243,28 @@ json::Object renderSummary(const FileCoverageSummary &Summary) {
 }
 
 json::Array renderFileExpansions(const coverage::CoverageMapping &Coverage,
-                                 const coverage::CoverageData &FileCoverage,
-                                 const FileCoverageSummary &FileReport) {
+                                 const coverage::CoverageData &FileCoverage) {
   json::Array ExpansionArray;
   for (const auto &Expansion : FileCoverage.getExpansions())
     ExpansionArray.push_back(renderExpansion(Coverage, Expansion));
   return ExpansionArray;
 }
 
-json::Array renderFileSegments(const coverage::CoverageData &FileCoverage,
-                               const FileCoverageSummary &FileReport) {
+json::Array renderFileSegments(const coverage::CoverageData &FileCoverage) {
   json::Array SegmentArray;
   for (const auto &Segment : FileCoverage)
     SegmentArray.push_back(renderSegment(Segment));
   return SegmentArray;
 }
 
-json::Array renderFileBranches(const coverage::CoverageData &FileCoverage,
-                               const FileCoverageSummary &FileReport) {
+json::Array renderFileBranches(const coverage::CoverageData &FileCoverage) {
   json::Array BranchArray;
   for (const auto &Branch : FileCoverage.getBranches())
     BranchArray.push_back(renderBranch(Branch));
   return BranchArray;
 }
 
-json::Array renderFileMCDC(const coverage::CoverageData &FileCoverage,
-                           const FileCoverageSummary &FileReport) {
+json::Array renderFileMCDC(const coverage::CoverageData &FileCoverage) {
   json::Array MCDCRecordArray;
   for (const auto &Record : FileCoverage.getMCDCRecords())
     MCDCRecordArray.push_back(renderMCDCRecord(Record));
@@ -254,12 +279,11 @@ json::Object renderFile(const coverage::CoverageMapping &Coverage,
   if (!Options.ExportSummaryOnly) {
     // Calculate and render detailed coverage information for given file.
     auto FileCoverage = Coverage.getCoverageForFile(Filename);
-    File["segments"] = renderFileSegments(FileCoverage, FileReport);
-    File["branches"] = renderFileBranches(FileCoverage, FileReport);
-    File["mcdc_records"] = renderFileMCDC(FileCoverage, FileReport);
+    File["segments"] = renderFileSegments(FileCoverage);
+    File["branches"] = renderFileBranches(FileCoverage);
+    File["mcdc_records"] = renderFileMCDC(FileCoverage);
     if (!Options.SkipExpansions) {
-      File["expansions"] =
-          renderFileExpansions(Coverage, FileCoverage, FileReport);
+      File["expansions"] = renderFileExpansions(Coverage, FileCoverage);
     }
   }
   File["summary"] = renderSummary(FileReport);



More information about the llvm-commits mailing list