@@ -12,8 +12,8 @@ use super::operand::OperandValue;
1212use super :: place:: PlaceRef ;
1313use super :: { FunctionCx , LocalRef } ;
1414
15- pub struct FunctionDebugContext < D > {
16- pub scopes : IndexVec < mir:: SourceScope , DebugScope < D > > ,
15+ pub struct FunctionDebugContext < S , L > {
16+ pub scopes : IndexVec < mir:: SourceScope , DebugScope < S , L > > ,
1717}
1818
1919#[ derive( Copy , Clone ) ]
@@ -36,15 +36,42 @@ pub struct PerLocalVarDebugInfo<'tcx, D> {
3636}
3737
3838#[ derive( Clone , Copy , Debug ) ]
39- pub struct DebugScope < D > {
39+ pub struct DebugScope < S , L > {
4040 // FIXME(eddyb) this should never be `None`, after initialization.
41- pub dbg_scope : Option < D > ,
41+ pub dbg_scope : Option < S > ,
42+
43+ /// Call site location, if this scope was inlined from another function.
44+ pub inlined_at : Option < L > ,
45+
4246 // Start and end offsets of the file to which this DIScope belongs.
4347 // These are used to quickly determine whether some span refers to the same file.
4448 pub file_start_pos : BytePos ,
4549 pub file_end_pos : BytePos ,
4650}
4751
52+ impl < ' tcx , S : Copy , L : Copy > DebugScope < S , L > {
53+ /// DILocations inherit source file name from the parent DIScope. Due to macro expansions
54+ /// it may so happen that the current span belongs to a different file than the DIScope
55+ /// corresponding to span's containing source scope. If so, we need to create a DIScope
56+ /// "extension" into that file.
57+ pub fn adjust_dbg_scope_for_span < Cx : CodegenMethods < ' tcx , DIScope = S , DILocation = L > > (
58+ & self ,
59+ cx : & Cx ,
60+ span : Span ,
61+ ) -> S {
62+ // FIXME(eddyb) this should never be `None`.
63+ let dbg_scope = self . dbg_scope . unwrap ( ) ;
64+
65+ let pos = span. lo ( ) ;
66+ if pos < self . file_start_pos || pos >= self . file_end_pos {
67+ let sm = cx. sess ( ) . source_map ( ) ;
68+ cx. extend_scope_to_file ( dbg_scope, & sm. lookup_char_pos ( pos) . file )
69+ } else {
70+ dbg_scope
71+ }
72+ }
73+ }
74+
4875impl < ' a , ' tcx , Bx : BuilderMethods < ' a , ' tcx > > FunctionCx < ' a , ' tcx , Bx > {
4976 pub fn set_debug_loc ( & self , bx : & mut Bx , source_info : mir:: SourceInfo ) {
5077 bx. set_span ( source_info. span ) ;
@@ -54,19 +81,21 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
5481 }
5582
5683 fn dbg_loc ( & self , source_info : mir:: SourceInfo ) -> Option < Bx :: DILocation > {
57- let ( scope, span) = self . dbg_scope_and_span ( source_info) ?;
58- Some ( self . cx . dbg_loc ( scope, span) )
84+ let span = self . adjust_span_for_debugging ( source_info. span ) ;
85+ let scope = & self . debug_context . as_ref ( ) ?. scopes [ source_info. scope ] ;
86+ let dbg_scope = scope. adjust_dbg_scope_for_span ( self . cx , span) ;
87+ Some ( self . cx . dbg_loc ( dbg_scope, scope. inlined_at , span) )
5988 }
6089
61- fn dbg_scope_and_span ( & self , source_info : mir:: SourceInfo ) -> Option < ( Bx :: DIScope , Span ) > {
90+ /// In order to have a good line stepping behavior in debugger, we overwrite debug
91+ /// locations of macro expansions with that of the outermost expansion site
92+ /// (unless the crate is being compiled with `-Z debug-macros`).
93+ fn adjust_span_for_debugging ( & self , mut span : Span ) -> Span {
6294 // Bail out if debug info emission is not enabled.
63- let debug_context = self . debug_context . as_ref ( ) ?;
64- let scope = & debug_context. scopes [ source_info. scope ] ;
95+ if self . debug_context . is_none ( ) {
96+ return span;
97+ }
6598
66- // In order to have a good line stepping behavior in debugger, we overwrite debug
67- // locations of macro expansions with that of the outermost expansion site
68- // (unless the crate is being compiled with `-Z debug-macros`).
69- let mut span = source_info. span ;
7099 if span. from_expansion ( ) && !self . cx . sess ( ) . opts . debugging_opts . debug_macros {
71100 // Walk up the macro expansion chain until we reach a non-expanded span.
72101 // We also stop at the function body level because no line stepping can occur
@@ -75,20 +104,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
75104 span = rustc_span:: hygiene:: walk_chain ( span, self . mir . span . ctxt ( ) ) ;
76105 }
77106
78- // FIXME(eddyb) this should never be `None`.
79- let mut dbg_scope = scope. dbg_scope ?;
80-
81- // DILocations inherit source file name from the parent DIScope. Due to macro expansions
82- // it may so happen that the current span belongs to a different file than the DIScope
83- // corresponding to span's containing source scope. If so, we need to create a DIScope
84- // "extension" into that file.
85- let pos = span. lo ( ) ;
86- if pos < scope. file_start_pos || pos >= scope. file_end_pos {
87- let sm = self . cx . sess ( ) . source_map ( ) ;
88- dbg_scope = self . cx . extend_scope_to_file ( dbg_scope, & sm. lookup_char_pos ( pos) . file ) ;
89- }
90-
91- Some ( ( dbg_scope, span) )
107+ span
92108 }
93109
94110 /// Apply debuginfo and/or name, after creating the `alloca` for a local,
@@ -130,11 +146,17 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
130146 let name = kw:: Invalid ;
131147 let decl = & self . mir . local_decls [ local] ;
132148 let dbg_var = if full_debug_info {
133- self . dbg_scope_and_span ( decl . source_info ) . map ( |( scope , span ) | {
149+ self . debug_context . as_ref ( ) . map ( |debug_context | {
134150 // FIXME(eddyb) is this `+ 1` needed at all?
135151 let kind = VariableKind :: ArgumentVariable ( arg_index + 1 ) ;
136152
137- self . cx . create_dbg_var ( name, self . monomorphize ( & decl. ty ) , scope, kind, span)
153+ let arg_ty = self . monomorphize ( & decl. ty ) ;
154+
155+ let span = self . adjust_span_for_debugging ( decl. source_info . span ) ;
156+ let scope = & debug_context. scopes [ decl. source_info . scope ] ;
157+ let dbg_scope = scope. adjust_dbg_scope_for_span ( self . cx , span) ;
158+
159+ self . cx . create_dbg_var ( name, arg_ty, dbg_scope, kind, span)
138160 } )
139161 } else {
140162 None
@@ -288,9 +310,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
288310
289311 let mut per_local = IndexVec :: from_elem ( vec ! [ ] , & self . mir . local_decls ) ;
290312 for var in & self . mir . var_debug_info {
291- let scope_and_span =
292- if full_debug_info { self . dbg_scope_and_span ( var. source_info ) } else { None } ;
293- let dbg_var = scope_and_span. map ( |( scope, span) | {
313+ let dbg_scope_and_span = if full_debug_info {
314+ self . debug_context . as_ref ( ) . map ( |debug_context| {
315+ let span = self . adjust_span_for_debugging ( var. source_info . span ) ;
316+ let scope = & debug_context. scopes [ var. source_info . scope ] ;
317+ ( scope. adjust_dbg_scope_for_span ( self . cx , span) , span)
318+ } )
319+ } else {
320+ None
321+ } ;
322+ let dbg_var = dbg_scope_and_span. map ( |( dbg_scope, span) | {
294323 let place = var. place ;
295324 let var_ty = self . monomorphized_place_ty ( place. as_ref ( ) ) ;
296325 let var_kind = if self . mir . local_kind ( place. local ) == mir:: LocalKind :: Arg
@@ -306,7 +335,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
306335 } else {
307336 VariableKind :: LocalVariable
308337 } ;
309- self . cx . create_dbg_var ( var. name , var_ty, scope , var_kind, span)
338+ self . cx . create_dbg_var ( var. name , var_ty, dbg_scope , var_kind, span)
310339 } ) ;
311340
312341 per_local[ var. place . local ] . push ( PerLocalVarDebugInfo {
0 commit comments