21
21
// -- Branches: array => List of Branches in the file
22
22
// -- Branch: dict => Describes a branch of the file with counters
23
23
// -- 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
25
26
// -- Segments: array => List of Segments contained in the file
26
27
// -- Segment: dict => Describes a segment of the file with a counter
27
28
// -- Expansions: array => List of expansion records
62
63
#include < utility>
63
64
64
65
// / 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 "
66
67
67
68
// / Unique type identifier for JSON coverage export.
68
69
#define LLVM_COVERAGE_EXPORT_JSON_TYPE_STR " llvm.coverage.json.export"
@@ -108,13 +109,42 @@ json::Array gatherConditions(const coverage::MCDCRecord &Record) {
108
109
return Conditions;
109
110
}
110
111
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
+
111
140
json::Array renderMCDCRecord (const coverage::MCDCRecord &Record) {
112
141
const llvm::coverage::CounterMappingRegion &CMR = Record.getDecisionRegion ();
113
142
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))});
118
148
}
119
149
120
150
json::Array renderRegions (ArrayRef<coverage::CountedRegion> Regions) {
@@ -216,32 +246,28 @@ json::Object renderSummary(const FileCoverageSummary &Summary) {
216
246
}
217
247
218
248
json::Array renderFileExpansions (const coverage::CoverageMapping &Coverage,
219
- const coverage::CoverageData &FileCoverage,
220
- const FileCoverageSummary &FileReport) {
249
+ const coverage::CoverageData &FileCoverage) {
221
250
json::Array ExpansionArray;
222
251
for (const auto &Expansion : FileCoverage.getExpansions ())
223
252
ExpansionArray.push_back (renderExpansion (Coverage, Expansion));
224
253
return ExpansionArray;
225
254
}
226
255
227
- json::Array renderFileSegments (const coverage::CoverageData &FileCoverage,
228
- const FileCoverageSummary &FileReport) {
256
+ json::Array renderFileSegments (const coverage::CoverageData &FileCoverage) {
229
257
json::Array SegmentArray;
230
258
for (const auto &Segment : FileCoverage)
231
259
SegmentArray.push_back (renderSegment (Segment));
232
260
return SegmentArray;
233
261
}
234
262
235
- json::Array renderFileBranches (const coverage::CoverageData &FileCoverage,
236
- const FileCoverageSummary &FileReport) {
263
+ json::Array renderFileBranches (const coverage::CoverageData &FileCoverage) {
237
264
json::Array BranchArray;
238
265
for (const auto &Branch : FileCoverage.getBranches ())
239
266
BranchArray.push_back (renderBranch (Branch));
240
267
return BranchArray;
241
268
}
242
269
243
- json::Array renderFileMCDC (const coverage::CoverageData &FileCoverage,
244
- const FileCoverageSummary &FileReport) {
270
+ json::Array renderFileMCDC (const coverage::CoverageData &FileCoverage) {
245
271
json::Array MCDCRecordArray;
246
272
for (const auto &Record : FileCoverage.getMCDCRecords ())
247
273
MCDCRecordArray.push_back (renderMCDCRecord (Record));
@@ -256,12 +282,11 @@ json::Object renderFile(const coverage::CoverageMapping &Coverage,
256
282
if (!Options.ExportSummaryOnly ) {
257
283
// Calculate and render detailed coverage information for given file.
258
284
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);
262
288
if (!Options.SkipExpansions ) {
263
- File[" expansions" ] =
264
- renderFileExpansions (Coverage, FileCoverage, FileReport);
289
+ File[" expansions" ] = renderFileExpansions (Coverage, FileCoverage);
265
290
}
266
291
}
267
292
File[" summary" ] = renderSummary (FileReport);
0 commit comments