1
1
// See doc.rs for documentation.
2
2
mod doc;
3
3
4
- use rustc_codegen_ssa:: debuginfo:: VariableAccess :: * ;
5
- use rustc_codegen_ssa:: debuginfo:: VariableKind :: * ;
4
+ use rustc_codegen_ssa:: mir:: debuginfo:: VariableKind :: * ;
6
5
7
6
use self :: utils:: { DIB , span_start, create_DIArray, is_node_local_to_unit} ;
8
7
use self :: namespace:: mangled_name_of_instance;
@@ -11,7 +10,7 @@ use self::metadata::{type_metadata, file_metadata, TypeMap};
11
10
use self :: source_loc:: InternalDebugLocation :: { self , UnknownLocation } ;
12
11
13
12
use crate :: llvm;
14
- use crate :: llvm:: debuginfo:: { DIFile , DIType , DIScope , DIBuilder , DISubprogram , DIArray , DIFlags ,
13
+ use crate :: llvm:: debuginfo:: { DIFile , DIType , DIScope , DIBuilder , DIArray , DIFlags ,
15
14
DISPFlags , DILexicalBlock } ;
16
15
use rustc:: hir:: CodegenFnAttrFlags ;
17
16
use rustc:: hir:: def_id:: { DefId , CrateNum , LOCAL_CRATE } ;
@@ -27,17 +26,19 @@ use rustc::session::config::{self, DebugInfo};
27
26
use rustc:: util:: nodemap:: { DefIdMap , FxHashMap , FxHashSet } ;
28
27
use rustc_data_structures:: small_c_str:: SmallCStr ;
29
28
use rustc_index:: vec:: IndexVec ;
30
- use rustc_codegen_ssa:: debuginfo:: { FunctionDebugContext , MirDebugScope , VariableAccess ,
31
- VariableKind , FunctionDebugContextData , type_names} ;
29
+ use rustc_codegen_ssa:: debuginfo:: type_names;
30
+ use rustc_codegen_ssa:: mir:: debuginfo:: { FunctionDebugContext , DebugScope ,
31
+ VariableKind } ;
32
32
33
33
use libc:: c_uint;
34
34
use std:: cell:: RefCell ;
35
35
use std:: ffi:: { CStr , CString } ;
36
36
37
- use syntax_pos:: { self , Span , Pos } ;
37
+ use smallvec:: SmallVec ;
38
+ use syntax_pos:: { self , BytePos , Span , Pos } ;
38
39
use syntax:: ast;
39
40
use syntax:: symbol:: Symbol ;
40
- use rustc:: ty:: layout:: { self , LayoutOf , HasTyCtxt } ;
41
+ use rustc:: ty:: layout:: { self , LayoutOf , HasTyCtxt , Size } ;
41
42
use rustc_codegen_ssa:: traits:: * ;
42
43
43
44
pub mod gdb;
@@ -47,7 +48,7 @@ pub mod metadata;
47
48
mod create_scope_map;
48
49
mod source_loc;
49
50
50
- pub use self :: create_scope_map:: { create_mir_scopes } ;
51
+ pub use self :: create_scope_map:: compute_mir_scopes ;
51
52
pub use self :: metadata:: create_global_var_metadata;
52
53
pub use self :: metadata:: extend_scope_to_file;
53
54
pub use self :: source_loc:: set_source_location;
@@ -148,21 +149,23 @@ pub fn finalize(cx: &CodegenCx<'_, '_>) {
148
149
impl DebugInfoBuilderMethods < ' tcx > for Builder < ' a , ' ll , ' tcx > {
149
150
fn declare_local (
150
151
& mut self ,
151
- dbg_context : & FunctionDebugContext < & ' ll DISubprogram > ,
152
+ dbg_context : & FunctionDebugContext < & ' ll DIScope > ,
152
153
variable_name : ast:: Name ,
153
154
variable_type : Ty < ' tcx > ,
154
155
scope_metadata : & ' ll DIScope ,
155
- variable_access : VariableAccess < ' _ , & ' ll Value > ,
156
+ variable_alloca : Self :: Value ,
157
+ direct_offset : Size ,
158
+ indirect_offsets : & [ Size ] ,
156
159
variable_kind : VariableKind ,
157
160
span : Span ,
158
161
) {
159
- assert ! ( !dbg_context. get_ref ( span ) . source_locations_enabled) ;
162
+ assert ! ( !dbg_context. source_locations_enabled) ;
160
163
let cx = self . cx ( ) ;
161
164
162
165
let file = span_start ( cx, span) . file ;
163
166
let file_metadata = file_metadata ( cx,
164
167
& file. name ,
165
- dbg_context. get_ref ( span ) . defining_crate ) ;
168
+ dbg_context. defining_crate ) ;
166
169
167
170
let loc = span_start ( cx, span) ;
168
171
let type_metadata = type_metadata ( cx, variable_type, span) ;
@@ -173,49 +176,61 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
173
176
} ;
174
177
let align = cx. align_of ( variable_type) ;
175
178
176
- let name = SmallCStr :: new ( & variable_name. as_str ( ) ) ;
177
- match ( variable_access, & [ ] [ ..] ) {
178
- ( DirectVariable { alloca } , address_operations) |
179
- ( IndirectVariable { alloca, address_operations} , _) => {
180
- let metadata = unsafe {
181
- llvm:: LLVMRustDIBuilderCreateVariable (
182
- DIB ( cx) ,
183
- dwarf_tag,
184
- scope_metadata,
185
- name. as_ptr ( ) ,
186
- file_metadata,
187
- loc. line as c_uint ,
188
- type_metadata,
189
- cx. sess ( ) . opts . optimize != config:: OptLevel :: No ,
190
- DIFlags :: FlagZero ,
191
- argument_index,
192
- align. bytes ( ) as u32 ,
193
- )
194
- } ;
195
- source_loc:: set_debug_location ( self ,
196
- InternalDebugLocation :: new ( scope_metadata, loc. line , loc. col . to_usize ( ) ) ) ;
197
- unsafe {
198
- let debug_loc = llvm:: LLVMGetCurrentDebugLocation ( self . llbuilder ) ;
199
- let instr = llvm:: LLVMRustDIBuilderInsertDeclareAtEnd (
200
- DIB ( cx) ,
201
- alloca,
202
- metadata,
203
- address_operations. as_ptr ( ) ,
204
- address_operations. len ( ) as c_uint ,
205
- debug_loc,
206
- self . llbb ( ) ) ;
207
-
208
- llvm:: LLVMSetInstDebugLocation ( self . llbuilder , instr) ;
209
- }
210
- source_loc:: set_debug_location ( self , UnknownLocation ) ;
179
+ // Convert the direct and indirect offsets to address ops.
180
+ let op_deref = || unsafe { llvm:: LLVMRustDIBuilderCreateOpDeref ( ) } ;
181
+ let op_plus_uconst = || unsafe { llvm:: LLVMRustDIBuilderCreateOpPlusUconst ( ) } ;
182
+ let mut addr_ops = SmallVec :: < [ _ ; 8 ] > :: new ( ) ;
183
+
184
+ if direct_offset. bytes ( ) > 0 {
185
+ addr_ops. push ( op_plus_uconst ( ) ) ;
186
+ addr_ops. push ( direct_offset. bytes ( ) as i64 ) ;
187
+ }
188
+ for & offset in indirect_offsets {
189
+ addr_ops. push ( op_deref ( ) ) ;
190
+ if offset. bytes ( ) > 0 {
191
+ addr_ops. push ( op_plus_uconst ( ) ) ;
192
+ addr_ops. push ( offset. bytes ( ) as i64 ) ;
211
193
}
212
194
}
195
+
196
+ let name = SmallCStr :: new ( & variable_name. as_str ( ) ) ;
197
+ let metadata = unsafe {
198
+ llvm:: LLVMRustDIBuilderCreateVariable (
199
+ DIB ( cx) ,
200
+ dwarf_tag,
201
+ scope_metadata,
202
+ name. as_ptr ( ) ,
203
+ file_metadata,
204
+ loc. line as c_uint ,
205
+ type_metadata,
206
+ cx. sess ( ) . opts . optimize != config:: OptLevel :: No ,
207
+ DIFlags :: FlagZero ,
208
+ argument_index,
209
+ align. bytes ( ) as u32 ,
210
+ )
211
+ } ;
212
+ source_loc:: set_debug_location ( self ,
213
+ InternalDebugLocation :: new ( scope_metadata, loc. line , loc. col . to_usize ( ) ) ) ;
214
+ unsafe {
215
+ let debug_loc = llvm:: LLVMGetCurrentDebugLocation ( self . llbuilder ) ;
216
+ let instr = llvm:: LLVMRustDIBuilderInsertDeclareAtEnd (
217
+ DIB ( cx) ,
218
+ variable_alloca,
219
+ metadata,
220
+ addr_ops. as_ptr ( ) ,
221
+ addr_ops. len ( ) as c_uint ,
222
+ debug_loc,
223
+ self . llbb ( ) ) ;
224
+
225
+ llvm:: LLVMSetInstDebugLocation ( self . llbuilder , instr) ;
226
+ }
227
+ source_loc:: set_debug_location ( self , UnknownLocation ) ;
213
228
}
214
229
215
230
fn set_source_location (
216
231
& mut self ,
217
- debug_context : & mut FunctionDebugContext < & ' ll DISubprogram > ,
218
- scope : Option < & ' ll DIScope > ,
232
+ debug_context : & mut FunctionDebugContext < & ' ll DIScope > ,
233
+ scope : & ' ll DIScope ,
219
234
span : Span ,
220
235
) {
221
236
set_source_location ( debug_context, & self , scope, span)
@@ -224,7 +239,7 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
224
239
gdb:: insert_reference_to_gdb_debug_scripts_section_global ( self )
225
240
}
226
241
227
- fn set_var_name ( & mut self , value : & ' ll Value , name : impl ToString ) {
242
+ fn set_var_name ( & mut self , value : & ' ll Value , name : & str ) {
228
243
// Avoid wasting time if LLVM value names aren't even enabled.
229
244
if self . sess ( ) . fewer_names ( ) {
230
245
return ;
@@ -254,7 +269,7 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
254
269
Err ( _) => return ,
255
270
}
256
271
257
- let cname = CString :: new ( name. to_string ( ) ) . unwrap ( ) ;
272
+ let cname = SmallCStr :: new ( name) ;
258
273
unsafe {
259
274
llvm:: LLVMSetValueName ( value, cname. as_ptr ( ) ) ;
260
275
}
@@ -268,14 +283,14 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
268
283
sig : ty:: FnSig < ' tcx > ,
269
284
llfn : & ' ll Value ,
270
285
mir : & mir:: Body < ' _ > ,
271
- ) -> FunctionDebugContext < & ' ll DISubprogram > {
286
+ ) -> Option < FunctionDebugContext < & ' ll DIScope > > {
272
287
if self . sess ( ) . opts . debuginfo == DebugInfo :: None {
273
- return FunctionDebugContext :: DebugInfoDisabled ;
288
+ return None ;
274
289
}
275
290
276
291
if let InstanceDef :: Item ( def_id) = instance. def {
277
292
if self . tcx ( ) . codegen_fn_attrs ( def_id) . flags . contains ( CodegenFnAttrFlags :: NO_DEBUG ) {
278
- return FunctionDebugContext :: FunctionWithoutDebugInfo ;
293
+ return None ;
279
294
}
280
295
}
281
296
@@ -284,7 +299,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
284
299
// This can be the case for functions inlined from another crate
285
300
if span. is_dummy ( ) {
286
301
// FIXME(simulacrum): Probably can't happen; remove.
287
- return FunctionDebugContext :: FunctionWithoutDebugInfo ;
302
+ return None ;
288
303
}
289
304
290
305
let def_id = instance. def_id ( ) ;
@@ -357,14 +372,23 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
357
372
None )
358
373
} ;
359
374
360
- // Initialize fn debug context (including scope map and namespace map)
361
- let fn_debug_context = FunctionDebugContextData {
362
- fn_metadata,
375
+ // Initialize fn debug context (including scopes).
376
+ // FIXME(eddyb) figure out a way to not need `Option` for `scope_metadata`.
377
+ let null_scope = DebugScope {
378
+ scope_metadata : None ,
379
+ file_start_pos : BytePos ( 0 ) ,
380
+ file_end_pos : BytePos ( 0 )
381
+ } ;
382
+ let mut fn_debug_context = FunctionDebugContext {
383
+ scopes : IndexVec :: from_elem ( null_scope, & mir. source_scopes ) ,
363
384
source_locations_enabled : false ,
364
385
defining_crate : def_id. krate ,
365
386
} ;
366
387
367
- return FunctionDebugContext :: RegularContext ( fn_debug_context) ;
388
+ // Fill in all the scopes, with the information from the MIR body.
389
+ compute_mir_scopes ( self , mir, fn_metadata, & mut fn_debug_context) ;
390
+
391
+ return Some ( fn_debug_context) ;
368
392
369
393
fn get_function_signature < ' ll , ' tcx > (
370
394
cx : & CodegenCx < ' ll , ' tcx > ,
@@ -549,14 +573,6 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
549
573
metadata:: create_vtable_metadata ( self , ty, vtable)
550
574
}
551
575
552
- fn create_mir_scopes (
553
- & self ,
554
- mir : & mir:: Body < ' _ > ,
555
- debug_context : & mut FunctionDebugContext < & ' ll DISubprogram > ,
556
- ) -> IndexVec < mir:: SourceScope , MirDebugScope < & ' ll DIScope > > {
557
- create_scope_map:: create_mir_scopes ( self , mir, debug_context)
558
- }
559
-
560
576
fn extend_scope_to_file (
561
577
& self ,
562
578
scope_metadata : & ' ll DIScope ,
@@ -569,13 +585,4 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
569
585
fn debuginfo_finalize ( & self ) {
570
586
finalize ( self )
571
587
}
572
-
573
- fn debuginfo_upvar_ops_sequence ( & self , byte_offset_of_var_in_env : u64 ) -> [ i64 ; 4 ] {
574
- unsafe {
575
- [ llvm:: LLVMRustDIBuilderCreateOpDeref ( ) ,
576
- llvm:: LLVMRustDIBuilderCreateOpPlusUconst ( ) ,
577
- byte_offset_of_var_in_env as i64 ,
578
- llvm:: LLVMRustDIBuilderCreateOpDeref ( ) ]
579
- }
580
- }
581
588
}
0 commit comments