@@ -11,8 +11,10 @@ use rustc_index::IndexVec;
1111use rustc_middle:: mir:: coverage:: MappingKind ;
1212use rustc_middle:: ty:: { self , TyCtxt } ;
1313use rustc_middle:: { bug, mir} ;
14- use rustc_span:: Symbol ;
14+ use rustc_session:: RemapFileNameExt ;
15+ use rustc_session:: config:: RemapPathScopeComponents ;
1516use rustc_span:: def_id:: DefIdSet ;
17+ use rustc_span:: { Span , Symbol } ;
1618use rustc_target:: spec:: HasTargetSpec ;
1719use tracing:: debug;
1820
@@ -69,8 +71,10 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
6971 . map ( |( instance, function_coverage) | ( instance, function_coverage. into_finished ( ) ) )
7072 . collect :: < Vec < _ > > ( ) ;
7173
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) ) ;
7478 let global_file_table = GlobalFileTable :: new ( all_file_names) ;
7579
7680 // Encode all filenames referenced by coverage mappings in this CGU.
@@ -95,7 +99,7 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
9599 let is_used = function_coverage. is_used ( ) ;
96100
97101 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) ;
99103
100104 if coverage_mapping_buffer. is_empty ( ) {
101105 if function_coverage. is_used ( ) {
@@ -232,12 +236,20 @@ impl VirtualFileMapping {
232236 }
233237}
234238
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+
235246/// Using the expressions and counter regions collected for a single function,
236247/// generate the variable-sized payload of its corresponding `__llvm_covfun`
237248/// entry. The payload is returned as a vector of bytes.
238249///
239250/// Newly-encountered filenames will be added to the global file table.
240251fn encode_mappings_for_function (
252+ tcx : TyCtxt < ' _ > ,
241253 global_file_table : & GlobalFileTable ,
242254 function_coverage : & FunctionCoverage < ' _ > ,
243255) -> Vec < u8 > {
@@ -254,53 +266,45 @@ fn encode_mappings_for_function(
254266 let mut mcdc_branch_regions = vec ! [ ] ;
255267 let mut mcdc_decision_regions = vec ! [ ] ;
256268
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+ } ) ;
304308 }
305309 }
306310 }
0 commit comments