@@ -3,21 +3,26 @@ use super::utils::DIB;
3
3
use rustc_codegen_ssa:: mir:: debuginfo:: { DebugScope , FunctionDebugContext } ;
4
4
use rustc_codegen_ssa:: traits:: * ;
5
5
6
+ use crate :: abi:: FnAbi ;
6
7
use crate :: common:: CodegenCx ;
7
8
use crate :: llvm;
8
- use crate :: llvm:: debuginfo:: { DIScope , DISubprogram } ;
9
+ use crate :: llvm:: debuginfo:: { DILocation , DIScope } ;
9
10
use rustc_middle:: mir:: { Body , SourceScope } ;
11
+ use rustc_middle:: ty:: layout:: FnAbiExt ;
12
+ use rustc_middle:: ty:: { self , Instance } ;
10
13
use rustc_session:: config:: DebugInfo ;
11
14
12
15
use rustc_index:: bit_set:: BitSet ;
13
16
use rustc_index:: vec:: Idx ;
14
17
15
18
/// Produces DIScope DIEs for each MIR Scope which has variables defined in it.
19
+ // FIXME(eddyb) almost all of this should be in `rustc_codegen_ssa::mir::debuginfo`.
16
20
pub fn compute_mir_scopes (
17
- cx : & CodegenCx < ' ll , ' _ > ,
18
- mir : & Body < ' _ > ,
19
- fn_metadata : & ' ll DISubprogram ,
20
- debug_context : & mut FunctionDebugContext < & ' ll DIScope > ,
21
+ cx : & CodegenCx < ' ll , ' tcx > ,
22
+ instance : Instance < ' tcx > ,
23
+ mir : & Body < ' tcx > ,
24
+ fn_dbg_scope : & ' ll DIScope ,
25
+ debug_context : & mut FunctionDebugContext < & ' ll DIScope , & ' ll DILocation > ,
21
26
) {
22
27
// Find all the scopes with variables defined in them.
23
28
let mut has_variables = BitSet :: new_empty ( mir. source_scopes . len ( ) ) ;
@@ -37,58 +42,82 @@ pub fn compute_mir_scopes(
37
42
// Instantiate all scopes.
38
43
for idx in 0 ..mir. source_scopes . len ( ) {
39
44
let scope = SourceScope :: new ( idx) ;
40
- make_mir_scope ( cx, & mir, fn_metadata , & has_variables, debug_context, scope) ;
45
+ make_mir_scope ( cx, instance , & mir, fn_dbg_scope , & has_variables, debug_context, scope) ;
41
46
}
42
47
}
43
48
44
49
fn make_mir_scope (
45
- cx : & CodegenCx < ' ll , ' _ > ,
46
- mir : & Body < ' _ > ,
47
- fn_metadata : & ' ll DISubprogram ,
50
+ cx : & CodegenCx < ' ll , ' tcx > ,
51
+ instance : Instance < ' tcx > ,
52
+ mir : & Body < ' tcx > ,
53
+ fn_dbg_scope : & ' ll DIScope ,
48
54
has_variables : & BitSet < SourceScope > ,
49
- debug_context : & mut FunctionDebugContext < & ' ll DISubprogram > ,
55
+ debug_context : & mut FunctionDebugContext < & ' ll DIScope , & ' ll DILocation > ,
50
56
scope : SourceScope ,
51
57
) {
52
- if debug_context. scopes [ scope] . is_valid ( ) {
58
+ if debug_context. scopes [ scope] . dbg_scope . is_some ( ) {
53
59
return ;
54
60
}
55
61
56
62
let scope_data = & mir. source_scopes [ scope] ;
57
63
let parent_scope = if let Some ( parent) = scope_data. parent_scope {
58
- make_mir_scope ( cx, mir, fn_metadata , has_variables, debug_context, parent) ;
64
+ make_mir_scope ( cx, instance , mir, fn_dbg_scope , has_variables, debug_context, parent) ;
59
65
debug_context. scopes [ parent]
60
66
} else {
61
67
// The root is the function itself.
62
68
let loc = cx. lookup_debug_loc ( mir. span . lo ( ) ) ;
63
69
debug_context. scopes [ scope] = DebugScope {
64
- scope_metadata : Some ( fn_metadata) ,
70
+ dbg_scope : Some ( fn_dbg_scope) ,
71
+ inlined_at : None ,
65
72
file_start_pos : loc. file . start_pos ,
66
73
file_end_pos : loc. file . end_pos ,
67
74
} ;
68
75
return ;
69
76
} ;
70
77
71
- if !has_variables. contains ( scope) {
72
- // Do not create a DIScope if there are no variables
73
- // defined in this MIR Scope , to avoid debuginfo bloat.
78
+ if !has_variables. contains ( scope) && scope_data . inlined . is_none ( ) {
79
+ // Do not create a DIScope if there are no variables defined in this
80
+ // MIR `SourceScope`, and it's not `inlined` , to avoid debuginfo bloat.
74
81
debug_context. scopes [ scope] = parent_scope;
75
82
return ;
76
83
}
77
84
78
85
let loc = cx. lookup_debug_loc ( scope_data. span . lo ( ) ) ;
79
- let file_metadata = file_metadata ( cx, & loc. file , debug_context . defining_crate ) ;
86
+ let file_metadata = file_metadata ( cx, & loc. file ) ;
80
87
81
- let scope_metadata = unsafe {
82
- Some ( llvm:: LLVMRustDIBuilderCreateLexicalBlock (
83
- DIB ( cx) ,
84
- parent_scope. scope_metadata . unwrap ( ) ,
85
- file_metadata,
86
- loc. line . unwrap_or ( UNKNOWN_LINE_NUMBER ) ,
87
- loc. col . unwrap_or ( UNKNOWN_COLUMN_NUMBER ) ,
88
- ) )
88
+ let dbg_scope = match scope_data. inlined {
89
+ Some ( ( callee, _) ) => {
90
+ // FIXME(eddyb) this would be `self.monomorphize(&callee)`
91
+ // if this is moved to `rustc_codegen_ssa::mir::debuginfo`.
92
+ let callee = cx. tcx . subst_and_normalize_erasing_regions (
93
+ instance. substs ,
94
+ ty:: ParamEnv :: reveal_all ( ) ,
95
+ & callee,
96
+ ) ;
97
+ let callee_fn_abi = FnAbi :: of_instance ( cx, callee, & [ ] ) ;
98
+ cx. dbg_scope_fn ( callee, & callee_fn_abi, None )
99
+ }
100
+ None => unsafe {
101
+ llvm:: LLVMRustDIBuilderCreateLexicalBlock (
102
+ DIB ( cx) ,
103
+ parent_scope. dbg_scope . unwrap ( ) ,
104
+ file_metadata,
105
+ loc. line . unwrap_or ( UNKNOWN_LINE_NUMBER ) ,
106
+ loc. col . unwrap_or ( UNKNOWN_COLUMN_NUMBER ) ,
107
+ )
108
+ } ,
89
109
} ;
110
+
111
+ let inlined_at = scope_data. inlined . map ( |( _, callsite_span) | {
112
+ // FIXME(eddyb) this doesn't account for the macro-related
113
+ // `Span` fixups that `rustc_codegen_ssa::mir::debuginfo` does.
114
+ let callsite_scope = parent_scope. adjust_dbg_scope_for_span ( cx, callsite_span) ;
115
+ cx. dbg_loc ( callsite_scope, parent_scope. inlined_at , callsite_span)
116
+ } ) ;
117
+
90
118
debug_context. scopes [ scope] = DebugScope {
91
- scope_metadata,
119
+ dbg_scope : Some ( dbg_scope) ,
120
+ inlined_at : inlined_at. or ( parent_scope. inlined_at ) ,
92
121
file_start_pos : loc. file . start_pos ,
93
122
file_end_pos : loc. file . end_pos ,
94
123
} ;
0 commit comments