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+ } ;
24
35/// Must match the layout of `LLVMRustCounterKind`.
46#[ derive( Copy , Clone , Debug ) ]
@@ -99,6 +101,86 @@ pub enum RegionKind {
99101 /// associated with two counters, each representing the number of times the
100102 /// expression evaluates to true or false.
101103 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+ }
102184}
103185
104186/// This struct provides LLVM's representation of a "CoverageMappingRegion", encoded into the
@@ -122,6 +204,7 @@ pub struct CounterMappingRegion {
122204 /// for the false branch of the region.
123205 false_counter : Counter ,
124206
207+ mcdc_params : mcdc:: Parameters ,
125208 /// An indirect reference to the source filename. In the LLVM Coverage Mapping Format, the
126209 /// file_id is an index into a function-specific `virtual_file_mapping` array of indexes
127210 /// that, in turn, are used to look up the filename for this region.
@@ -173,6 +256,26 @@ impl CounterMappingRegion {
173256 end_line,
174257 end_col,
175258 ) ,
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+ ) ,
176279 }
177280 }
178281
@@ -187,6 +290,7 @@ impl CounterMappingRegion {
187290 Self {
188291 counter,
189292 false_counter : Counter :: ZERO ,
293+ mcdc_params : mcdc:: Parameters :: none ( ) ,
190294 file_id,
191295 expanded_file_id : 0 ,
192296 start_line,
@@ -209,6 +313,7 @@ impl CounterMappingRegion {
209313 Self {
210314 counter,
211315 false_counter,
316+ mcdc_params : mcdc:: Parameters :: none ( ) ,
212317 file_id,
213318 expanded_file_id : 0 ,
214319 start_line,
@@ -219,6 +324,54 @@ impl CounterMappingRegion {
219324 }
220325 }
221326
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+
222375 // This function might be used in the future; the LLVM API is still evolving, as is coverage
223376 // support.
224377 #[ allow( dead_code) ]
@@ -233,6 +386,7 @@ impl CounterMappingRegion {
233386 Self {
234387 counter : Counter :: ZERO ,
235388 false_counter : Counter :: ZERO ,
389+ mcdc_params : mcdc:: Parameters :: none ( ) ,
236390 file_id,
237391 expanded_file_id,
238392 start_line,
@@ -256,6 +410,7 @@ impl CounterMappingRegion {
256410 Self {
257411 counter : Counter :: ZERO ,
258412 false_counter : Counter :: ZERO ,
413+ mcdc_params : mcdc:: Parameters :: none ( ) ,
259414 file_id,
260415 expanded_file_id : 0 ,
261416 start_line,
@@ -280,6 +435,7 @@ impl CounterMappingRegion {
280435 Self {
281436 counter,
282437 false_counter : Counter :: ZERO ,
438+ mcdc_params : mcdc:: Parameters :: none ( ) ,
283439 file_id,
284440 expanded_file_id : 0 ,
285441 start_line,
0 commit comments