@@ -11,8 +11,10 @@ use rustc_index::IndexVec;
11
11
use rustc_middle:: mir:: coverage:: MappingKind ;
12
12
use rustc_middle:: ty:: { self , TyCtxt } ;
13
13
use rustc_middle:: { bug, mir} ;
14
- use rustc_span:: Symbol ;
14
+ use rustc_session:: RemapFileNameExt ;
15
+ use rustc_session:: config:: RemapPathScopeComponents ;
15
16
use rustc_span:: def_id:: DefIdSet ;
17
+ use rustc_span:: { Span , Symbol } ;
16
18
use rustc_target:: spec:: HasTargetSpec ;
17
19
use tracing:: debug;
18
20
@@ -69,8 +71,10 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
69
71
. map ( |( instance, function_coverage) | ( instance, function_coverage. into_finished ( ) ) )
70
72
. collect :: < Vec < _ > > ( ) ;
71
73
72
- let all_file_names =
73
- function_coverage_entries. iter ( ) . flat_map ( |( _, fn_cov) | fn_cov. all_file_names ( ) ) ;
74
+ let all_file_names = function_coverage_entries
75
+ . iter ( )
76
+ . map ( |( _, fn_cov) | fn_cov. function_coverage_info . body_span )
77
+ . map ( |span| span_file_name ( tcx, span) ) ;
74
78
let global_file_table = GlobalFileTable :: new ( all_file_names) ;
75
79
76
80
// Encode all filenames referenced by coverage mappings in this CGU.
@@ -95,7 +99,7 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
95
99
let is_used = function_coverage. is_used ( ) ;
96
100
97
101
let coverage_mapping_buffer =
98
- encode_mappings_for_function ( & global_file_table, & function_coverage) ;
102
+ encode_mappings_for_function ( tcx , & global_file_table, & function_coverage) ;
99
103
100
104
if coverage_mapping_buffer. is_empty ( ) {
101
105
if function_coverage. is_used ( ) {
@@ -232,12 +236,20 @@ impl VirtualFileMapping {
232
236
}
233
237
}
234
238
239
+ fn span_file_name ( tcx : TyCtxt < ' _ > , span : Span ) -> Symbol {
240
+ let source_file = tcx. sess . source_map ( ) . lookup_source_file ( span. lo ( ) ) ;
241
+ let name =
242
+ source_file. name . for_scope ( tcx. sess , RemapPathScopeComponents :: MACRO ) . to_string_lossy ( ) ;
243
+ Symbol :: intern ( & name)
244
+ }
245
+
235
246
/// Using the expressions and counter regions collected for a single function,
236
247
/// generate the variable-sized payload of its corresponding `__llvm_covfun`
237
248
/// entry. The payload is returned as a vector of bytes.
238
249
///
239
250
/// Newly-encountered filenames will be added to the global file table.
240
251
fn encode_mappings_for_function (
252
+ tcx : TyCtxt < ' _ > ,
241
253
global_file_table : & GlobalFileTable ,
242
254
function_coverage : & FunctionCoverage < ' _ > ,
243
255
) -> Vec < u8 > {
@@ -254,53 +266,45 @@ fn encode_mappings_for_function(
254
266
let mut mcdc_branch_regions = vec ! [ ] ;
255
267
let mut mcdc_decision_regions = vec ! [ ] ;
256
268
257
- // Group mappings into runs with the same filename, preserving the order
258
- // yielded by `FunctionCoverage`.
259
- // Prepare file IDs for each filename, and prepare the mapping data so that
260
- // we can pass it through FFI to LLVM.
261
- for ( file_name, counter_regions_for_file) in
262
- & counter_regions. group_by ( |( _, region) | region. file_name )
263
- {
264
- // Look up the global file ID for this filename.
265
- let global_file_id = global_file_table. global_file_id_for_file_name ( file_name) ;
266
-
267
- // Associate that global file ID with a local file ID for this function.
268
- let local_file_id = virtual_file_mapping. local_id_for_global ( global_file_id) ;
269
- debug ! ( " file id: {local_file_id:?} => {global_file_id:?} = '{file_name:?}'" ) ;
270
-
271
- // For each counter/region pair in this function+file, convert it to a
272
- // form suitable for FFI.
273
- for ( mapping_kind, region) in counter_regions_for_file {
274
- debug ! ( "Adding counter {mapping_kind:?} to map for {region:?}" ) ;
275
- let span = ffi:: CoverageSpan :: from_source_region ( local_file_id. as_u32 ( ) , region) ;
276
- match mapping_kind {
277
- MappingKind :: Code ( term) => {
278
- code_regions
279
- . push ( ffi:: CodeRegion { span, counter : ffi:: Counter :: from_term ( term) } ) ;
280
- }
281
- MappingKind :: Branch { true_term, false_term } => {
282
- branch_regions. push ( ffi:: BranchRegion {
283
- span,
284
- true_counter : ffi:: Counter :: from_term ( true_term) ,
285
- false_counter : ffi:: Counter :: from_term ( false_term) ,
286
- } ) ;
287
- }
288
- MappingKind :: MCDCBranch { true_term, false_term, mcdc_params } => {
289
- mcdc_branch_regions. push ( ffi:: MCDCBranchRegion {
290
- span,
291
- true_counter : ffi:: Counter :: from_term ( true_term) ,
292
- false_counter : ffi:: Counter :: from_term ( false_term) ,
293
- mcdc_branch_params : ffi:: mcdc:: BranchParameters :: from ( mcdc_params) ,
294
- } ) ;
295
- }
296
- MappingKind :: MCDCDecision ( mcdc_decision_params) => {
297
- mcdc_decision_regions. push ( ffi:: MCDCDecisionRegion {
298
- span,
299
- mcdc_decision_params : ffi:: mcdc:: DecisionParameters :: from (
300
- mcdc_decision_params,
301
- ) ,
302
- } ) ;
303
- }
269
+ // Currently a function's mappings must all be in the same file as its body span.
270
+ let file_name = span_file_name ( tcx, function_coverage. function_coverage_info . body_span ) ;
271
+
272
+ // Look up the global file ID for that filename.
273
+ let global_file_id = global_file_table. global_file_id_for_file_name ( file_name) ;
274
+
275
+ // Associate that global file ID with a local file ID for this function.
276
+ let local_file_id = virtual_file_mapping. local_id_for_global ( global_file_id) ;
277
+ debug ! ( " file id: {local_file_id:?} => {global_file_id:?} = '{file_name:?}'" ) ;
278
+
279
+ // For each counter/region pair in this function+file, convert it to a
280
+ // form suitable for FFI.
281
+ for ( mapping_kind, region) in counter_regions {
282
+ debug ! ( "Adding counter {mapping_kind:?} to map for {region:?}" ) ;
283
+ let span = ffi:: CoverageSpan :: from_source_region ( local_file_id. as_u32 ( ) , region) ;
284
+ match mapping_kind {
285
+ MappingKind :: Code ( term) => {
286
+ code_regions. push ( ffi:: CodeRegion { span, counter : ffi:: Counter :: from_term ( term) } ) ;
287
+ }
288
+ MappingKind :: Branch { true_term, false_term } => {
289
+ branch_regions. push ( ffi:: BranchRegion {
290
+ span,
291
+ true_counter : ffi:: Counter :: from_term ( true_term) ,
292
+ false_counter : ffi:: Counter :: from_term ( false_term) ,
293
+ } ) ;
294
+ }
295
+ MappingKind :: MCDCBranch { true_term, false_term, mcdc_params } => {
296
+ mcdc_branch_regions. push ( ffi:: MCDCBranchRegion {
297
+ span,
298
+ true_counter : ffi:: Counter :: from_term ( true_term) ,
299
+ false_counter : ffi:: Counter :: from_term ( false_term) ,
300
+ mcdc_branch_params : ffi:: mcdc:: BranchParameters :: from ( mcdc_params) ,
301
+ } ) ;
302
+ }
303
+ MappingKind :: MCDCDecision ( mcdc_decision_params) => {
304
+ mcdc_decision_regions. push ( ffi:: MCDCDecisionRegion {
305
+ span,
306
+ mcdc_decision_params : ffi:: mcdc:: DecisionParameters :: from ( mcdc_decision_params) ,
307
+ } ) ;
304
308
}
305
309
}
306
310
}
0 commit comments