@@ -8,7 +8,6 @@ use cranelift_codegen::MachSrcLoc;
88use gimli:: write:: {
99 Address , AttributeValue , FileId , FileInfo , LineProgram , LineString , LineStringTable ,
1010} ;
11- use rustc_data_structures:: sync:: Lrc ;
1211use rustc_span:: {
1312 FileName , Pos , SourceFile , SourceFileAndLine , SourceFileHash , SourceFileHashAlgorithm ,
1413} ;
@@ -60,72 +59,78 @@ fn make_file_info(hash: SourceFileHash) -> Option<FileInfo> {
6059
6160impl DebugContext {
6261 pub ( crate ) fn get_span_loc (
62+ & mut self ,
6363 tcx : TyCtxt < ' _ > ,
6464 function_span : Span ,
6565 span : Span ,
66- ) -> ( Lrc < SourceFile > , u64 , u64 ) {
66+ ) -> ( FileId , u64 , u64 ) {
6767 // Based on https://github.com/rust-lang/rust/blob/e369d87b015a84653343032833d65d0545fd3f26/src/librustc_codegen_ssa/mir/mod.rs#L116-L131
6868 // In order to have a good line stepping behavior in debugger, we overwrite debug
6969 // locations of macro expansions with that of the outermost expansion site (when the macro is
7070 // annotated with `#[collapse_debuginfo]` or when `-Zdebug-macros` is provided).
7171 let span = tcx. collapsed_debuginfo ( span, function_span) ;
7272 match tcx. sess . source_map ( ) . lookup_line ( span. lo ( ) ) {
7373 Ok ( SourceFileAndLine { sf : file, line } ) => {
74+ let file_id = self . add_source_file ( & file) ;
7475 let line_pos = file. lines ( ) [ line] ;
7576 let col = file. relative_position ( span. lo ( ) ) - line_pos;
7677
77- ( file , u64:: try_from ( line) . unwrap ( ) + 1 , u64:: from ( col. to_u32 ( ) ) + 1 )
78+ ( file_id , u64:: try_from ( line) . unwrap ( ) + 1 , u64:: from ( col. to_u32 ( ) ) + 1 )
7879 }
79- Err ( file) => ( file, 0 , 0 ) ,
80+ Err ( file) => ( self . add_source_file ( & file) , 0 , 0 ) ,
8081 }
8182 }
8283
8384 pub ( crate ) fn add_source_file ( & mut self , source_file : & SourceFile ) -> FileId {
84- let line_program: & mut LineProgram = & mut self . dwarf . unit . line_program ;
85- let line_strings: & mut LineStringTable = & mut self . dwarf . line_strings ;
86-
87- match & source_file. name {
88- FileName :: Real ( path) => {
89- let ( dir_path, file_name) =
90- split_path_dir_and_file ( if self . should_remap_filepaths {
91- path. remapped_path_if_available ( )
92- } else {
93- path. local_path_if_available ( )
94- } ) ;
95- let dir_name = osstr_as_utf8_bytes ( dir_path. as_os_str ( ) ) ;
96- let file_name = osstr_as_utf8_bytes ( file_name) ;
97-
98- let dir_id = if !dir_name. is_empty ( ) {
99- let dir_name = LineString :: new ( dir_name, line_program. encoding ( ) , line_strings) ;
100- line_program. add_directory ( dir_name)
101- } else {
102- line_program. default_directory ( )
103- } ;
104- let file_name = LineString :: new ( file_name, line_program. encoding ( ) , line_strings) ;
105-
106- let info = make_file_info ( source_file. src_hash ) ;
107-
108- line_program. file_has_md5 &= info. is_some ( ) ;
109- line_program. add_file ( file_name, dir_id, info)
110- }
111- // FIXME give more appropriate file names
112- filename => {
113- let dir_id = line_program. default_directory ( ) ;
114- let dummy_file_name = LineString :: new (
115- filename
116- . display ( if self . should_remap_filepaths {
117- FileNameDisplayPreference :: Remapped
85+ let cache_key = ( source_file. stable_id , source_file. src_hash ) ;
86+ * self . created_files . entry ( cache_key) . or_insert_with ( || {
87+ let line_program: & mut LineProgram = & mut self . dwarf . unit . line_program ;
88+ let line_strings: & mut LineStringTable = & mut self . dwarf . line_strings ;
89+
90+ match & source_file. name {
91+ FileName :: Real ( path) => {
92+ let ( dir_path, file_name) =
93+ split_path_dir_and_file ( if self . should_remap_filepaths {
94+ path. remapped_path_if_available ( )
11895 } else {
119- FileNameDisplayPreference :: Local
120- } )
121- . to_string ( )
122- . into_bytes ( ) ,
123- line_program. encoding ( ) ,
124- line_strings,
125- ) ;
126- line_program. add_file ( dummy_file_name, dir_id, None )
96+ path. local_path_if_available ( )
97+ } ) ;
98+ let dir_name = osstr_as_utf8_bytes ( dir_path. as_os_str ( ) ) ;
99+ let file_name = osstr_as_utf8_bytes ( file_name) ;
100+
101+ let dir_id = if !dir_name. is_empty ( ) {
102+ let dir_name =
103+ LineString :: new ( dir_name, line_program. encoding ( ) , line_strings) ;
104+ line_program. add_directory ( dir_name)
105+ } else {
106+ line_program. default_directory ( )
107+ } ;
108+ let file_name =
109+ LineString :: new ( file_name, line_program. encoding ( ) , line_strings) ;
110+
111+ let info = make_file_info ( source_file. src_hash ) ;
112+
113+ line_program. file_has_md5 &= info. is_some ( ) ;
114+ line_program. add_file ( file_name, dir_id, info)
115+ }
116+ filename => {
117+ let dir_id = line_program. default_directory ( ) ;
118+ let dummy_file_name = LineString :: new (
119+ filename
120+ . display ( if self . should_remap_filepaths {
121+ FileNameDisplayPreference :: Remapped
122+ } else {
123+ FileNameDisplayPreference :: Local
124+ } )
125+ . to_string ( )
126+ . into_bytes ( ) ,
127+ line_program. encoding ( ) ,
128+ line_strings,
129+ ) ;
130+ line_program. add_file ( dummy_file_name, dir_id, None )
131+ }
127132 }
128- }
133+ } )
129134 }
130135}
131136
0 commit comments