@@ -2,7 +2,7 @@ use self::MemberDescriptionFactory::*;
2
2
use self :: RecursiveTypeDescription :: * ;
3
3
4
4
use super :: namespace:: mangled_name_of_instance;
5
- use super :: type_names:: compute_debuginfo_type_name;
5
+ use super :: type_names:: { compute_debuginfo_type_name, compute_debuginfo_vtable_name } ;
6
6
use super :: utils:: {
7
7
create_DIArray, debug_context, get_namespace_for_item, is_node_local_to_unit, DIB ,
8
8
} ;
@@ -30,8 +30,9 @@ use rustc_middle::ich::NodeIdHashingMode;
30
30
use rustc_middle:: mir:: { self , GeneratorLayout } ;
31
31
use rustc_middle:: ty:: layout:: { self , IntegerExt , LayoutOf , PrimitiveExt , TyAndLayout } ;
32
32
use rustc_middle:: ty:: subst:: GenericArgKind ;
33
- use rustc_middle:: ty:: Instance ;
34
- use rustc_middle:: ty:: { self , AdtKind , GeneratorSubsts , ParamEnv , Ty , TyCtxt } ;
33
+ use rustc_middle:: ty:: {
34
+ self , AdtKind , GeneratorSubsts , Instance , ParamEnv , Ty , TyCtxt , COMMON_VTABLE_ENTRIES ,
35
+ } ;
35
36
use rustc_middle:: { bug, span_bug} ;
36
37
use rustc_session:: config:: { self , DebugInfo } ;
37
38
use rustc_span:: symbol:: Symbol ;
@@ -2591,11 +2592,45 @@ pub fn create_global_var_metadata(cx: &CodegenCx<'ll, '_>, def_id: DefId, global
2591
2592
}
2592
2593
}
2593
2594
2595
+ /// Generates LLVM debuginfo for a vtable.
2596
+ fn vtable_type_metadata (
2597
+ cx : & CodegenCx < ' ll , ' tcx > ,
2598
+ ty : Ty < ' tcx > ,
2599
+ poly_trait_ref : Option < ty:: PolyExistentialTraitRef < ' tcx > > ,
2600
+ ) -> & ' ll DIType {
2601
+ let tcx = cx. tcx ;
2602
+
2603
+ let vtable_entries = if let Some ( poly_trait_ref) = poly_trait_ref {
2604
+ let trait_ref = poly_trait_ref. with_self_ty ( tcx, ty) ;
2605
+ let trait_ref = tcx. erase_regions ( trait_ref) ;
2606
+
2607
+ tcx. vtable_entries ( trait_ref)
2608
+ } else {
2609
+ COMMON_VTABLE_ENTRIES
2610
+ } ;
2611
+
2612
+ // FIXME: We describe the vtable as an array of *const () pointers. The length of the array is
2613
+ // correct - but we could create a more accurate description, e.g. by describing it
2614
+ // as a struct where each field has a name that corresponds to the name of the method
2615
+ // it points to.
2616
+ // However, this is not entirely straightforward because there might be multiple
2617
+ // methods with the same name if the vtable is for multiple traits. So for now we keep
2618
+ // things simple instead of adding some ad-hoc disambiguation scheme.
2619
+ let vtable_type = tcx. mk_array ( tcx. mk_imm_ptr ( tcx. types . unit ) , vtable_entries. len ( ) as u64 ) ;
2620
+
2621
+ type_metadata ( cx, vtable_type, rustc_span:: DUMMY_SP )
2622
+ }
2623
+
2594
2624
/// Creates debug information for the given vtable, which is for the
2595
2625
/// given type.
2596
2626
///
2597
2627
/// Adds the created metadata nodes directly to the crate's IR.
2598
- pub fn create_vtable_metadata ( cx : & CodegenCx < ' ll , ' tcx > , ty : Ty < ' tcx > , vtable : & ' ll Value ) {
2628
+ pub fn create_vtable_metadata (
2629
+ cx : & CodegenCx < ' ll , ' tcx > ,
2630
+ ty : Ty < ' tcx > ,
2631
+ poly_trait_ref : Option < ty:: PolyExistentialTraitRef < ' tcx > > ,
2632
+ vtable : & ' ll Value ,
2633
+ ) {
2599
2634
if cx. dbg_cx . is_none ( ) {
2600
2635
return ;
2601
2636
}
@@ -2605,42 +2640,16 @@ pub fn create_vtable_metadata(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>, vtable: &
2605
2640
return ;
2606
2641
}
2607
2642
2608
- let type_metadata = type_metadata ( cx, ty, rustc_span:: DUMMY_SP ) ;
2643
+ let vtable_name = compute_debuginfo_vtable_name ( cx. tcx , ty, poly_trait_ref) ;
2644
+ let vtable_type = vtable_type_metadata ( cx, ty, poly_trait_ref) ;
2609
2645
2610
2646
unsafe {
2611
- // `LLVMRustDIBuilderCreateStructType()` wants an empty array. A null
2612
- // pointer will lead to hard to trace and debug LLVM assertions
2613
- // later on in `llvm/lib/IR/Value.cpp`.
2614
- let empty_array = create_DIArray ( DIB ( cx) , & [ ] ) ;
2615
- let name = "vtable" ;
2616
-
2617
- // Create a new one each time. We don't want metadata caching
2618
- // here, because each vtable will refer to a unique containing
2619
- // type.
2620
- let vtable_type = llvm:: LLVMRustDIBuilderCreateStructType (
2621
- DIB ( cx) ,
2622
- NO_SCOPE_METADATA ,
2623
- name. as_ptr ( ) . cast ( ) ,
2624
- name. len ( ) ,
2625
- unknown_file_metadata ( cx) ,
2626
- UNKNOWN_LINE_NUMBER ,
2627
- Size :: ZERO . bits ( ) ,
2628
- cx. tcx . data_layout . pointer_align . abi . bits ( ) as u32 ,
2629
- DIFlags :: FlagArtificial ,
2630
- None ,
2631
- empty_array,
2632
- 0 ,
2633
- Some ( type_metadata) ,
2634
- name. as_ptr ( ) . cast ( ) ,
2635
- name. len ( ) ,
2636
- ) ;
2637
-
2638
2647
let linkage_name = "" ;
2639
2648
llvm:: LLVMRustDIBuilderCreateStaticVariable (
2640
2649
DIB ( cx) ,
2641
2650
NO_SCOPE_METADATA ,
2642
- name . as_ptr ( ) . cast ( ) ,
2643
- name . len ( ) ,
2651
+ vtable_name . as_ptr ( ) . cast ( ) ,
2652
+ vtable_name . len ( ) ,
2644
2653
linkage_name. as_ptr ( ) . cast ( ) ,
2645
2654
linkage_name. len ( ) ,
2646
2655
unknown_file_metadata ( cx) ,
0 commit comments