@@ -18,6 +18,7 @@ use super::utils::{debug_context, DIB, span_start, bytes_to_bits, size_and_align
1818use super :: namespace:: mangled_name_of_item;
1919use super :: type_names:: compute_debuginfo_type_name;
2020use super :: { CrateDebugContext } ;
21+ use abi;
2122use context:: SharedCrateContext ;
2223
2324use llvm:: { self , ValueRef } ;
@@ -438,11 +439,38 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
438439 let trait_llvm_type = type_of:: type_of ( cx, trait_object_type) ;
439440 let file_metadata = unknown_file_metadata ( cx) ;
440441
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+
441469 composite_type_metadata ( cx,
442470 trait_llvm_type,
443471 & trait_type_name[ ..] ,
444472 unique_type_id,
445- & [ ] ,
473+ & member_descriptions ,
446474 containing_scope,
447475 file_metadata,
448476 syntax_pos:: DUMMY_SP )
@@ -1858,3 +1886,65 @@ pub fn extend_scope_to_file(ccx: &CrateContext,
18581886 file_metadata)
18591887 }
18601888}
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