@@ -5,6 +5,7 @@ use std::path::{Component, Path};
55
66use crate :: prelude:: * ;
77
8+ use rustc_data_structures:: sync:: Lrc ;
89use rustc_span:: {
910 FileName , Pos , SourceFile , SourceFileAndLine , SourceFileHash , SourceFileHashAlgorithm ,
1011} ;
@@ -47,9 +48,33 @@ fn osstr_as_utf8_bytes(path: &OsStr) -> &[u8] {
4748 }
4849}
4950
50- pub ( crate ) const MD5_LEN : usize = 16 ;
51+ fn get_span_loc ( tcx : TyCtxt < ' _ > , function_span : Span , span : Span ) -> ( Lrc < SourceFile > , u64 , u64 ) {
52+ // Based on https://github.com/rust-lang/rust/blob/e369d87b015a84653343032833d65d0545fd3f26/src/librustc_codegen_ssa/mir/mod.rs#L116-L131
53+ // In order to have a good line stepping behavior in debugger, we overwrite debug
54+ // locations of macro expansions with that of the outermost expansion site
55+ // (unless the crate is being compiled with `-Z debug-macros`).
56+ let span = if !span. from_expansion ( ) || tcx. sess . opts . unstable_opts . debug_macros {
57+ span
58+ } else {
59+ // Walk up the macro expansion chain until we reach a non-expanded span.
60+ // We also stop at the function body level because no line stepping can occur
61+ // at the level above that.
62+ rustc_span:: hygiene:: walk_chain ( span, function_span. ctxt ( ) )
63+ } ;
64+
65+ match tcx. sess . source_map ( ) . lookup_line ( span. lo ( ) ) {
66+ Ok ( SourceFileAndLine { sf : file, line } ) => {
67+ let line_pos = file. line_begin_pos ( span. lo ( ) ) ;
68+
69+ ( file, u64:: try_from ( line) . unwrap ( ) + 1 , u64:: from ( ( span. lo ( ) - line_pos) . to_u32 ( ) ) + 1 )
70+ }
71+ Err ( file) => ( file, 0 , 0 ) ,
72+ }
73+ }
74+
75+ const MD5_LEN : usize = 16 ;
5176
52- pub ( crate ) fn make_file_info ( hash : SourceFileHash ) -> Option < FileInfo > {
77+ fn make_file_info ( hash : SourceFileHash ) -> Option < FileInfo > {
5378 if hash. kind == SourceFileHashAlgorithm :: Md5 {
5479 let mut buf = [ 0u8 ; MD5_LEN ] ;
5580 buf. copy_from_slice ( hash. hash_bytes ( ) ) ;
@@ -97,22 +122,6 @@ fn line_program_add_file(
97122}
98123
99124impl DebugContext {
100- fn emit_location ( & mut self , tcx : TyCtxt < ' _ > , entry_id : UnitEntryId , span : Span ) {
101- let loc = tcx. sess . source_map ( ) . lookup_char_pos ( span. lo ( ) ) ;
102-
103- let file_id = line_program_add_file (
104- & mut self . dwarf . unit . line_program ,
105- & mut self . dwarf . line_strings ,
106- & loc. file ,
107- ) ;
108-
109- let entry = self . dwarf . unit . get_mut ( entry_id) ;
110-
111- entry. set ( gimli:: DW_AT_decl_file , AttributeValue :: FileIndex ( Some ( file_id) ) ) ;
112- entry. set ( gimli:: DW_AT_decl_line , AttributeValue :: Udata ( loc. line as u64 ) ) ;
113- entry. set ( gimli:: DW_AT_decl_column , AttributeValue :: Udata ( loc. col . to_usize ( ) as u64 ) ) ;
114- }
115-
116125 pub ( super ) fn create_debug_lines (
117126 & mut self ,
118127 tcx : TyCtxt < ' _ > ,
@@ -136,31 +145,7 @@ impl DebugContext {
136145 }
137146 last_span = Some ( span) ;
138147
139- // Based on https://github.com/rust-lang/rust/blob/e369d87b015a84653343032833d65d0545fd3f26/src/librustc_codegen_ssa/mir/mod.rs#L116-L131
140- // In order to have a good line stepping behavior in debugger, we overwrite debug
141- // locations of macro expansions with that of the outermost expansion site
142- // (unless the crate is being compiled with `-Z debug-macros`).
143- let span = if !span. from_expansion ( ) || tcx. sess . opts . unstable_opts . debug_macros {
144- span
145- } else {
146- // Walk up the macro expansion chain until we reach a non-expanded span.
147- // We also stop at the function body level because no line stepping can occur
148- // at the level above that.
149- rustc_span:: hygiene:: walk_chain ( span, function_span. ctxt ( ) )
150- } ;
151-
152- let ( file, line, col) = match tcx. sess . source_map ( ) . lookup_line ( span. lo ( ) ) {
153- Ok ( SourceFileAndLine { sf : file, line } ) => {
154- let line_pos = file. line_begin_pos ( span. lo ( ) ) ;
155-
156- (
157- file,
158- u64:: try_from ( line) . unwrap ( ) + 1 ,
159- u64:: from ( ( span. lo ( ) - line_pos) . to_u32 ( ) ) + 1 ,
160- )
161- }
162- Err ( file) => ( file, 0 , 0 ) ,
163- } ;
148+ let ( file, line, col) = get_span_loc ( tcx, function_span, span) ;
164149
165150 // line_program_add_file is very slow.
166151 // Optimize for the common case of the current file not being changed.
@@ -204,14 +189,24 @@ impl DebugContext {
204189
205190 assert_ne ! ( func_end, 0 ) ;
206191
192+ let ( function_file, function_line, function_col) =
193+ get_span_loc ( tcx, function_span, function_span) ;
194+
195+ let function_file_id = line_program_add_file (
196+ & mut self . dwarf . unit . line_program ,
197+ & mut self . dwarf . line_strings ,
198+ & function_file,
199+ ) ;
200+
207201 let entry = self . dwarf . unit . get_mut ( entry_id) ;
208202 entry. set (
209203 gimli:: DW_AT_low_pc ,
210204 AttributeValue :: Address ( Address :: Symbol { symbol, addend : 0 } ) ,
211205 ) ;
212206 entry. set ( gimli:: DW_AT_high_pc , AttributeValue :: Udata ( u64:: from ( func_end) ) ) ;
213-
214- self . emit_location ( tcx, entry_id, function_span) ;
207+ entry. set ( gimli:: DW_AT_decl_file , AttributeValue :: FileIndex ( Some ( function_file_id) ) ) ;
208+ entry. set ( gimli:: DW_AT_decl_line , AttributeValue :: Udata ( function_line) ) ;
209+ entry. set ( gimli:: DW_AT_decl_column , AttributeValue :: Udata ( function_col) ) ;
215210
216211 func_end
217212 }
0 commit comments