1
- use rustc_middle:: mir:: coverage:: { CodeRegion , CounterId , CovTerm , ExpressionId , MappingKind } ;
1
+ use rustc_middle:: mir:: coverage:: {
2
+ CodeRegion , ConditionInfo , CounterId , CovTerm , DecisionInfo , ExpressionId , MappingKind ,
3
+ } ;
2
4
3
5
/// Must match the layout of `LLVMRustCounterKind`.
4
6
#[ derive( Copy , Clone , Debug ) ]
@@ -99,6 +101,86 @@ pub enum RegionKind {
99
101
/// associated with two counters, each representing the number of times the
100
102
/// expression evaluates to true or false.
101
103
BranchRegion = 4 ,
104
+
105
+ /// A DecisionRegion represents a top-level boolean expression and is
106
+ /// associated with a variable length bitmap index and condition number.
107
+ MCDCDecisionRegion = 5 ,
108
+
109
+ /// A Branch Region can be extended to include IDs to facilitate MC/DC.
110
+ MCDCBranchRegion = 6 ,
111
+ }
112
+
113
+ pub mod mcdc {
114
+ use rustc_middle:: mir:: coverage:: { ConditionInfo , DecisionInfo } ;
115
+
116
+ /// Must match the layout of `LLVMRustMCDCDecisionParameters`.
117
+ #[ repr( C ) ]
118
+ #[ derive( Clone , Copy , Debug , Default ) ]
119
+ pub struct DecisionParameters {
120
+ bitmap_idx : u32 ,
121
+ conditions_num : u16 ,
122
+ }
123
+
124
+ // ConditionId in llvm is `unsigned int` at 18 while `int16_t` at [19](https://github.com/llvm/llvm-project/pull/81257)
125
+ type LLVMConditionId = i16 ;
126
+
127
+ /// Must match the layout of `LLVMRustMCDCBranchParameters`.
128
+ #[ repr( C ) ]
129
+ #[ derive( Clone , Copy , Debug , Default ) ]
130
+ pub struct BranchParameters {
131
+ condition_id : LLVMConditionId ,
132
+ condition_ids : [ LLVMConditionId ; 2 ] ,
133
+ }
134
+
135
+ #[ repr( C ) ]
136
+ #[ derive( Clone , Copy , Debug ) ]
137
+ pub enum ParameterTag {
138
+ None = 0 ,
139
+ Decision = 1 ,
140
+ Branch = 2 ,
141
+ }
142
+ /// Same layout with `LLVMRustMCDCParameters`
143
+ #[ repr( C ) ]
144
+ #[ derive( Clone , Copy , Debug ) ]
145
+ pub struct Parameters {
146
+ tag : ParameterTag ,
147
+ decision_params : DecisionParameters ,
148
+ branch_params : BranchParameters ,
149
+ }
150
+
151
+ impl Parameters {
152
+ pub fn none ( ) -> Self {
153
+ Self {
154
+ tag : ParameterTag :: None ,
155
+ decision_params : Default :: default ( ) ,
156
+ branch_params : Default :: default ( ) ,
157
+ }
158
+ }
159
+ pub fn decision ( decision_params : DecisionParameters ) -> Self {
160
+ Self { tag : ParameterTag :: Decision , decision_params, branch_params : Default :: default ( ) }
161
+ }
162
+ pub fn branch ( branch_params : BranchParameters ) -> Self {
163
+ Self { tag : ParameterTag :: Branch , decision_params : Default :: default ( ) , branch_params }
164
+ }
165
+ }
166
+
167
+ impl From < ConditionInfo > for BranchParameters {
168
+ fn from ( value : ConditionInfo ) -> Self {
169
+ Self {
170
+ condition_id : value. condition_id . as_u32 ( ) as LLVMConditionId ,
171
+ condition_ids : [
172
+ value. false_next_id . as_u32 ( ) as LLVMConditionId ,
173
+ value. true_next_id . as_u32 ( ) as LLVMConditionId ,
174
+ ] ,
175
+ }
176
+ }
177
+ }
178
+
179
+ impl From < DecisionInfo > for DecisionParameters {
180
+ fn from ( value : DecisionInfo ) -> Self {
181
+ Self { bitmap_idx : value. bitmap_idx , conditions_num : value. conditions_num }
182
+ }
183
+ }
102
184
}
103
185
104
186
/// This struct provides LLVM's representation of a "CoverageMappingRegion", encoded into the
@@ -122,6 +204,7 @@ pub struct CounterMappingRegion {
122
204
/// for the false branch of the region.
123
205
false_counter : Counter ,
124
206
207
+ mcdc_params : mcdc:: Parameters ,
125
208
/// An indirect reference to the source filename. In the LLVM Coverage Mapping Format, the
126
209
/// file_id is an index into a function-specific `virtual_file_mapping` array of indexes
127
210
/// that, in turn, are used to look up the filename for this region.
@@ -173,6 +256,26 @@ impl CounterMappingRegion {
173
256
end_line,
174
257
end_col,
175
258
) ,
259
+ MappingKind :: MCDCBranch { true_term, false_term, mcdc_params } => {
260
+ Self :: mcdc_branch_region (
261
+ Counter :: from_term ( true_term) ,
262
+ Counter :: from_term ( false_term) ,
263
+ mcdc_params,
264
+ local_file_id,
265
+ start_line,
266
+ start_col,
267
+ end_line,
268
+ end_col,
269
+ )
270
+ }
271
+ MappingKind :: MCDCDecision ( decision_info) => Self :: decision_region (
272
+ decision_info,
273
+ local_file_id,
274
+ start_line,
275
+ start_col,
276
+ end_line,
277
+ end_col,
278
+ ) ,
176
279
}
177
280
}
178
281
@@ -187,6 +290,7 @@ impl CounterMappingRegion {
187
290
Self {
188
291
counter,
189
292
false_counter : Counter :: ZERO ,
293
+ mcdc_params : mcdc:: Parameters :: none ( ) ,
190
294
file_id,
191
295
expanded_file_id : 0 ,
192
296
start_line,
@@ -209,6 +313,7 @@ impl CounterMappingRegion {
209
313
Self {
210
314
counter,
211
315
false_counter,
316
+ mcdc_params : mcdc:: Parameters :: none ( ) ,
212
317
file_id,
213
318
expanded_file_id : 0 ,
214
319
start_line,
@@ -219,6 +324,54 @@ impl CounterMappingRegion {
219
324
}
220
325
}
221
326
327
+ pub ( crate ) fn mcdc_branch_region (
328
+ counter : Counter ,
329
+ false_counter : Counter ,
330
+ condition_info : ConditionInfo ,
331
+ file_id : u32 ,
332
+ start_line : u32 ,
333
+ start_col : u32 ,
334
+ end_line : u32 ,
335
+ end_col : u32 ,
336
+ ) -> Self {
337
+ Self {
338
+ counter,
339
+ false_counter,
340
+ mcdc_params : mcdc:: Parameters :: branch ( condition_info. into ( ) ) ,
341
+ file_id,
342
+ expanded_file_id : 0 ,
343
+ start_line,
344
+ start_col,
345
+ end_line,
346
+ end_col,
347
+ kind : RegionKind :: MCDCBranchRegion ,
348
+ }
349
+ }
350
+
351
+ pub ( crate ) fn decision_region (
352
+ decision_info : DecisionInfo ,
353
+ file_id : u32 ,
354
+ start_line : u32 ,
355
+ start_col : u32 ,
356
+ end_line : u32 ,
357
+ end_col : u32 ,
358
+ ) -> Self {
359
+ let mcdc_params = mcdc:: Parameters :: decision ( decision_info. into ( ) ) ;
360
+
361
+ Self {
362
+ counter : Counter :: ZERO ,
363
+ false_counter : Counter :: ZERO ,
364
+ mcdc_params,
365
+ file_id,
366
+ expanded_file_id : 0 ,
367
+ start_line,
368
+ start_col,
369
+ end_line,
370
+ end_col,
371
+ kind : RegionKind :: MCDCDecisionRegion ,
372
+ }
373
+ }
374
+
222
375
// This function might be used in the future; the LLVM API is still evolving, as is coverage
223
376
// support.
224
377
#[ allow( dead_code) ]
@@ -233,6 +386,7 @@ impl CounterMappingRegion {
233
386
Self {
234
387
counter : Counter :: ZERO ,
235
388
false_counter : Counter :: ZERO ,
389
+ mcdc_params : mcdc:: Parameters :: none ( ) ,
236
390
file_id,
237
391
expanded_file_id,
238
392
start_line,
@@ -256,6 +410,7 @@ impl CounterMappingRegion {
256
410
Self {
257
411
counter : Counter :: ZERO ,
258
412
false_counter : Counter :: ZERO ,
413
+ mcdc_params : mcdc:: Parameters :: none ( ) ,
259
414
file_id,
260
415
expanded_file_id : 0 ,
261
416
start_line,
@@ -280,6 +435,7 @@ impl CounterMappingRegion {
280
435
Self {
281
436
counter,
282
437
false_counter : Counter :: ZERO ,
438
+ mcdc_params : mcdc:: Parameters :: none ( ) ,
283
439
file_id,
284
440
expanded_file_id : 0 ,
285
441
start_line,
0 commit comments