@@ -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
@@ -389,26 +402,11 @@ fn build_dyn_type_di_node<'ll, 'tcx>(
389402}
390403
391404/// 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.
408405fn build_slice_type_di_node < ' ll , ' tcx > (
409406 cx : & CodegenCx < ' ll , ' tcx > ,
410407 slice_type : Ty < ' tcx > ,
411408 unique_type_id : UniqueTypeId < ' tcx > ,
409+ span : Span ,
412410) -> DINodeCreationResult < ' ll > {
413411 let element_type = match slice_type. kind ( ) {
414412 ty:: Slice ( element_type) => * element_type,
@@ -423,7 +421,20 @@ fn build_slice_type_di_node<'ll, 'tcx>(
423421
424422 let element_type_di_node = type_di_node ( cx, element_type) ;
425423 return_if_di_node_created_in_meantime ! ( cx, unique_type_id) ;
426- DINodeCreationResult { di_node : element_type_di_node, already_stored_in_typemap : false }
424+ let ( size, align) = cx. spanned_size_and_align_of ( slice_type, span) ;
425+ let subrange = unsafe { llvm:: LLVMDIBuilderGetOrCreateSubrange ( DIB ( cx) , 0 , -1 ) } ;
426+ let subscripts = & [ subrange] ;
427+ let di_node = unsafe {
428+ llvm:: LLVMDIBuilderCreateArrayType (
429+ DIB ( cx) ,
430+ size. bits ( ) ,
431+ align. bits ( ) as u32 ,
432+ element_type_di_node,
433+ subscripts. as_ptr ( ) ,
434+ subscripts. len ( ) as c_uint ,
435+ )
436+ } ;
437+ DINodeCreationResult { di_node, already_stored_in_typemap : false }
427438}
428439
429440/// Get the debuginfo node for the given type.
@@ -454,7 +465,7 @@ pub(crate) fn spanned_type_di_node<'ll, 'tcx>(
454465 }
455466 ty:: Tuple ( elements) if elements. is_empty ( ) => build_basic_type_di_node ( cx, t) ,
456467 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) ,
468+ ty:: Slice ( _) | ty:: Str => build_slice_type_di_node ( cx, t, unique_type_id, span ) ,
458469 ty:: Dynamic ( ..) => build_dyn_type_di_node ( cx, t, unique_type_id) ,
459470 ty:: Foreign ( ..) => build_foreign_type_di_node ( cx, t, unique_type_id) ,
460471 ty:: RawPtr ( pointee_type, _) | ty:: Ref ( _, pointee_type, _) => {
0 commit comments