@@ -152,7 +152,20 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
152152 cx. size_and_align_of( Ty :: new_mut_ptr( cx. tcx, pointee_type) )
153153 ) ;
154154
155- let pointee_type_di_node = type_di_node ( cx, pointee_type) ;
155+ let pointee_type_di_node = match pointee_type. kind ( ) {
156+ // `&[T]` will look like `{ data_ptr: *const T, length: usize }`
157+ ty:: Slice ( element_type) => type_di_node ( cx, * element_type) ,
158+ // `&str` will look like `{ data_ptr: *const u8, length: usize }`
159+ ty:: Str => type_di_node ( cx, cx. tcx . types . u8 ) ,
160+
161+ // `&dyn K` will look like `{ pointer: _, vtable: _}`
162+ // any Adt `Foo` containing an unsized type (eg `&[_]` or `&dyn _`)
163+ // will look like `{ data_ptr: *const Foo, length: usize }`
164+ // and thin pointers `&Foo` will just look like `*const Foo`.
165+ //
166+ // in all those cases, we just use the pointee_type
167+ _ => type_di_node ( cx, pointee_type) ,
168+ } ;
156169
157170 return_if_di_node_created_in_meantime ! ( cx, unique_type_id) ;
158171
@@ -194,23 +207,7 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
194207 DIFlags :: FlagZero ,
195208 ) ,
196209 |cx, owner| {
197- // FIXME: If this wide pointer is a `Box` then we don't want to use its
198- // type layout and instead use the layout of the raw pointer inside
199- // of it.
200- // The proper way to handle this is to not treat Box as a pointer
201- // at all and instead emit regular struct debuginfo for it. We just
202- // need to make sure that we don't break existing debuginfo consumers
203- // by doing that (at least not without a warning period).
204- let layout_type = if ptr_type. is_box ( ) {
205- // The assertion at the start of this function ensures we have a ZST
206- // allocator. We'll make debuginfo "skip" all ZST allocators, not just the
207- // default allocator.
208- Ty :: new_mut_ptr ( cx. tcx , pointee_type)
209- } else {
210- ptr_type
211- } ;
212-
213- let layout = cx. layout_of ( layout_type) ;
210+ let layout = cx. layout_of ( ptr_type) ;
214211 let addr_field = layout. field ( cx, WIDE_PTR_ADDR ) ;
215212 let extra_field = layout. field ( cx, WIDE_PTR_EXTRA ) ;
216213
@@ -389,26 +386,11 @@ fn build_dyn_type_di_node<'ll, 'tcx>(
389386}
390387
391388/// Create debuginfo for `[T]` and `str`. These are unsized.
392- ///
393- /// NOTE: We currently emit just emit the debuginfo for the element type here
394- /// (i.e. `T` for slices and `u8` for `str`), so that we end up with
395- /// `*const T` for the `data_ptr` field of the corresponding wide-pointer
396- /// debuginfo of `&[T]`.
397- ///
398- /// It would be preferable and more accurate if we emitted a DIArray of T
399- /// without an upper bound instead. That is, LLVM already supports emitting
400- /// debuginfo of arrays of unknown size. But GDB currently seems to end up
401- /// in an infinite loop when confronted with such a type.
402- ///
403- /// As a side effect of the current encoding every instance of a type like
404- /// `struct Foo { unsized_field: [u8] }` will look like
405- /// `struct Foo { unsized_field: u8 }` in debuginfo. If the length of the
406- /// slice is zero, then accessing `unsized_field` in the debugger would
407- /// result in an out-of-bounds access.
408389fn build_slice_type_di_node < ' ll , ' tcx > (
409390 cx : & CodegenCx < ' ll , ' tcx > ,
410391 slice_type : Ty < ' tcx > ,
411392 unique_type_id : UniqueTypeId < ' tcx > ,
393+ span : Span ,
412394) -> DINodeCreationResult < ' ll > {
413395 let element_type = match slice_type. kind ( ) {
414396 ty:: Slice ( element_type) => * element_type,
@@ -423,7 +405,20 @@ fn build_slice_type_di_node<'ll, 'tcx>(
423405
424406 let element_type_di_node = type_di_node ( cx, element_type) ;
425407 return_if_di_node_created_in_meantime ! ( cx, unique_type_id) ;
426- DINodeCreationResult { di_node : element_type_di_node, already_stored_in_typemap : false }
408+ let ( size, align) = cx. spanned_size_and_align_of ( slice_type, span) ;
409+ let subrange = unsafe { llvm:: LLVMDIBuilderGetOrCreateSubrange ( DIB ( cx) , 0 , -1 ) } ;
410+ let subscripts = & [ subrange] ;
411+ let di_node = unsafe {
412+ llvm:: LLVMDIBuilderCreateArrayType (
413+ DIB ( cx) ,
414+ size. bits ( ) ,
415+ align. bits ( ) as u32 ,
416+ element_type_di_node,
417+ subscripts. as_ptr ( ) ,
418+ subscripts. len ( ) as c_uint ,
419+ )
420+ } ;
421+ DINodeCreationResult { di_node, already_stored_in_typemap : false }
427422}
428423
429424/// Get the debuginfo node for the given type.
@@ -454,21 +449,12 @@ pub(crate) fn spanned_type_di_node<'ll, 'tcx>(
454449 }
455450 ty:: Tuple ( elements) if elements. is_empty ( ) => build_basic_type_di_node ( cx, t) ,
456451 ty:: Array ( ..) => build_fixed_size_array_di_node ( cx, unique_type_id, t, span) ,
457- ty:: Slice ( _) | ty:: Str => build_slice_type_di_node ( cx, t, unique_type_id) ,
452+ ty:: Slice ( _) | ty:: Str => build_slice_type_di_node ( cx, t, unique_type_id, span ) ,
458453 ty:: Dynamic ( ..) => build_dyn_type_di_node ( cx, t, unique_type_id) ,
459454 ty:: Foreign ( ..) => build_foreign_type_di_node ( cx, t, unique_type_id) ,
460455 ty:: RawPtr ( pointee_type, _) | ty:: Ref ( _, pointee_type, _) => {
461456 build_pointer_or_reference_di_node ( cx, t, pointee_type, unique_type_id)
462457 }
463- // Some `Box` are newtyped pointers, make debuginfo aware of that.
464- // Only works if the allocator argument is a 1-ZST and hence irrelevant for layout
465- // (or if there is no allocator argument).
466- ty:: Adt ( def, args)
467- if def. is_box ( )
468- && args. get ( 1 ) . is_none_or ( |arg| cx. layout_of ( arg. expect_ty ( ) ) . is_1zst ( ) ) =>
469- {
470- build_pointer_or_reference_di_node ( cx, t, t. expect_boxed_ty ( ) , unique_type_id)
471- }
472458 ty:: FnDef ( ..) | ty:: FnPtr ( ..) => build_subroutine_type_di_node ( cx, unique_type_id) ,
473459 ty:: Closure ( ..) => build_closure_env_di_node ( cx, unique_type_id) ,
474460 ty:: CoroutineClosure ( ..) => build_closure_env_di_node ( cx, unique_type_id) ,
0 commit comments