@@ -12,8 +12,8 @@ use super::operand::OperandValue;
12
12
use super :: place:: PlaceRef ;
13
13
use super :: { FunctionCx , LocalRef } ;
14
14
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 > > ,
17
17
}
18
18
19
19
#[ derive( Copy , Clone ) ]
@@ -36,15 +36,42 @@ pub struct PerLocalVarDebugInfo<'tcx, D> {
36
36
}
37
37
38
38
#[ derive( Clone , Copy , Debug ) ]
39
- pub struct DebugScope < D > {
39
+ pub struct DebugScope < S , L > {
40
40
// 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
+
42
46
// Start and end offsets of the file to which this DIScope belongs.
43
47
// These are used to quickly determine whether some span refers to the same file.
44
48
pub file_start_pos : BytePos ,
45
49
pub file_end_pos : BytePos ,
46
50
}
47
51
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
+
48
75
impl < ' a , ' tcx , Bx : BuilderMethods < ' a , ' tcx > > FunctionCx < ' a , ' tcx , Bx > {
49
76
pub fn set_debug_loc ( & self , bx : & mut Bx , source_info : mir:: SourceInfo ) {
50
77
bx. set_span ( source_info. span ) ;
@@ -54,19 +81,21 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
54
81
}
55
82
56
83
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) )
59
88
}
60
89
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 {
62
94
// 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
+ }
65
98
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 ;
70
99
if span. from_expansion ( ) && !self . cx . sess ( ) . opts . debugging_opts . debug_macros {
71
100
// Walk up the macro expansion chain until we reach a non-expanded span.
72
101
// 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> {
75
104
span = rustc_span:: hygiene:: walk_chain ( span, self . mir . span . ctxt ( ) ) ;
76
105
}
77
106
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
92
108
}
93
109
94
110
/// 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> {
130
146
let name = kw:: Invalid ;
131
147
let decl = & self . mir . local_decls [ local] ;
132
148
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 | {
134
150
// FIXME(eddyb) is this `+ 1` needed at all?
135
151
let kind = VariableKind :: ArgumentVariable ( arg_index + 1 ) ;
136
152
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)
138
160
} )
139
161
} else {
140
162
None
@@ -288,9 +310,16 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
288
310
289
311
let mut per_local = IndexVec :: from_elem ( vec ! [ ] , & self . mir . local_decls ) ;
290
312
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) | {
294
323
let place = var. place ;
295
324
let var_ty = self . monomorphized_place_ty ( place. as_ref ( ) ) ;
296
325
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> {
306
335
} else {
307
336
VariableKind :: LocalVariable
308
337
} ;
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)
310
339
} ) ;
311
340
312
341
per_local[ var. place . local ] . push ( PerLocalVarDebugInfo {
0 commit comments