@@ -18,6 +18,7 @@ use super::utils::{debug_context, DIB, span_start, bytes_to_bits, size_and_align
18
18
use super :: namespace:: mangled_name_of_item;
19
19
use super :: type_names:: compute_debuginfo_type_name;
20
20
use super :: { CrateDebugContext } ;
21
+ use abi;
21
22
use context:: SharedCrateContext ;
22
23
23
24
use llvm:: { self , ValueRef } ;
@@ -438,11 +439,38 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
438
439
let trait_llvm_type = type_of:: type_of ( cx, trait_object_type) ;
439
440
let file_metadata = unknown_file_metadata ( cx) ;
440
441
442
+
443
+ let ptr_type = cx. tcx ( ) . mk_ptr ( ty:: TypeAndMut {
444
+ ty : cx. tcx ( ) . types . u8 ,
445
+ mutbl : hir:: MutImmutable
446
+ } ) ;
447
+ let ptr_type_metadata = type_metadata ( cx, ptr_type, syntax_pos:: DUMMY_SP ) ;
448
+ let llvm_type = type_of:: type_of ( cx, ptr_type) ;
449
+
450
+ assert_eq ! ( abi:: FAT_PTR_ADDR , 0 ) ;
451
+ assert_eq ! ( abi:: FAT_PTR_EXTRA , 1 ) ;
452
+ let member_descriptions = [
453
+ MemberDescription {
454
+ name : "pointer" . to_string ( ) ,
455
+ llvm_type : llvm_type,
456
+ type_metadata : ptr_type_metadata,
457
+ offset : ComputedMemberOffset ,
458
+ flags : DIFlags :: FlagArtificial ,
459
+ } ,
460
+ MemberDescription {
461
+ name : "vtable" . to_string ( ) ,
462
+ llvm_type : llvm_type,
463
+ type_metadata : ptr_type_metadata,
464
+ offset : ComputedMemberOffset ,
465
+ flags : DIFlags :: FlagArtificial ,
466
+ } ,
467
+ ] ;
468
+
441
469
composite_type_metadata ( cx,
442
470
trait_llvm_type,
443
471
& trait_type_name[ ..] ,
444
472
unique_type_id,
445
- & [ ] ,
473
+ & member_descriptions ,
446
474
containing_scope,
447
475
file_metadata,
448
476
syntax_pos:: DUMMY_SP )
@@ -1858,3 +1886,65 @@ pub fn extend_scope_to_file(ccx: &CrateContext,
1858
1886
file_metadata)
1859
1887
}
1860
1888
}
1889
+
1890
+ /// Creates debug information for the given vtable, which is for the
1891
+ /// given type.
1892
+ ///
1893
+ /// Adds the created metadata nodes directly to the crate's IR.
1894
+ pub fn create_vtable_metadata < ' a , ' tcx > ( cx : & CrateContext < ' a , ' tcx > ,
1895
+ ty : ty:: Ty < ' tcx > ,
1896
+ vtable : ValueRef ) {
1897
+ if cx. dbg_cx ( ) . is_none ( ) {
1898
+ return ;
1899
+ }
1900
+
1901
+ let type_metadata = type_metadata ( cx, ty, syntax_pos:: DUMMY_SP ) ;
1902
+ let llvm_vtable_type = Type :: vtable_ptr ( cx) . element_type ( ) ;
1903
+ let ( struct_size, struct_align) = size_and_align_of ( cx, llvm_vtable_type) ;
1904
+
1905
+ unsafe {
1906
+ // LLVMRustDIBuilderCreateStructType() wants an empty array. A null
1907
+ // pointer will lead to hard to trace and debug LLVM assertions
1908
+ // later on in llvm/lib/IR/Value.cpp.
1909
+ let empty_array = create_DIArray ( DIB ( cx) , & [ ] ) ;
1910
+
1911
+ let name = CString :: new ( "vtable" ) . unwrap ( ) ;
1912
+
1913
+ // Create a new one each time. We don't want metadata caching
1914
+ // here, because each vtable will refer to a unique containing
1915
+ // type.
1916
+ let vtable_type = llvm:: LLVMRustDIBuilderCreateStructType (
1917
+ DIB ( cx) ,
1918
+ NO_SCOPE_METADATA ,
1919
+ name. as_ptr ( ) ,
1920
+ unknown_file_metadata ( cx) ,
1921
+ UNKNOWN_LINE_NUMBER ,
1922
+ bytes_to_bits ( struct_size) ,
1923
+ bytes_to_bits ( struct_align) ,
1924
+ DIFlags :: FlagArtificial ,
1925
+ ptr:: null_mut ( ) ,
1926
+ empty_array,
1927
+ 0 ,
1928
+ type_metadata,
1929
+ name. as_ptr ( )
1930
+ ) ;
1931
+
1932
+ llvm:: LLVMRustDIBuilderCreateStaticVariable ( DIB ( cx) ,
1933
+ NO_SCOPE_METADATA ,
1934
+ name. as_ptr ( ) ,
1935
+ // LLVM 3.9
1936
+ // doesn't accept
1937
+ // null here, so
1938
+ // pass the name
1939
+ // as the linkage
1940
+ // name.
1941
+ name. as_ptr ( ) ,
1942
+ unknown_file_metadata ( cx) ,
1943
+ UNKNOWN_LINE_NUMBER ,
1944
+ vtable_type,
1945
+ true ,
1946
+ vtable,
1947
+ ptr:: null_mut ( ) ,
1948
+ 0 ) ;
1949
+ }
1950
+ }
0 commit comments