11// See doc.rs for documentation.
22mod doc;
33
4- use rustc_codegen_ssa:: debuginfo:: VariableAccess :: * ;
5- use rustc_codegen_ssa:: debuginfo:: VariableKind :: * ;
4+ use rustc_codegen_ssa:: mir:: debuginfo:: VariableKind :: * ;
65
76use self :: utils:: { DIB , span_start, create_DIArray, is_node_local_to_unit} ;
87use self :: namespace:: mangled_name_of_instance;
@@ -11,7 +10,7 @@ use self::metadata::{type_metadata, file_metadata, TypeMap};
1110use self :: source_loc:: InternalDebugLocation :: { self , UnknownLocation } ;
1211
1312use 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 ,
1514 DISPFlags , DILexicalBlock } ;
1615use rustc:: hir:: CodegenFnAttrFlags ;
1716use rustc:: hir:: def_id:: { DefId , CrateNum , LOCAL_CRATE } ;
@@ -27,17 +26,19 @@ use rustc::session::config::{self, DebugInfo};
2726use rustc:: util:: nodemap:: { DefIdMap , FxHashMap , FxHashSet } ;
2827use rustc_data_structures:: small_c_str:: SmallCStr ;
2928use 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 } ;
3232
3333use libc:: c_uint;
3434use std:: cell:: RefCell ;
3535use std:: ffi:: { CStr , CString } ;
3636
37- use syntax_pos:: { self , Span , Pos } ;
37+ use smallvec:: SmallVec ;
38+ use syntax_pos:: { self , BytePos , Span , Pos } ;
3839use syntax:: ast;
3940use syntax:: symbol:: Symbol ;
40- use rustc:: ty:: layout:: { self , LayoutOf , HasTyCtxt } ;
41+ use rustc:: ty:: layout:: { self , LayoutOf , HasTyCtxt , Size } ;
4142use rustc_codegen_ssa:: traits:: * ;
4243
4344pub mod gdb;
@@ -47,7 +48,7 @@ pub mod metadata;
4748mod create_scope_map;
4849mod source_loc;
4950
50- pub use self :: create_scope_map:: { create_mir_scopes } ;
51+ pub use self :: create_scope_map:: compute_mir_scopes ;
5152pub use self :: metadata:: create_global_var_metadata;
5253pub use self :: metadata:: extend_scope_to_file;
5354pub use self :: source_loc:: set_source_location;
@@ -148,21 +149,23 @@ pub fn finalize(cx: &CodegenCx<'_, '_>) {
148149impl DebugInfoBuilderMethods < ' tcx > for Builder < ' a , ' ll , ' tcx > {
149150 fn declare_local (
150151 & mut self ,
151- dbg_context : & FunctionDebugContext < & ' ll DISubprogram > ,
152+ dbg_context : & FunctionDebugContext < & ' ll DIScope > ,
152153 variable_name : ast:: Name ,
153154 variable_type : Ty < ' tcx > ,
154155 scope_metadata : & ' ll DIScope ,
155- variable_access : VariableAccess < ' _ , & ' ll Value > ,
156+ variable_alloca : Self :: Value ,
157+ direct_offset : Size ,
158+ indirect_offsets : & [ Size ] ,
156159 variable_kind : VariableKind ,
157160 span : Span ,
158161 ) {
159- assert ! ( !dbg_context. get_ref ( span ) . source_locations_enabled) ;
162+ assert ! ( !dbg_context. source_locations_enabled) ;
160163 let cx = self . cx ( ) ;
161164
162165 let file = span_start ( cx, span) . file ;
163166 let file_metadata = file_metadata ( cx,
164167 & file. name ,
165- dbg_context. get_ref ( span ) . defining_crate ) ;
168+ dbg_context. defining_crate ) ;
166169
167170 let loc = span_start ( cx, span) ;
168171 let type_metadata = type_metadata ( cx, variable_type, span) ;
@@ -173,49 +176,61 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
173176 } ;
174177 let align = cx. align_of ( variable_type) ;
175178
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 ) ;
211193 }
212194 }
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 ) ;
213228 }
214229
215230 fn set_source_location (
216231 & 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 ,
219234 span : Span ,
220235 ) {
221236 set_source_location ( debug_context, & self , scope, span)
@@ -224,7 +239,7 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
224239 gdb:: insert_reference_to_gdb_debug_scripts_section_global ( self )
225240 }
226241
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 ) {
228243 // Avoid wasting time if LLVM value names aren't even enabled.
229244 if self . sess ( ) . fewer_names ( ) {
230245 return ;
@@ -254,7 +269,7 @@ impl DebugInfoBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
254269 Err ( _) => return ,
255270 }
256271
257- let cname = CString :: new ( name. to_string ( ) ) . unwrap ( ) ;
272+ let cname = SmallCStr :: new ( name) ;
258273 unsafe {
259274 llvm:: LLVMSetValueName ( value, cname. as_ptr ( ) ) ;
260275 }
@@ -268,14 +283,14 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
268283 sig : ty:: FnSig < ' tcx > ,
269284 llfn : & ' ll Value ,
270285 mir : & mir:: Body < ' _ > ,
271- ) -> FunctionDebugContext < & ' ll DISubprogram > {
286+ ) -> Option < FunctionDebugContext < & ' ll DIScope > > {
272287 if self . sess ( ) . opts . debuginfo == DebugInfo :: None {
273- return FunctionDebugContext :: DebugInfoDisabled ;
288+ return None ;
274289 }
275290
276291 if let InstanceDef :: Item ( def_id) = instance. def {
277292 if self . tcx ( ) . codegen_fn_attrs ( def_id) . flags . contains ( CodegenFnAttrFlags :: NO_DEBUG ) {
278- return FunctionDebugContext :: FunctionWithoutDebugInfo ;
293+ return None ;
279294 }
280295 }
281296
@@ -284,7 +299,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
284299 // This can be the case for functions inlined from another crate
285300 if span. is_dummy ( ) {
286301 // FIXME(simulacrum): Probably can't happen; remove.
287- return FunctionDebugContext :: FunctionWithoutDebugInfo ;
302+ return None ;
288303 }
289304
290305 let def_id = instance. def_id ( ) ;
@@ -357,14 +372,23 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
357372 None )
358373 } ;
359374
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 ) ,
363384 source_locations_enabled : false ,
364385 defining_crate : def_id. krate ,
365386 } ;
366387
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) ;
368392
369393 fn get_function_signature < ' ll , ' tcx > (
370394 cx : & CodegenCx < ' ll , ' tcx > ,
@@ -549,14 +573,6 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
549573 metadata:: create_vtable_metadata ( self , ty, vtable)
550574 }
551575
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-
560576 fn extend_scope_to_file (
561577 & self ,
562578 scope_metadata : & ' ll DIScope ,
@@ -569,13 +585,4 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
569585 fn debuginfo_finalize ( & self ) {
570586 finalize ( self )
571587 }
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- }
581588}
0 commit comments