2121// -- Branches: array => List of Branches in the file
2222// -- Branch: dict => Describes a branch of the file with counters
2323// -- MCDC Records: array => List of MCDC records in the file
24- // -- MCDC Values: array => List of T/F covered condition values
24+ // -- MCDC Values: array => List of T/F covered condition values and
25+ // list of executed test vectors
2526// -- Segments: array => List of Segments contained in the file
2627// -- Segment: dict => Describes a segment of the file with a counter
2728// -- Expansions: array => List of expansion records
6263#include < utility>
6364
6465// / The semantic version combined as a string.
65- #define LLVM_COVERAGE_EXPORT_JSON_STR " 3.0.1 "
66+ #define LLVM_COVERAGE_EXPORT_JSON_STR " 3.1.0 "
6667
6768// / Unique type identifier for JSON coverage export.
6869#define LLVM_COVERAGE_EXPORT_JSON_TYPE_STR " llvm.coverage.json.export"
@@ -108,13 +109,42 @@ json::Array gatherConditions(const coverage::MCDCRecord &Record) {
108109 return Conditions;
109110}
110111
112+ json::Value renderCondState (const coverage::MCDCRecord::CondState CondState) {
113+ switch (CondState) {
114+ case coverage::MCDCRecord::MCDC_DontCare:
115+ return json::Value (nullptr );
116+ case coverage::MCDCRecord::MCDC_True:
117+ return json::Value (true );
118+ case coverage::MCDCRecord::MCDC_False:
119+ return json::Value (false );
120+ }
121+ }
122+
123+ json::Array gatherTestVectors (coverage::MCDCRecord &Record) {
124+ json::Array TestVectors;
125+ unsigned NumConditions = Record.getNumConditions ();
126+ for (unsigned tv = 0 ; tv < Record.getNumTestVectors (); tv++) {
127+
128+ json::Array TVConditions;
129+ for (unsigned c = 0 ; c < NumConditions; c++)
130+ TVConditions.push_back (renderCondState (Record.getTVCondition (tv, c)));
131+
132+ TestVectors.push_back (
133+ json::Object ({{" executed" , json::Value (true )},
134+ {" result" , renderCondState (Record.getTVResult (tv))},
135+ {" conditions" , std::move (TVConditions)}}));
136+ }
137+ return TestVectors;
138+ }
139+
111140json::Array renderMCDCRecord (const coverage::MCDCRecord &Record) {
112141 const llvm::coverage::CounterMappingRegion &CMR = Record.getDecisionRegion ();
113142 const auto [TrueDecisions, FalseDecisions] = Record.getDecisions ();
114- return json::Array ({CMR.LineStart , CMR.ColumnStart , CMR.LineEnd ,
115- CMR.ColumnEnd , TrueDecisions, FalseDecisions,
116- CMR.FileID , CMR.ExpandedFileID , int64_t (CMR.Kind ),
117- gatherConditions (Record)});
143+ return json::Array (
144+ {CMR.LineStart , CMR.ColumnStart , CMR.LineEnd , CMR.ColumnEnd ,
145+ TrueDecisions, FalseDecisions, CMR.FileID , CMR.ExpandedFileID ,
146+ int64_t (CMR.Kind ), gatherConditions (Record),
147+ gatherTestVectors (const_cast <coverage::MCDCRecord &>(Record))});
118148}
119149
120150json::Array renderRegions (ArrayRef<coverage::CountedRegion> Regions) {
@@ -216,32 +246,28 @@ json::Object renderSummary(const FileCoverageSummary &Summary) {
216246}
217247
218248json::Array renderFileExpansions (const coverage::CoverageMapping &Coverage,
219- const coverage::CoverageData &FileCoverage,
220- const FileCoverageSummary &FileReport) {
249+ const coverage::CoverageData &FileCoverage) {
221250 json::Array ExpansionArray;
222251 for (const auto &Expansion : FileCoverage.getExpansions ())
223252 ExpansionArray.push_back (renderExpansion (Coverage, Expansion));
224253 return ExpansionArray;
225254}
226255
227- json::Array renderFileSegments (const coverage::CoverageData &FileCoverage,
228- const FileCoverageSummary &FileReport) {
256+ json::Array renderFileSegments (const coverage::CoverageData &FileCoverage) {
229257 json::Array SegmentArray;
230258 for (const auto &Segment : FileCoverage)
231259 SegmentArray.push_back (renderSegment (Segment));
232260 return SegmentArray;
233261}
234262
235- json::Array renderFileBranches (const coverage::CoverageData &FileCoverage,
236- const FileCoverageSummary &FileReport) {
263+ json::Array renderFileBranches (const coverage::CoverageData &FileCoverage) {
237264 json::Array BranchArray;
238265 for (const auto &Branch : FileCoverage.getBranches ())
239266 BranchArray.push_back (renderBranch (Branch));
240267 return BranchArray;
241268}
242269
243- json::Array renderFileMCDC (const coverage::CoverageData &FileCoverage,
244- const FileCoverageSummary &FileReport) {
270+ json::Array renderFileMCDC (const coverage::CoverageData &FileCoverage) {
245271 json::Array MCDCRecordArray;
246272 for (const auto &Record : FileCoverage.getMCDCRecords ())
247273 MCDCRecordArray.push_back (renderMCDCRecord (Record));
@@ -256,12 +282,11 @@ json::Object renderFile(const coverage::CoverageMapping &Coverage,
256282 if (!Options.ExportSummaryOnly ) {
257283 // Calculate and render detailed coverage information for given file.
258284 auto FileCoverage = Coverage.getCoverageForFile (Filename);
259- File[" segments" ] = renderFileSegments (FileCoverage, FileReport );
260- File[" branches" ] = renderFileBranches (FileCoverage, FileReport );
261- File[" mcdc_records" ] = renderFileMCDC (FileCoverage, FileReport );
285+ File[" segments" ] = renderFileSegments (FileCoverage);
286+ File[" branches" ] = renderFileBranches (FileCoverage);
287+ File[" mcdc_records" ] = renderFileMCDC (FileCoverage);
262288 if (!Options.SkipExpansions ) {
263- File[" expansions" ] =
264- renderFileExpansions (Coverage, FileCoverage, FileReport);
289+ File[" expansions" ] = renderFileExpansions (Coverage, FileCoverage);
265290 }
266291 }
267292 File[" summary" ] = renderSummary (FileReport);
0 commit comments