@@ -1440,32 +1440,40 @@ fn build_vtable_type_di_node<'ll, 'tcx>(
14401440) -> & ' ll DIType {
14411441 let tcx = cx. tcx ;
14421442
1443- let vtable_entries = if let Some ( poly_trait_ref) = poly_trait_ref {
1444- let trait_ref = poly_trait_ref. with_self_ty ( tcx, ty) ;
1445- let trait_ref = tcx. erase_and_anonymize_regions ( trait_ref) ;
1446-
1447- tcx. vtable_entries ( trait_ref)
1448- } else {
1449- TyCtxt :: COMMON_VTABLE_ENTRIES
1450- } ;
1451-
14521443 // All function pointers are described as opaque pointers. This could be improved in the future
14531444 // by describing them as actual function pointers.
14541445 let void_pointer_ty = Ty :: new_imm_ptr ( tcx, tcx. types . unit ) ;
14551446 let void_pointer_type_di_node = type_di_node ( cx, void_pointer_ty) ;
14561447 let usize_di_node = type_di_node ( cx, tcx. types . usize ) ;
1448+ let usize_layout = cx. layout_of ( tcx. types . usize ) ;
14571449 let pointer_layout = cx. layout_of ( void_pointer_ty) ;
14581450 let pointer_size = pointer_layout. size ;
14591451 let pointer_align = pointer_layout. align . abi ;
1460- // If `usize` is not pointer-sized and -aligned then the size and alignment computations
1461- // for the vtable as a whole would be wrong. Let's make sure this holds even on weird
1462- // platforms.
1463- assert_eq ! ( cx. size_and_align_of( tcx. types. usize ) , ( pointer_size, pointer_align) ) ;
1452+ let size_zero = Size :: from_bits ( 0 ) ;
1453+
1454+ let vtable_entry_size = |& entry| match entry {
1455+ ty:: VtblEntry :: MetadataSize | ty:: VtblEntry :: MetadataAlign => cx. size_of ( tcx. types . usize ) ,
1456+ ty:: VtblEntry :: MetadataDropInPlace
1457+ | ty:: VtblEntry :: Method ( _)
1458+ | ty:: VtblEntry :: TraitVPtr ( _) => pointer_size,
1459+ ty:: VtblEntry :: Vacant => size_zero,
1460+ } ;
1461+
1462+ let vtable_entries = if let Some ( poly_trait_ref) = poly_trait_ref {
1463+ let trait_ref = poly_trait_ref. with_self_ty ( tcx, ty) ;
1464+ let trait_ref = tcx. erase_and_anonymize_regions ( trait_ref) ;
1465+
1466+ tcx. vtable_entries ( trait_ref)
1467+ } else {
1468+ TyCtxt :: COMMON_VTABLE_ENTRIES
1469+ } ;
14641470
14651471 let vtable_type_name =
14661472 compute_debuginfo_vtable_name ( cx. tcx , ty, poly_trait_ref, VTableNameKind :: Type ) ;
14671473 let unique_type_id = UniqueTypeId :: for_vtable_ty ( tcx, ty, poly_trait_ref) ;
1468- let size = pointer_size * vtable_entries. len ( ) as u64 ;
1474+ let entries_size = vtable_entries. iter ( ) . map ( vtable_entry_size) . collect :: < Vec < _ > > ( ) ;
1475+ let size = entries_size. iter ( ) . fold ( size_zero, |a, s| a + * s) ;
1476+ let mut field_offset = size_zero;
14691477
14701478 // This gets mapped to a DW_AT_containing_type attribute which allows GDB to correlate
14711479 // the vtable to the type it is for.
@@ -1488,32 +1496,33 @@ fn build_vtable_type_di_node<'ll, 'tcx>(
14881496 . iter ( )
14891497 . enumerate ( )
14901498 . filter_map ( |( index, vtable_entry) | {
1491- let ( field_name, field_type_di_node) = match vtable_entry {
1499+ let ( field_name, layout , field_type_di_node) = match vtable_entry {
14921500 ty:: VtblEntry :: MetadataDropInPlace => {
1493- ( "drop_in_place" . to_string ( ) , void_pointer_type_di_node)
1501+ ( "drop_in_place" . to_string ( ) , pointer_layout , void_pointer_type_di_node)
14941502 }
14951503 ty:: VtblEntry :: Method ( _) => {
14961504 // Note: This code does not try to give a proper name to each method
14971505 // because their might be multiple methods with the same name
14981506 // (coming from different traits).
1499- ( format ! ( "__method{index}" ) , void_pointer_type_di_node)
1507+ ( format ! ( "__method{index}" ) , pointer_layout , void_pointer_type_di_node)
15001508 }
15011509 ty:: VtblEntry :: TraitVPtr ( _) => {
1502- ( format ! ( "__super_trait_ptr{index}" ) , void_pointer_type_di_node)
1510+ ( format ! ( "__super_trait_ptr{index}" ) , pointer_layout , void_pointer_type_di_node)
15031511 }
1504- ty:: VtblEntry :: MetadataAlign => ( "align" . to_string ( ) , usize_di_node) ,
1505- ty:: VtblEntry :: MetadataSize => ( "size" . to_string ( ) , usize_di_node) ,
1512+ ty:: VtblEntry :: MetadataAlign => ( "align" . to_string ( ) , usize_layout , usize_di_node) ,
1513+ ty:: VtblEntry :: MetadataSize => ( "size" . to_string ( ) , usize_layout , usize_di_node) ,
15061514 ty:: VtblEntry :: Vacant => return None ,
15071515 } ;
15081516
1509- let field_offset = pointer_size * index as u64 ;
1517+ let current_offset = field_offset;
1518+ field_offset += entries_size[ index] ;
15101519
15111520 Some ( build_field_di_node (
15121521 cx,
15131522 vtable_type_di_node,
15141523 & field_name,
1515- pointer_layout ,
1516- field_offset ,
1524+ layout ,
1525+ current_offset ,
15171526 DIFlags :: FlagZero ,
15181527 field_type_di_node,
15191528 None ,
0 commit comments